LiteSpeed Cache - Version 1.1.6

Version Description

  • August 23 2017 =
  • [NEW FEATURE] Added option to privately cache logged-in users.
  • [NEW FEATURE] Added option to privately cache commenters.
  • [NEW FEATURE] Added option to cache requests made through WordPress REST API.
  • [BUGFIX] Fixed network 3rd-party full-page cache detection bug.
  • [GUI] New Cache and Purge menus in Settings.
Download this release

Release Info

Developer LiteSpeedTech
Plugin Icon 128x128 LiteSpeed Cache
Version 1.1.6
Comparing to
See all releases

Version 1.1.6

Files changed (105) hide show
  1. admin/class-litespeed-cache-admin.php +7 -0
  2. admin/css/fonts/litespeedfont.eot +0 -0
  3. admin/css/fonts/litespeedfont.svg +11 -0
  4. admin/css/fonts/litespeedfont.ttf +0 -0
  5. admin/css/fonts/litespeedfont.woff +0 -0
  6. admin/css/litespeed-btn.css +730 -0
  7. admin/css/litespeed-cache-admin.css +269 -0
  8. admin/css/litespeed-callout.css +63 -0
  9. admin/css/litespeed-checkbox.css +356 -0
  10. admin/css/litespeed-common.css +81 -0
  11. admin/css/litespeed-icon.css +27 -0
  12. admin/css/litespeed-label.css +67 -0
  13. admin/css/snowman.css +685 -0
  14. admin/img/Litespeed.icon.svg +30 -0
  15. admin/js/litespeed-cache-admin.js +359 -0
  16. admin/litespeed-cache-admin-display.class.php +863 -0
  17. admin/litespeed-cache-admin-error.class.php +263 -0
  18. admin/litespeed-cache-admin-report.class.php +198 -0
  19. admin/litespeed-cache-admin-rules.class.php +891 -0
  20. admin/litespeed-cache-admin-settings.class.php +910 -0
  21. admin/litespeed-cache-admin.class.php +277 -0
  22. admin/tpl/admin_footer.php +19 -0
  23. admin/tpl/crawler.php +229 -0
  24. admin/tpl/debug_log.php +27 -0
  25. admin/tpl/edit_htaccess.php +73 -0
  26. admin/tpl/esi_widget_edit.php +46 -0
  27. admin/tpl/help_tabs.php +26 -0
  28. admin/tpl/info.php +42 -0
  29. admin/tpl/info_admin_ip.php +33 -0
  30. admin/tpl/info_common_rewrite.php +58 -0
  31. admin/tpl/info_compatibility.php +57 -0
  32. admin/tpl/info_config.php +68 -0
  33. admin/tpl/info_crawler.php +67 -0
  34. admin/tpl/info_faqs.php +110 -0
  35. admin/tpl/manage.php +201 -0
  36. admin/tpl/network_settings.php +56 -0
  37. admin/tpl/network_settings_cache.php +18 -0
  38. admin/tpl/network_settings_excludes.php +11 -0
  39. admin/tpl/network_settings_general.php +34 -0
  40. admin/tpl/network_settings_purge.php +10 -0
  41. admin/tpl/report.php +45 -0
  42. admin/tpl/settings.php +141 -0
  43. admin/tpl/settings_advanced.php +79 -0
  44. admin/tpl/settings_cache.php +56 -0
  45. admin/tpl/settings_compatibilities.php +38 -0
  46. admin/tpl/settings_crawler.php +196 -0
  47. admin/tpl/settings_debug.php +161 -0
  48. admin/tpl/settings_esi.php +38 -0
  49. admin/tpl/settings_excludes.php +111 -0
  50. admin/tpl/settings_general.php +134 -0
  51. admin/tpl/settings_inc.cache_favicon.php +15 -0
  52. admin/tpl/settings_inc.cache_mobile.php +78 -0
  53. admin/tpl/settings_inc.cache_resources.php +16 -0
  54. admin/tpl/settings_inc.exclude_cookies.php +23 -0
  55. admin/tpl/settings_inc.exclude_useragent.php +26 -0
  56. admin/tpl/settings_inc.purge_on_upgrade.php +14 -0
  57. admin/tpl/settings_purge.php +97 -0
  58. admin/tpl/show_display_installed.php +21 -0
  59. admin/tpl/show_error_cookie.php +13 -0
  60. admin/tpl/show_rule_conflict.php +13 -0
  61. admin/tpl/snowman.inc.php +86 -0
  62. cli/litespeed-cache-cli-admin.class.php +323 -0
  63. cli/litespeed-cache-cli-purge.class.php +303 -0
  64. includes/advanced-cache.php +20 -0
  65. includes/deprecated-litespeed-cache-tags.class.php +12 -0
  66. includes/litespeed-cache-activation.class.php +245 -0
  67. includes/litespeed-cache-api.class.php +360 -0
  68. includes/litespeed-cache-config.class.php +727 -0
  69. includes/litespeed-cache-control.class.php +602 -0
  70. includes/litespeed-cache-crawler-sitemap.class.php +157 -0
  71. includes/litespeed-cache-crawler.class.php +451 -0
  72. includes/litespeed-cache-esi-dummy.tpl.php +9 -0
  73. includes/litespeed-cache-esi.class.php +545 -0
  74. includes/litespeed-cache-esi.tpl.php +9 -0
  75. includes/litespeed-cache-log.class.php +293 -0
  76. includes/litespeed-cache-purge.class.php +732 -0
  77. includes/litespeed-cache-router.class.php +414 -0
  78. includes/litespeed-cache-tag.class.php +367 -0
  79. includes/litespeed-cache-task.class.php +128 -0
  80. includes/litespeed-cache-utility.class.php +31 -0
  81. includes/litespeed-cache-vary.class.php +402 -0
  82. includes/litespeed-cache.class.php +522 -0
  83. includes/litespeed.autoload.php +57 -0
  84. languages/litespeed-cache.pot +2782 -0
  85. lib/litespeed-php-compatibility.func.php +123 -0
  86. lib/litespeed/litespeed-crawler.class.php +573 -0
  87. lib/litespeed/litespeed-file.class.php +400 -0
  88. litespeed-cache.php +140 -0
  89. readme.txt +517 -0
  90. thirdparty/lscwp-3rd-aelia-currencyswitcher.cls.php +89 -0
  91. thirdparty/lscwp-3rd-autoptimize.cls.php +43 -0
  92. thirdparty/lscwp-3rd-avada.cls.php +46 -0
  93. thirdparty/lscwp-3rd-bbpress.cls.php +65 -0
  94. thirdparty/lscwp-3rd-betterwp-minify.cls.php +72 -0
  95. thirdparty/lscwp-3rd-like-dislike-counter.cls.php +38 -0
  96. thirdparty/lscwp-3rd-nextgengallery.cls.php +215 -0
  97. thirdparty/lscwp-3rd-theme-my-login.cls.php +50 -0
  98. thirdparty/lscwp-3rd-woocommerce.cls.php +725 -0
  99. thirdparty/lscwp-3rd-wp-polls.cls.php +24 -0
  100. thirdparty/lscwp-3rd-wp-postratings.cls.php +43 -0
  101. thirdparty/lscwp-3rd-wpforo.cls.php +157 -0
  102. thirdparty/lscwp-3rd-wplister.cls.php +34 -0
  103. thirdparty/lscwp-3rd-wptouch.cls.php +47 -0
  104. thirdparty/lscwp-3rd-yith-wishlist.cls.php +97 -0
  105. thirdparty/lscwp-registry-3rd.php +37 -0
admin/class-litespeed-cache-admin.php ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * ONLY for WHM plugin old version backward compatibility @Aug/2/2017
4
+ */
5
+
6
+
7
+ require_once dirname(__FILE__) . '/litespeed-cache-admin.class.php' ;
admin/css/fonts/litespeedfont.eot ADDED
Binary file
admin/css/fonts/litespeedfont.svg ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" standalone="no"?>
2
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
3
+ <svg xmlns="http://www.w3.org/2000/svg">
4
+ <metadata>Generated by IcoMoon</metadata>
5
+ <defs>
6
+ <font id="litespeedfont" horiz-adv-x="1024">
7
+ <font-face units-per-em="1024" ascent="960" descent="-64" />
8
+ <missing-glyph horiz-adv-x="1024" />
9
+ <glyph unicode="&#x20;" horiz-adv-x="512" d="" />
10
+ <glyph unicode="&#xe900;" glyph-name="wp_lscache" d="M1019.179 451.092c-0.094 0.469-0.27 0.916-0.404 1.374-0.156 0.532-0.284 1.070-0.495 1.57-0.222 0.549-0.532 1.061-0.822 1.57-0.205 0.384-0.381 0.788-0.623 1.152-0.572 0.853-1.226 1.664-1.977 2.423l-0.014 0.011-491.674 491.679c-0.040 0.031-0.082 0.063-0.122 0.094-2.847 2.796-6.741 4.531-11.051 4.531-4.315 0-8.206-1.735-11.054-4.531-0.043-0.031-0.088-0.063-0.125-0.094l-0.011-0.020-491.674-491.671c-0.754-0.759-1.408-1.57-1.98-2.423-0.242-0.361-0.41-0.768-0.623-1.152-0.284-0.509-0.603-1.018-0.822-1.57-0.213-0.501-0.333-1.038-0.486-1.57-0.139-0.458-0.316-0.905-0.407-1.374-0.205-1.007-0.313-2.037-0.313-3.095 0-1.061 0.108-2.088 0.313-3.089 0.088-0.466 0.265-0.91 0.407-1.368 0.156-0.532 0.276-1.087 0.486-1.587 0.219-0.538 0.535-1.050 0.822-1.57 0.213-0.384 0.381-0.777 0.623-1.152 0.572-0.842 1.226-1.664 1.98-2.412l0.009-0.011 491.676-491.682c0.737-0.742 1.539-1.382 2.395-1.957 0.168-0.114 0.358-0.188 0.535-0.299 0.703-0.415 1.414-0.845 2.176-1.155 0.282-0.125 0.597-0.176 0.893-0.282 0.677-0.239 1.345-0.475 2.054-0.626 1.007-0.193 2.054-0.307 3.126-0.307 1.064 0 2.113 0.114 3.123 0.307 0.703 0.151 1.374 0.387 2.048 0.626 0.296 0.105 0.614 0.156 0.896 0.282 0.759 0.31 1.473 0.742 2.182 1.155 0.171 0.111 0.367 0.185 0.532 0.299 0.856 0.572 1.658 1.215 2.395 1.957l0.014 0.020 491.676 491.674c0.754 0.748 1.405 1.57 1.977 2.412 0.242 0.375 0.415 0.771 0.623 1.152 0.293 0.521 0.6 1.030 0.822 1.57 0.21 0.501 0.338 1.055 0.495 1.587 0.134 0.458 0.307 0.902 0.404 1.368 0.196 1.001 0.316 2.028 0.316 3.089-0.003 1.061-0.122 2.091-0.321 3.095zM941.096 447.11l-0.168-0.444-0.137-0.484-0.492-0.879c-0.122-0.168-0.276-0.347-0.444-0.515l-424.624-424.63c-0.151-0.159-0.299-0.29-0.461-0.404-0.142-0.094-0.697-0.424-0.85-0.506l-1.166-0.384c-0.134-0.031-0.444-0.060-0.759-0.060s-0.62 0.031-0.919 0.097c0 0-0.811 0.29-0.993 0.347-0.188 0.1-0.879 0.512-0.879 0.512-0.162 0.131-0.296 0.247-0.427 0.381l-424.627 424.627c-0.168 0.171-0.313 0.344-0.444 0.526l-0.521 0.956-0.341 1.115c-0.006 0.040-0.046 0.327-0.046 0.634 0 0.304 0.040 0.6 0.1 0.887l0.171 0.444 0.151 0.515 0.225 0.356 0.265 0.515c0.134 0.179 0.273 0.356 0.424 0.506l424.741 424.715c0.449 0.435 1.525 1.26 3.126 1.26s2.679-0.825 3.18-1.32l424.667-424.644c0.168-0.168 0.31-0.344 0.435-0.523l0.512-0.936 0.353-1.126c0.006-0.051 0.048-0.347 0.048-0.651-0.003-0.304-0.043-0.592-0.1-0.887zM764.55 449.53c-0.060 0.225-0.156 0.455-0.21 0.683-0.071 0.265-0.134 0.535-0.245 0.782-0.111 0.267-0.262 0.532-0.412 0.774-0.105 0.196-0.188 0.404-0.31 0.58-0.279 0.421-0.623 0.825-0.973 1.198l-0.017 0.020-244.824 244.816c-0.017 0.011-0.046 0.037-0.057 0.054-1.417 1.388-3.351 2.256-5.504 2.256-2.139 0-4.087-0.868-5.504-2.256-0.020-0.017-0.043-0.043-0.057-0.054l-244.824-244.833c-0.375-0.373-0.705-0.774-0.987-1.198-0.128-0.179-0.202-0.384-0.307-0.58-0.151-0.245-0.302-0.509-0.407-0.774-0.111-0.25-0.168-0.521-0.247-0.782-0.074-0.228-0.165-0.458-0.208-0.683-0.102-0.503-0.154-1.018-0.154-1.553 0-0.521 0.051-1.027 0.154-1.525 0.046-0.233 0.134-0.455 0.208-0.697 0.080-0.253 0.137-0.523 0.247-0.771 0.102-0.267 0.256-0.529 0.407-0.788 0.105-0.182 0.179-0.39 0.307-0.566 0.282-0.421 0.612-0.822 0.987-1.2l0.003-0.006 244.821-244.827c0.37-0.367 0.771-0.688 1.189-0.967 0.082-0.065 0.185-0.094 0.27-0.145 0.347-0.216 0.708-0.438 1.084-0.589 0.137-0.057 0.299-0.071 0.441-0.122 0.327-0.134 0.663-0.245 1.024-0.321 0.503-0.1 1.018-0.145 1.55-0.145 0.535 0 1.058 0.046 1.562 0.145 0.347 0.077 0.683 0.188 1.015 0.321 0.148 0.051 0.304 0.065 0.455 0.122 0.373 0.151 0.728 0.373 1.078 0.589 0.082 0.051 0.188 0.077 0.267 0.145 0.427 0.279 0.828 0.6 1.183 0.967l0.017 0.006 244.821 244.827c0.35 0.378 0.694 0.777 0.973 1.2 0.122 0.179 0.205 0.384 0.31 0.566 0.151 0.262 0.299 0.523 0.412 0.788 0.111 0.247 0.174 0.518 0.245 0.771 0.057 0.242 0.151 0.464 0.21 0.697 0.088 0.498 0.145 1.007 0.145 1.525 0.003 0.532-0.051 1.047-0.139 1.55zM604.76 581.632l-78.35-99.419 42.416-61.002c0.051-0.071 0.1-0.151 0.156-0.228 0.711-1.106 1.229-2.222 1.596-3.573 2.506-9.782 0.745-17.55-4.907-21.834l-128.68-98.768c-2.216-1.749-5.299-3.766-9.429-3.766-4.588 0-8.829 2.651-10.769 6.679-2.33 4.699-1.476 9.671 2.534 14.771l78.327 99.439-43.036 61.921c-5.501 7.811-3.792 18.901 3.792 24.701l128.762 98.847c2.222 1.718 5.288 3.686 9.333 3.686 4.577 0 8.823-2.645 10.823-6.753 2.258-4.654 1.402-9.586-2.569-14.703zM233.35 419.499l249.805-249.816v-58.14l-307.965 307.957h58.16zM483.154 726.283l-249.793-249.785h-58.172l307.965 307.962v-58.177zM790.687 419.536h54.428l-307.988-307.996v54.417l253.559 253.579zM790.667 476.473l-253.54 253.537v54.451l311.683-307.988h-58.143z" />
11
+ </font></defs></svg>
admin/css/fonts/litespeedfont.ttf ADDED
Binary file
admin/css/fonts/litespeedfont.woff ADDED
Binary file
admin/css/litespeed-btn.css ADDED
@@ -0,0 +1,730 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ /** button style **/
3
+ .litespeed-btn {
4
+ display: inline-block;
5
+ padding: 6px 12px;
6
+ margin-bottom: 0;
7
+ font-size: 14px;
8
+ font-weight: normal;
9
+ line-height: 1.42857143;
10
+ text-align: center;
11
+ white-space: nowrap;
12
+ vertical-align: middle;
13
+ -ms-touch-action: manipulation;
14
+ touch-action: manipulation;
15
+ cursor: pointer;
16
+ -webkit-user-select: none;
17
+ -moz-user-select: none;
18
+ -ms-user-select: none;
19
+ user-select: none;
20
+ background-image: none;
21
+ border: 1px solid transparent;
22
+ border-radius: 4px;
23
+ text-decoration: none;
24
+ }
25
+ .litespeed-btn:focus,
26
+ .litespeed-btn:active:focus,
27
+ .litespeed-btn.active:focus,
28
+ .litespeed-btn.focus,
29
+ .litespeed-btn:active.focus,
30
+ .litespeed-btn.active.focus {
31
+ outline: 5px auto -webkit-focus-ring-color;
32
+ outline-offset: -2px;
33
+ }
34
+ .litespeed-btn:hover,
35
+ .litespeed-btn:focus,
36
+ .litespeed-btn.focus {
37
+ color: #333;
38
+ text-decoration: none;
39
+ }
40
+ .litespeed-btn:active,
41
+ .litespeed-btn.active {
42
+ background-image: none;
43
+ outline: 0;
44
+ -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
45
+ box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
46
+ }
47
+ .litespeed-btn.disabled,
48
+ .litespeed-btn[disabled],
49
+ fieldset[disabled] .litespeed-btn {
50
+ cursor: not-allowed;
51
+ filter: alpha(opacity=65);
52
+ -webkit-box-shadow: none;
53
+ box-shadow: none;
54
+ opacity: .65;
55
+ }
56
+ a.litespeed-btn.disabled,
57
+ fieldset[disabled] a.litespeed-btn {
58
+ pointer-events: none;
59
+ }
60
+ .litespeed-btn-default {
61
+ color: #333;
62
+ background-color: #fff;
63
+ border-color: #ccc;
64
+ }
65
+ .litespeed-btn-default:focus,
66
+ .litespeed-btn-default.focus {
67
+ color: #333;
68
+ background-color: #e6e6e6;
69
+ border-color: #8c8c8c;
70
+ }
71
+ .litespeed-btn-default:hover {
72
+ color: #333;
73
+ background-color: #e6e6e6;
74
+ border-color: #adadad;
75
+ }
76
+ .litespeed-btn-default:active,
77
+ .litespeed-btn-default.active,
78
+ .open > .dropdown-toggle.litespeed-btn-default {
79
+ color: #333;
80
+ background-color: #e6e6e6;
81
+ border-color: #adadad;
82
+ }
83
+ .litespeed-btn-default:active:hover,
84
+ .litespeed-btn-default.active:hover,
85
+ .open > .dropdown-toggle.litespeed-btn-default:hover,
86
+ .litespeed-btn-default:active:focus,
87
+ .litespeed-btn-default.active:focus,
88
+ .open > .dropdown-toggle.litespeed-btn-default:focus,
89
+ .litespeed-btn-default:active.focus,
90
+ .litespeed-btn-default.active.focus,
91
+ .open > .dropdown-toggle.litespeed-btn-default.focus {
92
+ color: #333;
93
+ background-color: #d4d4d4;
94
+ border-color: #8c8c8c;
95
+ }
96
+ .litespeed-btn-default:active,
97
+ .litespeed-btn-default.active,
98
+ .open > .dropdown-toggle.litespeed-btn-default {
99
+ background-image: none;
100
+ }
101
+ .litespeed-btn-default.disabled:hover,
102
+ .litespeed-btn-default[disabled]:hover,
103
+ fieldset[disabled] .litespeed-btn-default:hover,
104
+ .litespeed-btn-default.disabled:focus,
105
+ .litespeed-btn-default[disabled]:focus,
106
+ fieldset[disabled] .litespeed-btn-default:focus,
107
+ .litespeed-btn-default.disabled.focus,
108
+ .litespeed-btn-default[disabled].focus,
109
+ fieldset[disabled] .litespeed-btn-default.focus {
110
+ background-color: #fff;
111
+ border-color: #ccc;
112
+ }
113
+ .litespeed-btn-default .badge {
114
+ color: #fff;
115
+ background-color: #333;
116
+ }
117
+ .litespeed-btn-primary {
118
+ color: #fff;
119
+ background-color: #337ab7;
120
+ border-color: #2e6da4;
121
+ }
122
+ .litespeed-btn-primary:focus,
123
+ .litespeed-btn-primary.focus {
124
+ color: #fff;
125
+ background-color: #286090;
126
+ border-color: #122b40;
127
+ }
128
+ .litespeed-btn-primary:hover {
129
+ color: #fff;
130
+ background-color: #286090;
131
+ border-color: #204d74;
132
+ }
133
+ .litespeed-btn-primary:active,
134
+ .litespeed-btn-primary.active,
135
+ .open > .dropdown-toggle.litespeed-btn-primary {
136
+ color: #fff;
137
+ background-color: #286090;
138
+ border-color: #204d74;
139
+ }
140
+ .litespeed-btn-primary:active:hover,
141
+ .litespeed-btn-primary.active:hover,
142
+ .open > .dropdown-toggle.litespeed-btn-primary:hover,
143
+ .litespeed-btn-primary:active:focus,
144
+ .litespeed-btn-primary.active:focus,
145
+ .open > .dropdown-toggle.litespeed-btn-primary:focus,
146
+ .litespeed-btn-primary:active.focus,
147
+ .litespeed-btn-primary.active.focus,
148
+ .open > .dropdown-toggle.litespeed-btn-primary.focus {
149
+ color: #fff;
150
+ background-color: #204d74;
151
+ border-color: #122b40;
152
+ }
153
+ .litespeed-btn-primary:active,
154
+ .litespeed-btn-primary.active,
155
+ .open > .dropdown-toggle.litespeed-btn-primary {
156
+ background-image: none;
157
+ }
158
+ .litespeed-btn-primary.disabled:hover,
159
+ .litespeed-btn-primary[disabled]:hover,
160
+ fieldset[disabled] .litespeed-btn-primary:hover,
161
+ .litespeed-btn-primary.disabled:focus,
162
+ .litespeed-btn-primary[disabled]:focus,
163
+ fieldset[disabled] .litespeed-btn-primary:focus,
164
+ .litespeed-btn-primary.disabled.focus,
165
+ .litespeed-btn-primary[disabled].focus,
166
+ fieldset[disabled] .litespeed-btn-primary.focus {
167
+ background-color: #337ab7;
168
+ border-color: #2e6da4;
169
+ }
170
+ .litespeed-btn-primary .badge {
171
+ color: #337ab7;
172
+ background-color: #fff;
173
+ }
174
+ .litespeed-btn-success {
175
+ color: #fff;
176
+ background-color: #5cb85c;
177
+ border-color: #4cae4c;
178
+ }
179
+ .litespeed-btn-success:focus,
180
+ .litespeed-btn-success.focus {
181
+ color: #fff;
182
+ background-color: #449d44;
183
+ border-color: #255625;
184
+ }
185
+ .litespeed-btn-success:hover {
186
+ color: #fff;
187
+ background-color: #449d44;
188
+ border-color: #398439;
189
+ }
190
+ .litespeed-btn-success:active,
191
+ .litespeed-btn-success.active,
192
+ .open > .dropdown-toggle.litespeed-btn-success {
193
+ color: #fff;
194
+ background-color: #449d44;
195
+ border-color: #398439;
196
+ }
197
+ .litespeed-btn-success:active:hover,
198
+ .litespeed-btn-success.active:hover,
199
+ .open > .dropdown-toggle.litespeed-btn-success:hover,
200
+ .litespeed-btn-success:active:focus,
201
+ .litespeed-btn-success.active:focus,
202
+ .open > .dropdown-toggle.litespeed-btn-success:focus,
203
+ .litespeed-btn-success:active.focus,
204
+ .litespeed-btn-success.active.focus,
205
+ .open > .dropdown-toggle.litespeed-btn-success.focus {
206
+ color: #fff;
207
+ background-color: #398439;
208
+ border-color: #255625;
209
+ }
210
+ .litespeed-btn-success:active,
211
+ .litespeed-btn-success.active,
212
+ .open > .dropdown-toggle.litespeed-btn-success {
213
+ background-image: none;
214
+ }
215
+ .litespeed-btn-success.disabled:hover,
216
+ .litespeed-btn-success[disabled]:hover,
217
+ fieldset[disabled] .litespeed-btn-success:hover,
218
+ .litespeed-btn-success.disabled:focus,
219
+ .litespeed-btn-success[disabled]:focus,
220
+ fieldset[disabled] .litespeed-btn-success:focus,
221
+ .litespeed-btn-success.disabled.focus,
222
+ .litespeed-btn-success[disabled].focus,
223
+ fieldset[disabled] .litespeed-btn-success.focus {
224
+ background-color: #5cb85c;
225
+ border-color: #4cae4c;
226
+ }
227
+ .litespeed-btn-success .badge {
228
+ color: #5cb85c;
229
+ background-color: #fff;
230
+ }
231
+ .litespeed-btn-info {
232
+ color: #fff;
233
+ background-color: #5bc0de;
234
+ border-color: #46b8da;
235
+ }
236
+ .litespeed-btn-info:focus,
237
+ .litespeed-btn-info.focus {
238
+ color: #fff;
239
+ background-color: #31b0d5;
240
+ border-color: #1b6d85;
241
+ }
242
+ .litespeed-btn-info:hover {
243
+ color: #fff;
244
+ background-color: #31b0d5;
245
+ border-color: #269abc;
246
+ }
247
+ .litespeed-btn-info:active,
248
+ .litespeed-btn-info.active,
249
+ .open > .dropdown-toggle.litespeed-btn-info {
250
+ color: #fff;
251
+ background-color: #31b0d5;
252
+ border-color: #269abc;
253
+ }
254
+ .litespeed-btn-info:active:hover,
255
+ .litespeed-btn-info.active:hover,
256
+ .open > .dropdown-toggle.litespeed-btn-info:hover,
257
+ .litespeed-btn-info:active:focus,
258
+ .litespeed-btn-info.active:focus,
259
+ .open > .dropdown-toggle.litespeed-btn-info:focus,
260
+ .litespeed-btn-info:active.focus,
261
+ .litespeed-btn-info.active.focus,
262
+ .open > .dropdown-toggle.litespeed-btn-info.focus {
263
+ color: #fff;
264
+ background-color: #269abc;
265
+ border-color: #1b6d85;
266
+ }
267
+ .litespeed-btn-info:active,
268
+ .litespeed-btn-info.active,
269
+ .open > .dropdown-toggle.litespeed-btn-info {
270
+ background-image: none;
271
+ }
272
+ .litespeed-btn-info.disabled:hover,
273
+ .litespeed-btn-info[disabled]:hover,
274
+ fieldset[disabled] .litespeed-btn-info:hover,
275
+ .litespeed-btn-info.disabled:focus,
276
+ .litespeed-btn-info[disabled]:focus,
277
+ fieldset[disabled] .litespeed-btn-info:focus,
278
+ .litespeed-btn-info.disabled.focus,
279
+ .litespeed-btn-info[disabled].focus,
280
+ fieldset[disabled] .litespeed-btn-info.focus {
281
+ background-color: #5bc0de;
282
+ border-color: #46b8da;
283
+ }
284
+ .litespeed-btn-info .badge {
285
+ color: #5bc0de;
286
+ background-color: #fff;
287
+ }
288
+ .litespeed-btn-warning {
289
+ color: #fff;
290
+ background-color: #f0ad4e;
291
+ border-color: #eea236;
292
+ }
293
+ .litespeed-btn-warning:focus,
294
+ .litespeed-btn-warning.focus {
295
+ color: #fff;
296
+ background-color: #ec971f;
297
+ border-color: #985f0d;
298
+ }
299
+ .litespeed-btn-warning:hover {
300
+ color: #fff;
301
+ background-color: #ec971f;
302
+ border-color: #d58512;
303
+ }
304
+ .litespeed-btn-warning:active,
305
+ .litespeed-btn-warning.active,
306
+ .open > .dropdown-toggle.litespeed-btn-warning {
307
+ color: #fff;
308
+ background-color: #ec971f;
309
+ border-color: #d58512;
310
+ }
311
+ .litespeed-btn-warning:active:hover,
312
+ .litespeed-btn-warning.active:hover,
313
+ .open > .dropdown-toggle.litespeed-btn-warning:hover,
314
+ .litespeed-btn-warning:active:focus,
315
+ .litespeed-btn-warning.active:focus,
316
+ .open > .dropdown-toggle.litespeed-btn-warning:focus,
317
+ .litespeed-btn-warning:active.focus,
318
+ .litespeed-btn-warning.active.focus,
319
+ .open > .dropdown-toggle.litespeed-btn-warning.focus {
320
+ color: #fff;
321
+ background-color: #d58512;
322
+ border-color: #985f0d;
323
+ }
324
+ .litespeed-btn-warning:active,
325
+ .litespeed-btn-warning.active,
326
+ .open > .dropdown-toggle.litespeed-btn-warning {
327
+ background-image: none;
328
+ }
329
+ .litespeed-btn-warning.disabled:hover,
330
+ .litespeed-btn-warning[disabled]:hover,
331
+ fieldset[disabled] .litespeed-btn-warning:hover,
332
+ .litespeed-btn-warning.disabled:focus,
333
+ .litespeed-btn-warning[disabled]:focus,
334
+ fieldset[disabled] .litespeed-btn-warning:focus,
335
+ .litespeed-btn-warning.disabled.focus,
336
+ .litespeed-btn-warning[disabled].focus,
337
+ fieldset[disabled] .litespeed-btn-warning.focus {
338
+ background-color: #f0ad4e;
339
+ border-color: #eea236;
340
+ }
341
+ .litespeed-btn-warning .badge {
342
+ color: #f0ad4e;
343
+ background-color: #fff;
344
+ }
345
+ .litespeed-btn-danger {
346
+ color: #fff;
347
+ background-color: #d9534f;
348
+ border-color: #d43f3a;
349
+ }
350
+ .litespeed-btn-danger:focus,
351
+ .litespeed-btn-danger.focus {
352
+ color: #fff;
353
+ background-color: #c9302c;
354
+ border-color: #761c19;
355
+ }
356
+ .litespeed-btn-danger:hover {
357
+ color: #fff;
358
+ background-color: #c9302c;
359
+ border-color: #ac2925;
360
+ }
361
+ .litespeed-btn-danger:active,
362
+ .litespeed-btn-danger.active,
363
+ .open > .dropdown-toggle.litespeed-btn-danger {
364
+ color: #fff;
365
+ background-color: #c9302c;
366
+ border-color: #ac2925;
367
+ }
368
+ .litespeed-btn-danger:active:hover,
369
+ .litespeed-btn-danger.active:hover,
370
+ .open > .dropdown-toggle.litespeed-btn-danger:hover,
371
+ .litespeed-btn-danger:active:focus,
372
+ .litespeed-btn-danger.active:focus,
373
+ .open > .dropdown-toggle.litespeed-btn-danger:focus,
374
+ .litespeed-btn-danger:active.focus,
375
+ .litespeed-btn-danger.active.focus,
376
+ .open > .dropdown-toggle.litespeed-btn-danger.focus {
377
+ color: #fff;
378
+ background-color: #ac2925;
379
+ border-color: #761c19;
380
+ }
381
+ .litespeed-btn-danger:active,
382
+ .litespeed-btn-danger.active,
383
+ .open > .dropdown-toggle.litespeed-btn-danger {
384
+ background-image: none;
385
+ }
386
+ .litespeed-btn-danger.disabled:hover,
387
+ .litespeed-btn-danger[disabled]:hover,
388
+ fieldset[disabled] .litespeed-btn-danger:hover,
389
+ .litespeed-btn-danger.disabled:focus,
390
+ .litespeed-btn-danger[disabled]:focus,
391
+ fieldset[disabled] .litespeed-btn-danger:focus,
392
+ .litespeed-btn-danger.disabled.focus,
393
+ .litespeed-btn-danger[disabled].focus,
394
+ fieldset[disabled] .litespeed-btn-danger.focus {
395
+ background-color: #d9534f;
396
+ border-color: #d43f3a;
397
+ }
398
+ .litespeed-btn-danger .badge {
399
+ color: #d9534f;
400
+ background-color: #fff;
401
+ }
402
+ .litespeed-btn-lg,
403
+ .litespeed-btn-group-lg > .litespeed-btn {
404
+ padding: 10px 16px;
405
+ font-size: 18px;
406
+ line-height: 1.3333333;
407
+ border-radius: 6px;
408
+ }
409
+ .litespeed-btn-sm,
410
+ .litespeed-btn-group-sm > .litespeed-btn {
411
+ padding: 5px 10px;
412
+ font-size: 12px;
413
+ line-height: 1.5;
414
+ border-radius: 3px;
415
+ }
416
+ .litespeed-btn-xs,
417
+ .litespeed-btn-group-xs > .litespeed-btn {
418
+ padding: 1px 5px;
419
+ font-size: 12px;
420
+ line-height: 1.5;
421
+ border-radius: 3px;
422
+ }
423
+
424
+
425
+ .litespeed-btn-default,
426
+ .litespeed-btn-primary,
427
+ .litespeed-btn-success,
428
+ .litespeed-btn-info,
429
+ .litespeed-btn-warning,
430
+ .litespeed-btn-danger {
431
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, .2);
432
+ -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075);
433
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075);
434
+ }
435
+ .litespeed-btn-default:active,
436
+ .litespeed-btn-primary:active,
437
+ .litespeed-btn-success:active,
438
+ .litespeed-btn-info:active,
439
+ .litespeed-btn-warning:active,
440
+ .litespeed-btn-danger:active,
441
+ .litespeed-btn-default.active,
442
+ .litespeed-btn-primary.active,
443
+ .litespeed-btn-success.active,
444
+ .litespeed-btn-info.active,
445
+ .litespeed-btn-warning.active,
446
+ .litespeed-btn-danger.active {
447
+ -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
448
+ box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
449
+ }
450
+ .litespeed-btn-default.disabled,
451
+ .litespeed-btn-primary.disabled,
452
+ .litespeed-btn-success.disabled,
453
+ .litespeed-btn-info.disabled,
454
+ .litespeed-btn-warning.disabled,
455
+ .litespeed-btn-danger.disabled,
456
+ .litespeed-btn-default[disabled],
457
+ .litespeed-btn-primary[disabled],
458
+ .litespeed-btn-success[disabled],
459
+ .litespeed-btn-info[disabled],
460
+ .litespeed-btn-warning[disabled],
461
+ .litespeed-btn-danger[disabled],
462
+ fieldset[disabled] .litespeed-btn-default,
463
+ fieldset[disabled] .litespeed-btn-primary,
464
+ fieldset[disabled] .litespeed-btn-success,
465
+ fieldset[disabled] .litespeed-btn-info,
466
+ fieldset[disabled] .litespeed-btn-warning,
467
+ fieldset[disabled] .litespeed-btn-danger {
468
+ -webkit-box-shadow: none;
469
+ box-shadow: none;
470
+ }
471
+ .litespeed-btn-default .badge,
472
+ .litespeed-btn-primary .badge,
473
+ .litespeed-btn-success .badge,
474
+ .litespeed-btn-info .badge,
475
+ .litespeed-btn-warning .badge,
476
+ .litespeed-btn-danger .badge {
477
+ text-shadow: none;
478
+ }
479
+ .litespeed-btn:active,
480
+ .litespeed-btn.active {
481
+ background-image: none;
482
+ }
483
+ .litespeed-btn-default {
484
+ text-shadow: 0 1px 0 #fff;
485
+ background-image: -webkit-linear-gradient(top, #fff 0%, #e0e0e0 100%);
486
+ background-image: -o-linear-gradient(top, #fff 0%, #e0e0e0 100%);
487
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#e0e0e0));
488
+ background-image: linear-gradient(to bottom, #fff 0%, #e0e0e0 100%);
489
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);
490
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
491
+ background-repeat: repeat-x;
492
+ border-color: #dbdbdb;
493
+ border-color: #ccc;
494
+ }
495
+ .litespeed-btn-default:hover,
496
+ .litespeed-btn-default:focus {
497
+ background-color: #e0e0e0;
498
+ background-position: 0 -15px;
499
+ }
500
+ .litespeed-btn-default:active,
501
+ .litespeed-btn-default.active {
502
+ background-color: #e0e0e0;
503
+ border-color: #dbdbdb;
504
+ }
505
+ .litespeed-btn-default.disabled,
506
+ .litespeed-btn-default[disabled],
507
+ fieldset[disabled] .litespeed-btn-default,
508
+ .litespeed-btn-default.disabled:hover,
509
+ .litespeed-btn-default[disabled]:hover,
510
+ fieldset[disabled] .litespeed-btn-default:hover,
511
+ .litespeed-btn-default.disabled:focus,
512
+ .litespeed-btn-default[disabled]:focus,
513
+ fieldset[disabled] .litespeed-btn-default:focus,
514
+ .litespeed-btn-default.disabled.focus,
515
+ .litespeed-btn-default[disabled].focus,
516
+ fieldset[disabled] .litespeed-btn-default.focus,
517
+ .litespeed-btn-default.disabled:active,
518
+ .litespeed-btn-default[disabled]:active,
519
+ fieldset[disabled] .litespeed-btn-default:active,
520
+ .litespeed-btn-default.disabled.active,
521
+ .litespeed-btn-default[disabled].active,
522
+ fieldset[disabled] .litespeed-btn-default.active {
523
+ background-color: #e0e0e0;
524
+ background-image: none;
525
+ }
526
+ .litespeed-btn-primary {
527
+ background-image: -webkit-linear-gradient(top, #337ab7 0%, #265a88 100%);
528
+ background-image: -o-linear-gradient(top, #337ab7 0%, #265a88 100%);
529
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#265a88));
530
+ background-image: linear-gradient(to bottom, #337ab7 0%, #265a88 100%);
531
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);
532
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
533
+ background-repeat: repeat-x;
534
+ border-color: #245580;
535
+ }
536
+ .litespeed-btn-primary:hover,
537
+ .litespeed-btn-primary:focus {
538
+ background-color: #265a88;
539
+ background-position: 0 -15px;
540
+ }
541
+ .litespeed-btn-primary:active,
542
+ .litespeed-btn-primary.active {
543
+ background-color: #265a88;
544
+ border-color: #245580;
545
+ }
546
+ .litespeed-btn-primary.disabled,
547
+ .litespeed-btn-primary[disabled],
548
+ fieldset[disabled] .litespeed-btn-primary,
549
+ .litespeed-btn-primary.disabled:hover,
550
+ .litespeed-btn-primary[disabled]:hover,
551
+ fieldset[disabled] .litespeed-btn-primary:hover,
552
+ .litespeed-btn-primary.disabled:focus,
553
+ .litespeed-btn-primary[disabled]:focus,
554
+ fieldset[disabled] .litespeed-btn-primary:focus,
555
+ .litespeed-btn-primary.disabled.focus,
556
+ .litespeed-btn-primary[disabled].focus,
557
+ fieldset[disabled] .litespeed-btn-primary.focus,
558
+ .litespeed-btn-primary.disabled:active,
559
+ .litespeed-btn-primary[disabled]:active,
560
+ fieldset[disabled] .litespeed-btn-primary:active,
561
+ .litespeed-btn-primary.disabled.active,
562
+ .litespeed-btn-primary[disabled].active,
563
+ fieldset[disabled] .litespeed-btn-primary.active {
564
+ background-color: #265a88;
565
+ background-image: none;
566
+ }
567
+ .litespeed-btn-success {
568
+ background-image: -webkit-linear-gradient(top, #5cb85c 0%, #419641 100%);
569
+ background-image: -o-linear-gradient(top, #5cb85c 0%, #419641 100%);
570
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#419641));
571
+ background-image: linear-gradient(to bottom, #5cb85c 0%, #419641 100%);
572
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);
573
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
574
+ background-repeat: repeat-x;
575
+ border-color: #3e8f3e;
576
+ }
577
+ .litespeed-btn-success:hover,
578
+ .litespeed-btn-success:focus {
579
+ background-color: #419641;
580
+ background-position: 0 -15px;
581
+ }
582
+ .litespeed-btn-success:active,
583
+ .litespeed-btn-success.active {
584
+ background-color: #419641;
585
+ border-color: #3e8f3e;
586
+ }
587
+ .litespeed-btn-success.disabled,
588
+ .litespeed-btn-success[disabled],
589
+ fieldset[disabled] .litespeed-btn-success,
590
+ .litespeed-btn-success.disabled:hover,
591
+ .litespeed-btn-success[disabled]:hover,
592
+ fieldset[disabled] .litespeed-btn-success:hover,
593
+ .litespeed-btn-success.disabled:focus,
594
+ .litespeed-btn-success[disabled]:focus,
595
+ fieldset[disabled] .litespeed-btn-success:focus,
596
+ .litespeed-btn-success.disabled.focus,
597
+ .litespeed-btn-success[disabled].focus,
598
+ fieldset[disabled] .litespeed-btn-success.focus,
599
+ .litespeed-btn-success.disabled:active,
600
+ .litespeed-btn-success[disabled]:active,
601
+ fieldset[disabled] .litespeed-btn-success:active,
602
+ .litespeed-btn-success.disabled.active,
603
+ .litespeed-btn-success[disabled].active,
604
+ fieldset[disabled] .litespeed-btn-success.active {
605
+ background-color: #419641;
606
+ background-image: none;
607
+ }
608
+ .litespeed-btn-info {
609
+ background-image: -webkit-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);
610
+ background-image: -o-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);
611
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#2aabd2));
612
+ background-image: linear-gradient(to bottom, #5bc0de 0%, #2aabd2 100%);
613
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);
614
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
615
+ background-repeat: repeat-x;
616
+ border-color: #28a4c9;
617
+ }
618
+ .litespeed-btn-info:hover,
619
+ .litespeed-btn-info:focus {
620
+ background-color: #2aabd2;
621
+ background-position: 0 -15px;
622
+ }
623
+ .litespeed-btn-info:active,
624
+ .litespeed-btn-info.active {
625
+ background-color: #2aabd2;
626
+ border-color: #28a4c9;
627
+ }
628
+ .litespeed-btn-info.disabled,
629
+ .litespeed-btn-info[disabled],
630
+ fieldset[disabled] .litespeed-btn-info,
631
+ .litespeed-btn-info.disabled:hover,
632
+ .litespeed-btn-info[disabled]:hover,
633
+ fieldset[disabled] .litespeed-btn-info:hover,
634
+ .litespeed-btn-info.disabled:focus,
635
+ .litespeed-btn-info[disabled]:focus,
636
+ fieldset[disabled] .litespeed-btn-info:focus,
637
+ .litespeed-btn-info.disabled.focus,
638
+ .litespeed-btn-info[disabled].focus,
639
+ fieldset[disabled] .litespeed-btn-info.focus,
640
+ .litespeed-btn-info.disabled:active,
641
+ .litespeed-btn-info[disabled]:active,
642
+ fieldset[disabled] .litespeed-btn-info:active,
643
+ .litespeed-btn-info.disabled.active,
644
+ .litespeed-btn-info[disabled].active,
645
+ fieldset[disabled] .litespeed-btn-info.active {
646
+ background-color: #2aabd2;
647
+ background-image: none;
648
+ }
649
+ .litespeed-btn-warning {
650
+ background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);
651
+ background-image: -o-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);
652
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#eb9316));
653
+ background-image: linear-gradient(to bottom, #f0ad4e 0%, #eb9316 100%);
654
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);
655
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
656
+ background-repeat: repeat-x;
657
+ border-color: #e38d13;
658
+ }
659
+ .litespeed-btn-warning:hover,
660
+ .litespeed-btn-warning:focus {
661
+ background-color: #eb9316;
662
+ background-position: 0 -15px;
663
+ }
664
+ .litespeed-btn-warning:active,
665
+ .litespeed-btn-warning.active {
666
+ background-color: #eb9316;
667
+ border-color: #e38d13;
668
+ }
669
+ .litespeed-btn-warning.disabled,
670
+ .litespeed-btn-warning[disabled],
671
+ fieldset[disabled] .litespeed-btn-warning,
672
+ .litespeed-btn-warning.disabled:hover,
673
+ .litespeed-btn-warning[disabled]:hover,
674
+ fieldset[disabled] .litespeed-btn-warning:hover,
675
+ .litespeed-btn-warning.disabled:focus,
676
+ .litespeed-btn-warning[disabled]:focus,
677
+ fieldset[disabled] .litespeed-btn-warning:focus,
678
+ .litespeed-btn-warning.disabled.focus,
679
+ .litespeed-btn-warning[disabled].focus,
680
+ fieldset[disabled] .litespeed-btn-warning.focus,
681
+ .litespeed-btn-warning.disabled:active,
682
+ .litespeed-btn-warning[disabled]:active,
683
+ fieldset[disabled] .litespeed-btn-warning:active,
684
+ .litespeed-btn-warning.disabled.active,
685
+ .litespeed-btn-warning[disabled].active,
686
+ fieldset[disabled] .litespeed-btn-warning.active {
687
+ background-color: #eb9316;
688
+ background-image: none;
689
+ }
690
+ .litespeed-btn-danger {
691
+ background-image: -webkit-linear-gradient(top, #d9534f 0%, #c12e2a 100%);
692
+ background-image: -o-linear-gradient(top, #d9534f 0%, #c12e2a 100%);
693
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c12e2a));
694
+ background-image: linear-gradient(to bottom, #d9534f 0%, #c12e2a 100%);
695
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);
696
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
697
+ background-repeat: repeat-x;
698
+ border-color: #b92c28;
699
+ }
700
+ .litespeed-btn-danger:hover,
701
+ .litespeed-btn-danger:focus {
702
+ background-color: #c12e2a;
703
+ background-position: 0 -15px;
704
+ }
705
+ .litespeed-btn-danger:active,
706
+ .litespeed-btn-danger.active {
707
+ background-color: #c12e2a;
708
+ border-color: #b92c28;
709
+ }
710
+ .litespeed-btn-danger.disabled,
711
+ .litespeed-btn-danger[disabled],
712
+ fieldset[disabled] .litespeed-btn-danger,
713
+ .litespeed-btn-danger.disabled:hover,
714
+ .litespeed-btn-danger[disabled]:hover,
715
+ fieldset[disabled] .litespeed-btn-danger:hover,
716
+ .litespeed-btn-danger.disabled:focus,
717
+ .litespeed-btn-danger[disabled]:focus,
718
+ fieldset[disabled] .litespeed-btn-danger:focus,
719
+ .litespeed-btn-danger.disabled.focus,
720
+ .litespeed-btn-danger[disabled].focus,
721
+ fieldset[disabled] .litespeed-btn-danger.focus,
722
+ .litespeed-btn-danger.disabled:active,
723
+ .litespeed-btn-danger[disabled]:active,
724
+ fieldset[disabled] .litespeed-btn-danger:active,
725
+ .litespeed-btn-danger.disabled.active,
726
+ .litespeed-btn-danger[disabled].active,
727
+ fieldset[disabled] .litespeed-btn-danger.active {
728
+ background-color: #c12e2a;
729
+ background-image: none;
730
+ }
admin/css/litespeed-cache-admin.css ADDED
@@ -0,0 +1,269 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * All of the CSS for your admin-specific functionality should be
3
+ * included in this file.
4
+ */
5
+ @import "litespeed-common.css";
6
+ @import "litespeed-btn.css";
7
+ @import "litespeed-checkbox.css";
8
+ @import "litespeed-label.css";
9
+ @import "litespeed-callout.css";
10
+ @import "litespeed-icon.css";
11
+
12
+ #litespeedcache-purgeerrors{
13
+ margin:5px 0 15px 22px;
14
+ }
15
+
16
+ .litespeed-cache-welcome-panel .form-table > tbody > tr > th{
17
+ padding-left: 10px;
18
+ }
19
+ .litespeed-cache-welcome-panel .form-table > tbody > tr:nth-of-type(odd){
20
+ background-color: #f9f9f9;
21
+ }
22
+
23
+ .litespeed-cache-advanced-settings{
24
+ position: relative;
25
+ background: #fff;
26
+ font-size: 14px;
27
+ line-height: 2.1em;
28
+ }
29
+
30
+
31
+ .litespeed-cache-advanced-settings h3{
32
+ display:inline;
33
+ }
34
+
35
+ textarea#purgebylist{
36
+ height: auto;
37
+ min-height: 100%;
38
+ width: 100%;
39
+ position: relative;
40
+ -webkit-font-smoothing: subpixel-antialiased;
41
+ }
42
+
43
+ /* litespeed new style */
44
+ .litespeed-tab{
45
+ border-top-left-radius : 8px;
46
+ border-top-right-radius : 8px;
47
+ }
48
+
49
+ .litespeed-tab.nav-tab-active{
50
+ background-color: #FFFFFF;
51
+ border-bottom-color: #FFFFFF;
52
+ }
53
+
54
+ .litespeed-cache-welcome-panel{
55
+ background: none repeat scroll 0 0 #fff;
56
+ border: 1px solid #e5e5e5;
57
+ box-shadow: 0 2px 2px rgba(0, 0, 0, 0.05);
58
+ font-size: 14px;
59
+ /*line-height: 2em;*/
60
+ margin: 0px 0px 20px 0;
61
+ overflow: auto;
62
+ padding: 10px 15px 15px 15px;
63
+ position: relative;
64
+ border-top: none;
65
+ }
66
+ .litespeed-cache-welcome-panel p{
67
+ font-size: 14px;
68
+ margin: 0 0 10px;
69
+ }
70
+ .litespeed-cache-welcome-panel ul {
71
+ list-style: disc outside;
72
+ margin-left: 20px;
73
+ padding-left: 10px;
74
+ }
75
+
76
+ .litespeed-input-long{
77
+ width:580px;
78
+ }
79
+
80
+ .litespeed-title{
81
+ font-size: 18px;
82
+ color: #000;
83
+ border-bottom: 1px solid #d8d8d8;
84
+ margin-top: 10px;
85
+ margin-bottom: 20px;
86
+ display: table;
87
+ padding-right: 50px;
88
+ }
89
+
90
+ .litespeed-title:not(:first-of-type){
91
+ margin-top: 30px;
92
+ }
93
+
94
+ .litespeed-expend{
95
+ text-decoration: none;
96
+ font-size: 21px;
97
+ width: 40px;
98
+ text-align: center;
99
+ display: inline-block;
100
+ }
101
+
102
+ /* Manage */
103
+
104
+ .litespeed-cache-purgeby-text{
105
+ font-size: 11px;
106
+ font-style: italic;
107
+ padding-left: 20px;
108
+ display: inline-block;
109
+ vertical-align: top;
110
+ }
111
+
112
+ .litespeed-cache-purgeby-textarea,
113
+ .litespeed-cache-blacklist{
114
+ margin-top: 10px;
115
+ height: auto;
116
+ width: 100%;
117
+ position: relative;
118
+ -webkit-font-smoothing: subpixel-antialiased;
119
+ }
120
+
121
+ .litespeed-cache-blacklist{
122
+ max-width: 600px;
123
+ }
124
+
125
+ /* FAQ */
126
+ .litespeed-question{
127
+ background-color: #eee;
128
+ border: 1px solid #eee;
129
+ border-left: 5px solid #1b809e;
130
+ border-radius: 3px;
131
+ padding: 20px;
132
+ margin: 0 20px 5px 10px;
133
+ font-size: 15px;
134
+ font-family: inherit;
135
+ font-weight: 500;
136
+ line-height: 1.1;
137
+ }
138
+
139
+ .litespeed-question:hover{
140
+ opacity: 0.8;
141
+ cursor: pointer;
142
+ }
143
+
144
+ .litespeed-answer{
145
+ margin-left: 20px;
146
+ padding: 0 20px 20px 20px;
147
+ }
148
+
149
+ .litespeed-notice{
150
+ font-size: 11px;
151
+ font-style: italic;
152
+ margin-left: 10px;
153
+ position: relative;
154
+ top: 3px;
155
+ color: green;
156
+ }
157
+
158
+
159
+ /* shell */
160
+ .litespeed-shell {
161
+ width: 98%;
162
+ background: #141414;
163
+ margin: 20px auto 0 10px;
164
+ box-shadow: 0 0 5px rgba(0,0,0,0.4);
165
+ -webkit-border-radius: 3px;
166
+ -moz-border-radius: 3px;
167
+ border-radius: 3px;
168
+ position: relative;
169
+ height: 224px;
170
+ }
171
+
172
+ .litespeed-shell-header {
173
+ z-index: 999;
174
+ position: absolute;
175
+ top: 0;
176
+ right: 0;
177
+ width: 50px;
178
+ height: 34px;
179
+ padding: 5px 0;
180
+ }
181
+
182
+ .litespeed-shell-header-bg {
183
+ opacity: 0.4;
184
+ background-color: #CCCCCC;
185
+ position: absolute;
186
+ top: 0;
187
+ bottom: 0;
188
+ right: 0;
189
+ left: 0;
190
+ z-index: 4;
191
+ -webkit-border-radius: 3px;
192
+ -moz-border-radius: 3px;
193
+ border-top-radius: 3px;
194
+ }
195
+
196
+ .litespeed-shell-header-bar {
197
+ position: absolute;
198
+ top: 0;
199
+ left: 0;
200
+ z-index: 10;
201
+ height: 2px;
202
+ background-color: #F48024;
203
+ }
204
+
205
+ /*.litespeed-shell-header-num{
206
+ position: absolute;
207
+ bottom: 2px;
208
+ right: 2px;
209
+ width: 14px;
210
+ height: 14px;
211
+ text-align: left;
212
+ color: #808080;
213
+ font-size: 0.85em;
214
+ z-index: 5;
215
+ display: none;
216
+ }*/
217
+
218
+ .litespeed-shell-header-icon-container{
219
+ position: absolute;
220
+ top: 10px;
221
+ right: 10px;
222
+ width: 29px;
223
+ height: 34px;
224
+ z-index: 6;
225
+ }
226
+
227
+ ul.litespeed-shell-body {
228
+ position: absolute;
229
+ top: 0;
230
+ left: 0;
231
+ right: 0;
232
+ bottom: 0;
233
+ overflow-y: scroll;
234
+ margin: 0;
235
+ padding: 5px;
236
+ list-style: none;
237
+ background: #141414;
238
+ color: #45D40C;
239
+ font: 0.8em 'Andale Mono', Consolas, 'Courier New';
240
+ line-height: 1.6em;
241
+
242
+ -webkit-border-bottom-right-radius: 3px;
243
+ -webkit-border-bottom-left-radius: 3px;
244
+ -moz-border-radius-bottomright: 3px;
245
+ -moz-border-radius-bottomleft: 3px;
246
+ border-bottom-right-radius: 3px;
247
+ border-bottom-left-radius: 3px;
248
+
249
+ }
250
+
251
+ .litespeed-shell-body li:before {
252
+ content: '>';
253
+ position: absolute;
254
+ left: 0;
255
+ top: 0;
256
+ }
257
+
258
+ .litespeed-shell-body li {
259
+ word-wrap: break-word;
260
+ position: relative;
261
+ padding: 0 0 0 15px;
262
+ margin: 0;
263
+ }
264
+
265
+ .litespeed-widget-setting{
266
+ background-color: #ecebdc;
267
+ padding: 5px 14px;
268
+ margin: 5px -15px;
269
+ }
admin/css/litespeed-callout.css ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /** callout style **/
2
+ .litespeed-callout2{
3
+ margin: 20px;
4
+ border-left: 1px solid #999;
5
+ padding-left: 10px;
6
+ }
7
+
8
+ .litespeed-callout2 h4{
9
+ font-size: 2.0em;
10
+ margin-bottom: 10px;
11
+ }
12
+
13
+ .litespeed-callout {
14
+ padding: 10px 25px;
15
+ margin: 10px 0;
16
+ border: 1px solid #eee;
17
+ border-left-width: 5px;
18
+ border-radius: 3px;
19
+ }
20
+
21
+ .litespeed-callout+.litespeed-callout {
22
+ margin-top: -5px;
23
+ }
24
+
25
+ .litespeed-callout p:last-child {
26
+ margin-bottom: 0;
27
+ }
28
+
29
+ .litespeed-callout h4 {
30
+ margin-top: 0;
31
+ margin-bottom: 5px;
32
+ margin-left: -10px;
33
+ font-size: 14px;
34
+ font-family: inherit;
35
+ font-weight: 500;
36
+ line-height: 1.1;
37
+ color: inherit;
38
+ }
39
+
40
+ .litespeed-callout ol{
41
+ margin-bottom: 0;
42
+ }
43
+
44
+ .litespeed-callout-info{
45
+ border-left-color: #1b809e;
46
+ }
47
+ .litespeed-callout-info h4{
48
+ color: #1b809e;
49
+ }
50
+
51
+ .litespeed-callout-warning{
52
+ border-left-color: #aa6708;
53
+ }
54
+ .litespeed-callout-warning h4{
55
+ color: #aa6708;
56
+ }
57
+
58
+ .litespeed-callout-danger{
59
+ border-left-color: #ce4844;
60
+ }
61
+ .litespeed-callout-danger h4{
62
+ color: #ce4844;
63
+ }
admin/css/litespeed-checkbox.css ADDED
@@ -0,0 +1,356 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .litespeed-radio{
2
+ display: inline-block;
3
+ margin-right: 5px;
4
+ }
5
+
6
+ .litespeed-radio label {
7
+ min-width: 115px;
8
+ border-radius: 3px;
9
+ border: 1px solid #D1D3D4;
10
+ padding-right: 10px;
11
+ }
12
+
13
+ .litespeed-radio.litespeed-mini label {
14
+ min-width: 75px;
15
+ padding-right: 5px;
16
+ }
17
+
18
+ .litespeed-radio input:checked:before,
19
+ .litespeed-radio input:empty {
20
+ width: initial;
21
+ height: initial;
22
+ margin: initial;
23
+ min-width: initial;
24
+ border: initial;
25
+ content: initial;
26
+ }
27
+
28
+ .litespeed-radio input:empty {
29
+ -moz-appearance: none;
30
+ -webkit-appearance: none;
31
+ appearance: none;
32
+ }
33
+
34
+ /* style label */
35
+ .litespeed-radio input:empty ~ label {
36
+ position: relative;
37
+ float: left;
38
+ line-height: 2.5em;
39
+ text-indent: 3.25em;
40
+ cursor: pointer;
41
+ -webkit-user-select: none;
42
+ -moz-user-select: none;
43
+ -ms-user-select: none;
44
+ user-select: none;
45
+ }
46
+
47
+ .litespeed-radio.litespeed-mini input:empty ~ label {
48
+ line-height: 1.3em;
49
+ text-indent: 1.75em;
50
+ }
51
+
52
+ .litespeed-radio input:empty ~ label:before {
53
+ position: absolute;
54
+ display: block;
55
+ top: 0;
56
+ bottom: 0;
57
+ left: 0;
58
+ content: '';
59
+ width: 2.5em;
60
+ background: #D1D3D4;
61
+ border-radius: 3px 0 0 3px;
62
+ }
63
+
64
+ .litespeed-radio.litespeed-mini input:empty ~ label:before {
65
+ width: 1.3em;
66
+ border-radius: 1px 0 0 1px;
67
+ }
68
+
69
+ .litespeed-radio input:empty ~ label:before {
70
+ content:'\2714';
71
+ text-indent: .9em;
72
+ }
73
+
74
+ .litespeed-radio.cross input:empty ~ label:before {
75
+ content:'\2716';
76
+ }
77
+
78
+ .litespeed-radio.litespeed-mini input ~ label:before {
79
+ text-indent: .2em;
80
+ }
81
+
82
+ .litespeed-radio input:not(:checked) ~ label:before {
83
+ color: #C2C2C2;
84
+ }
85
+
86
+ /* toggle hover */
87
+ .litespeed-radio input:hover:not(:checked) ~ label:before {
88
+ color: #717171;
89
+ }
90
+
91
+ .litespeed-radio input:hover:not(:checked) ~ label {
92
+ color: #777;
93
+ }
94
+
95
+ /* toggle on */
96
+ .litespeed-radio input:checked ~ label:before {
97
+ color: #9CE2AE;
98
+ background-color: #4DCB6D;
99
+ }
100
+
101
+ .litespeed-radio.cross input:checked ~ label:before {
102
+ color: #faf4d5;
103
+ background-color: #f0ad4e;
104
+ }
105
+
106
+ .litespeed-radio.litespeed-mini input:checked ~ label:before {
107
+ text-indent: .2em;
108
+ }
109
+
110
+ .litespeed-radio input:checked ~ label {
111
+ /*color: #888;*/
112
+ }
113
+
114
+ /* radio focus */
115
+ .litespeed-radio input:focus ~ label:before {
116
+ /*box-shadow: 0 0 0 3px #999;*/
117
+ }
118
+
119
+ /******** switch **************/
120
+ .litespeed-switch{
121
+ display: inline-block;
122
+ }
123
+
124
+ .litespeed-switch input {
125
+ display: none;
126
+ }
127
+ .litespeed-switch label {
128
+ font-size: 13px;
129
+ display: inline-block;
130
+ min-width: 80px;
131
+ background-color: #e4e4e4;
132
+ color: #333;
133
+ font-weight: normal;
134
+ text-align: center;
135
+ text-shadow: none;
136
+ padding: 4px 9px;
137
+ border: 1px solid rgba(0, 0, 0, 0.2);
138
+ -webkit-transition: all 0.1s ease-in-out;
139
+ -moz-transition: all 0.1s ease-in-out;
140
+ -ms-transition: all 0.1s ease-in-out;
141
+ -o-transition: all 0.1s ease-in-out;
142
+ transition: all 0.1s ease-in-out;
143
+ float: left;
144
+ cursor: pointer;
145
+ -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.3), 0 1px rgba(255, 255, 255, 0.1);
146
+ box-shadow: inset 0 1px 3px -1px rgba(0, 0, 0, 0.3), inset 0 -1px 3px -1px rgba(0, 0, 0, 0.3);
147
+ }
148
+
149
+ .litespeed-switch label:hover{
150
+ color: #666;
151
+ background-color: #dedddd ;
152
+ }
153
+
154
+ .litespeed-switch label:first-of-type,.litespeed-switch label:last-of-type {
155
+ box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.3), 0 1px rgba(255, 255, 255, 0.1);
156
+ }
157
+
158
+ .litespeed-switch label:first-of-type:hover,
159
+ .litespeed-switch label:last-of-type:hover {
160
+ box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1), 0 1px rgba(255, 255, 255, 0.1);
161
+ }
162
+
163
+ .litespeed-switch label:first-of-type {
164
+ border-radius: 4px 0 0 4px;
165
+ }
166
+
167
+ .litespeed-switch label:last-of-type {
168
+ border-radius: 0 4px 4px 0;
169
+ }
170
+
171
+ .litespeed-switch input:checked + label {
172
+ background-color: #8a8a8a;
173
+ -webkit-box-shadow: none;
174
+ box-shadow: none;
175
+ color: #fff;
176
+ }
177
+
178
+ .litespeed-switch.litespeed-label-info,
179
+ .litespeed-switch.litespeed-label-success,
180
+ .litespeed-switch.litespeed-label-warning,
181
+ .litespeed-switch.litespeed-label-danger{
182
+ background-color: initial;
183
+ }
184
+
185
+ /* .litespeed-switch.litespeed-label-info label:hover, */
186
+ .litespeed-switch.litespeed-label-info input:checked + label {
187
+ background-color: #43A6DF;
188
+ }
189
+
190
+ .litespeed-switch.litespeed-label-info input:checked + label:hover {
191
+ background-color: #40a0d8 ;
192
+ }
193
+
194
+ /*.litespeed-switch.litespeed-label-success label:hover,*/
195
+ .litespeed-switch.litespeed-label-success input:checked + label {
196
+ background-color: #5cb85c;
197
+ }
198
+ /*.litespeed-switch.litespeed-label-warning label:hover,*/
199
+ .litespeed-switch.litespeed-label-warning input:checked + label {
200
+ background-color: #f0ad4e;
201
+ }
202
+ /*.litespeed-switch.litespeed-label-danger label:hover,*/
203
+ .litespeed-switch.litespeed-label-danger input:checked + label {
204
+ background-color: #d9534f;
205
+ }
206
+
207
+ .litespeed-switch.litespeed-mini label{
208
+ padding: 1px;
209
+ font-size: 12px;
210
+ line-height: 1.9em;
211
+ }
212
+
213
+ /*.litespeed-switch input[disabled] + label:hover {
214
+ background-color: #e4e4e4;
215
+ color: #333;
216
+ -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.3), 0 1px rgba(255, 255, 255, 0.1);
217
+ box-shadow: inset 0 1px 3px -1px rgba(0, 0, 0, 0.3), inset 0 -1px 3px -1px rgba(0, 0, 0, 0.3);
218
+ }
219
+
220
+ .litespeed-switch input[disabled] + label:first-of-type:hover,.litespeed-switch input[disabled] + label:last-of-type:hover {
221
+ box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.3), 0 1px rgba(255, 255, 255, 0.1);
222
+ }
223
+
224
+ .litespeed-switch input[disabled]:checked + label:hover {
225
+ background-color: #8a8a8a;
226
+ color: #fff;
227
+ }*/
228
+
229
+ .litespeed-switch input[disabled]:checked + label {
230
+ background-color: #8a8a8a;
231
+ }
232
+
233
+
234
+ /******** round on/off switch **************/
235
+ .litespeed-switch-onoff {
236
+ position: relative;
237
+ display: block;
238
+ vertical-align: top;
239
+ width: 100px;
240
+ height: 30px;
241
+ padding: 3px;
242
+ margin:0;
243
+ background: linear-gradient(to bottom, #eeeeee, #FFFFFF 25px);
244
+ background-image: -webkit-linear-gradient(top, #eeeeee, #FFFFFF 25px);
245
+ border-radius: 18px;
246
+ box-shadow: inset 0 -1px white, inset 0 1px 1px rgba(0, 0, 0, 0.05);
247
+ cursor: pointer;
248
+ box-sizing:content-box;
249
+ }
250
+
251
+ .litespeed-switch-onoff input,
252
+ .litespeed-switch-onoff input:disabled {
253
+ position: absolute;
254
+ top: 0;
255
+ left: 0;
256
+ opacity: 0;
257
+ box-sizing:content-box;
258
+ }
259
+
260
+ .litespeed-switch-onoff span:first-of-type {
261
+ position: relative;
262
+ display: block;
263
+ height: inherit;
264
+ font-size: 10px;
265
+ text-transform: uppercase;
266
+ background: #eceeef;
267
+ border-radius: inherit;
268
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.12), inset 0 0 2px rgba(0, 0, 0, 0.15);
269
+ box-sizing:content-box;
270
+ overflow: hidden;
271
+ }
272
+ .litespeed-switch-onoff span:first-of-type:before, .litespeed-switch-onoff span:first-of-type:after {
273
+ position: absolute;
274
+ margin-top: -.5em;
275
+ line-height: 1;
276
+ -webkit-transition: inherit;
277
+ -moz-transition: inherit;
278
+ -o-transition: inherit;
279
+ transition: inherit;
280
+ box-sizing:content-box;
281
+
282
+ width: 20px;
283
+ height: 20px;
284
+ top: 4px;
285
+ left: 0;
286
+ right: 0;
287
+ bottom: 0;
288
+ padding: 11px 0 0 0;
289
+ border-radius: 20px;
290
+ box-shadow: inset 0 1px 4px rgba(0, 0, 0, 0.2), inset 0 0 3px rgba(0, 0, 0, 0.1);
291
+ }
292
+ .litespeed-switch-onoff span:first-of-type:before {
293
+ content: attr(data-off);
294
+ right: 11px;
295
+ color: #aaaaaa;
296
+ text-shadow: 0 1px rgba(255, 255, 255, 0.5);
297
+ background: #eceeef;
298
+ text-align: left;
299
+ padding-left: 80px;
300
+ text-indent: -40px;
301
+ }
302
+ .litespeed-switch-onoff span:first-of-type:after {
303
+ content: attr(data-on);
304
+ color: #FFFFFF;
305
+ text-shadow: 0 1px rgba(0, 0, 0, 0.2);
306
+ text-align: left;
307
+ text-indent: 9px;
308
+ background: #FF7F50;
309
+ left: -100px;
310
+ width: 100%;
311
+ }
312
+ .litespeed-switch-onoff input:checked ~ span:first-of-type {
313
+ background: #E1B42B;
314
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.15), inset 0 0 3px rgba(0, 0, 0, 0.2);
315
+ }
316
+ .litespeed-switch-onoff input:checked ~ span:first-of-type:before {
317
+ left: 100px;
318
+ }
319
+ .litespeed-switch-onoff input:checked ~ span:first-of-type:after {
320
+ left: 0;
321
+ }
322
+ .litespeed-switch-onoff span:last-of-type {
323
+ position: absolute;
324
+ top: 4px;
325
+ left: 4px;
326
+ width: 28px;
327
+ height: 28px;
328
+ background: linear-gradient(to bottom, #FFFFFF 40%, #f0f0f0);
329
+ background-image: -webkit-linear-gradient(top, #FFFFFF 40%, #f0f0f0);
330
+ border-radius: 100%;
331
+ box-shadow: 1px 1px 5px rgba(0, 0, 0, 0.2);
332
+ }
333
+ .litespeed-switch-onoff span:last-of-type:before {
334
+ content: "";
335
+ position: absolute;
336
+ top: 50%;
337
+ left: 50%;
338
+ margin: -6px 0 0 -6px;
339
+ width: 12px;
340
+ height: 12px;
341
+ background: linear-gradient(to bottom, #eeeeee, #FFFFFF);
342
+ background-image: -webkit-linear-gradient(top, #eeeeee, #FFFFFF);
343
+ border-radius: 6px;
344
+ box-shadow: inset 0 1px rgba(0, 0, 0, 0.02);
345
+ }
346
+ .litespeed-switch-onoff input:checked ~ span:last-of-type {
347
+ left: 74px;
348
+ box-shadow: -1px 1px 5px rgba(0, 0, 0, 0.2);
349
+ }
350
+
351
+ .litespeed-switch-onoff span{
352
+ transition: All 0.3s ease;
353
+ -webkit-transition: All 0.3s ease;
354
+ -moz-transition: All 0.3s ease;
355
+ -o-transition: All 0.3s ease;
356
+ }
admin/css/litespeed-common.css ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Litespeed common */
2
+ .litespeed-row{
3
+ display: block;
4
+ margin-top: 5px;
5
+ }
6
+
7
+ .litespeed-reset{
8
+ width: initial;
9
+ }
10
+
11
+ .litespeed-inline{
12
+ display: inline-block;
13
+ }
14
+
15
+ .litespeed-left{
16
+ float: left;
17
+ }
18
+
19
+ .litespeed-row:before{
20
+ content: " ";
21
+ }
22
+
23
+ .litespeed-row:after,
24
+ .litespeed-clearfix:after{
25
+ content: " ";
26
+ display: block;
27
+ clear: both;
28
+ }
29
+
30
+ .litespeed-desc{
31
+ font-size: 12px;
32
+ font-weight: normal;
33
+ color: #9e9e9e;
34
+ margin-top: 5px;
35
+ }
36
+
37
+ .litespeed-hide{
38
+ display: none;
39
+ }
40
+
41
+ .litespeed-top10{
42
+ margin-top: 10px;
43
+ }
44
+
45
+ .litespeed-top15{
46
+ margin-top: 15px;
47
+ }
48
+
49
+ .litespeed-top20{
50
+ margin-top: 20px;
51
+ }
52
+
53
+ .litespeed-down:after{
54
+ content: ' ';
55
+ border: solid #16c316;
56
+ border-width: 0 3px 3px 0;
57
+ display: inline-block;
58
+ padding: 3px;
59
+ margin-left: 15px;
60
+ transform: rotate(45deg);
61
+ -webkit-transform: rotate(45deg);
62
+ -webkit-transition: all .3s ease;
63
+ -moz-transition: all .3s ease;
64
+ -ms-transition: all .3s ease;
65
+ -o-transition: all .3s ease;
66
+ }
67
+
68
+ .litespeed-up:after{
69
+ content: ' ';
70
+ border: solid #16c316;
71
+ border-width: 0 3px 3px 0;
72
+ display: inline-block;
73
+ padding: 3px;
74
+ margin-left: 15px;
75
+ transform: rotate(-135deg);
76
+ -webkit-transform: rotate(-135deg);
77
+ -webkit-transition: all .3s ease;
78
+ -moz-transition: all .3s ease;
79
+ -ms-transition: all .3s ease;
80
+ -o-transition: all .3s ease;
81
+ }
admin/css/litespeed-icon.css ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @font-face {
2
+ font-family: 'litespeedfont';
3
+ src: url('fonts/litespeedfont.eot?rs8ttq');
4
+ src: url('fonts/litespeedfont.eot?rs8ttq#iefix') format('embedded-opentype'),
5
+ url('fonts/litespeedfont.ttf?rs8ttq') format('truetype'),
6
+ url('fonts/litespeedfont.woff?rs8ttq') format('woff'),
7
+ url('fonts/litespeedfont.svg?rs8ttq#litespeedfont') format('svg');
8
+ font-weight: normal;
9
+ font-style: normal;
10
+ }
11
+
12
+ #adminmenu #toplevel_page_lscache-dash .menu-icon-generic div.wp-menu-image:before,
13
+ .litespeed-top-toolbar .ab-icon::before{
14
+ content: "\e900";
15
+ font-family: 'litespeedfont' !important;
16
+ speak: none;
17
+ font-style: normal;
18
+ font-weight: normal;
19
+ font-variant: normal;
20
+ text-transform: none;
21
+ line-height: 1;
22
+
23
+ /* Better Font Rendering =========== */
24
+ -webkit-font-smoothing: antialiased;
25
+ -moz-osx-font-smoothing: grayscale;
26
+
27
+ }
admin/css/litespeed-label.css ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .litespeed-label {
2
+ display: inline;
3
+ padding: .2em .6em .3em;
4
+ font-size: 75%;
5
+ font-weight: bold;
6
+ line-height: 1;
7
+ color: #fff;
8
+ text-align: center;
9
+ white-space: nowrap;
10
+ vertical-align: baseline;
11
+ border-radius: .25em;
12
+ }
13
+ a.litespeed-label:hover,
14
+ a.litespeed-label:focus {
15
+ color: #fff;
16
+ text-decoration: none;
17
+ cursor: pointer;
18
+ }
19
+ .litespeed-label:empty {
20
+ display: none;
21
+ }
22
+ .btn .litespeed-label {
23
+ position: relative;
24
+ top: -1px;
25
+ }
26
+ .litespeed-label-default {
27
+ background-color: #777;
28
+ }
29
+ .litespeed-label-default[href]:hover,
30
+ .litespeed-label-default[href]:focus {
31
+ background-color: #5e5e5e;
32
+ }
33
+ .litespeed-label-primary {
34
+ background-color: #337ab7;
35
+ }
36
+ .litespeed-label-primary[href]:hover,
37
+ .litespeed-label-primary[href]:focus {
38
+ background-color: #286090;
39
+ }
40
+ .litespeed-label-success {
41
+ background-color: #5cb85c;
42
+ }
43
+ .litespeed-label-success[href]:hover,
44
+ .litespeed-label-success[href]:focus {
45
+ background-color: #449d44;
46
+ }
47
+ .litespeed-label-info {
48
+ background-color: #5bc0de;
49
+ }
50
+ .litespeed-label-info[href]:hover,
51
+ .litespeed-label-info[href]:focus {
52
+ background-color: #31b0d5;
53
+ }
54
+ .litespeed-label-warning {
55
+ background-color: #f0ad4e;
56
+ }
57
+ .litespeed-label-warning[href]:hover,
58
+ .litespeed-label-warning[href]:focus {
59
+ background-color: #ec971f;
60
+ }
61
+ .litespeed-label-danger {
62
+ background-color: #d9534f;
63
+ }
64
+ .litespeed-label-danger[href]:hover,
65
+ .litespeed-label-danger[href]:focus {
66
+ background-color: #c9302c;
67
+ }
admin/css/snowman.css ADDED
@@ -0,0 +1,685 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*body {
2
+ background-color: #31a7c3;
3
+ *zoom: 1;
4
+ filter: progid:DXImageTransform.Microsoft.gradient(gradientType=1, startColorstr='#FFAEE4FB', endColorstr='#FF2A8DC5');
5
+ background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PHJhZGlhbEdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgY3g9IjUwJSIgY3k9IiIgcj0iMTAwJSI+PHN0b3Agb2Zmc2V0PSIxMCUiIHN0b3AtY29sb3I9IiNhZWU0ZmIiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiMyYThkYzUiLz48L3JhZGlhbEdyYWRpZW50PjwvZGVmcz48cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSJ1cmwoI2dyYWQpIiAvPjwvc3ZnPiA=');
6
+ background-size: 100%;
7
+ background-image: -moz-radial-gradient(center, ellipse cover, #aee4fb 10%, #2a8dc5 100%);
8
+ background-image: -webkit-radial-gradient(center, ellipse cover, #aee4fb 10%, #2a8dc5 100%);
9
+ background-image: radial-gradient(ellipse cover at center, #aee4fb 10%, #2a8dc5 100%);
10
+ }
11
+ body .container {
12
+ max-width: 550px;
13
+ padding: 0;
14
+ margin: 0 auto;
15
+ min-height: 450px;
16
+ }
17
+ body .container :before, body .container :after {
18
+ position: absolute;
19
+ content: "";
20
+ width: 0;
21
+ height: 0;
22
+ }*/
23
+
24
+ .olaf-container {
25
+ position: absolute;
26
+ height: 400px;
27
+ width: 120px;
28
+ top: calc(50% - 200px);
29
+ left: calc(50% - 60px);
30
+ margin-top: -15px;
31
+ }
32
+
33
+ .olaf {
34
+ height: 160px;
35
+ width: 120px;
36
+ margin: 230px auto 0 auto;
37
+ position: relative;
38
+ }
39
+ .olaf * {
40
+ position: absolute;
41
+ }
42
+ .olaf .head {
43
+ top: -152px;
44
+ left: calc(50% - (96px / 2));
45
+ width: 96px;
46
+ height: 116px;
47
+ background-color: #FFFFFF;
48
+ margin-top: 44px;
49
+ -moz-border-radius: 20% 20% 50% 50%/15% 15% 85% 85%;
50
+ -webkit-border-radius: 20%;
51
+ border-radius: 20% 20% 50% 50%/15% 15% 85% 85%;
52
+ -moz-box-shadow: inset 10px -2px 35px -5px rgba(0, 0, 0, 0.3), inset 0 -8px 5px -5px rgba(0, 0, 0, 0.2);
53
+ -webkit-box-shadow: inset 10px -2px 35px -5px rgba(0, 0, 0, 0.3), inset 0 -8px 5px -5px rgba(0, 0, 0, 0.2);
54
+ box-shadow: inset 10px -2px 35px -5px rgba(0, 0, 0, 0.3), inset 0 -8px 5px -5px rgba(0, 0, 0, 0.2);
55
+ z-index: 3;
56
+ }
57
+ .olaf .head .top {
58
+ height: 44px;
59
+ width: 53px;
60
+ top: -41px;
61
+ left: calc(50% - (53px / 2));
62
+ background: #FFFFFF;
63
+ -moz-border-radius: 45% 45% 1% 1%/40% 40% 1% 1%;
64
+ -webkit-border-radius: 45%;
65
+ border-radius: 45% 45% 1% 1%/40% 40% 1% 1%;
66
+ -moz-box-shadow: inset 15px 0px 10px -5px rgba(0, 0, 0, 0.1);
67
+ -webkit-box-shadow: inset 15px 0px 10px -5px rgba(0, 0, 0, 0.1);
68
+ box-shadow: inset 15px 0px 10px -5px rgba(0, 0, 0, 0.1);
69
+ }
70
+ .olaf .head .top:before, .olaf .head .top:after {
71
+ top: 16px;
72
+ height: 20px;
73
+ width: 34px;
74
+ border-top: 10px solid #FFFFFF;
75
+ z-index: 2;
76
+ }
77
+ .olaf .head .top:before {
78
+ border-top-color: #e0e0e0;
79
+ -moz-border-radius: 0 50% 0 0;
80
+ -webkit-border-radius: 0;
81
+ border-radius: 0 50% 0 0;
82
+ left: -28px;
83
+ -moz-transform: rotate(110deg);
84
+ -ms-transform: rotate(110deg);
85
+ -webkit-transform: rotate(110deg);
86
+ transform: rotate(110deg);
87
+ }
88
+ .olaf .head .top:after {
89
+ -moz-border-radius: 50% 0 0 0;
90
+ -webkit-border-radius: 50%;
91
+ border-radius: 50% 0 0 0;
92
+ right: -28px;
93
+ -moz-transform: rotate(-110deg);
94
+ -ms-transform: rotate(-110deg);
95
+ -webkit-transform: rotate(-110deg);
96
+ transform: rotate(-110deg);
97
+ }
98
+ .olaf .head .top .shadow {
99
+ left: calc(52% - 58%);
100
+ top: 38px;
101
+ height: 30%;
102
+ width: 116%;
103
+ -moz-box-shadow: inset 0 -2px 8px -4px rgba(0, 0, 0, 0.2);
104
+ -webkit-box-shadow: inset 0 -2px 8px -4px rgba(0, 0, 0, 0.2);
105
+ box-shadow: inset 0 -2px 8px -4px rgba(0, 0, 0, 0.2);
106
+ -moz-border-radius: 1% 1% 45% 45%/1% 1% 40% 40%;
107
+ -webkit-border-radius: 1%;
108
+ border-radius: 1% 1% 45% 45%/1% 1% 40% 40%;
109
+ z-index: 3;
110
+ }
111
+ .olaf .head .hair {
112
+ top: -35px;
113
+ left: 38px;
114
+ z-index: -1;
115
+ }
116
+ .olaf .head .hair span {
117
+ bottom: 0;
118
+ height: 32px;
119
+ width: 10px;
120
+ border-right: 2px solid #533F38;
121
+ }
122
+ .olaf .head .hair > span:nth-of-type(1) {
123
+ height: 27px;
124
+ left: -5px;
125
+ -moz-transform: rotate(-10deg);
126
+ -ms-transform: rotate(-10deg);
127
+ -webkit-transform: rotate(-10deg);
128
+ transform: rotate(-10deg);
129
+ -moz-border-radius: 10%;
130
+ -webkit-border-radius: 10%;
131
+ border-radius: 10%;
132
+ }
133
+ .olaf .head .hair > span:nth-of-type(1) > span:nth-of-type(1) {
134
+ left: 0px;
135
+ height: 22px;
136
+ bottom: 23px;
137
+ -moz-transform: rotate(-5deg);
138
+ -ms-transform: rotate(-5deg);
139
+ -webkit-transform: rotate(-5deg);
140
+ transform: rotate(-5deg);
141
+ -moz-border-radius: 30%;
142
+ -webkit-border-radius: 30%;
143
+ border-radius: 30%;
144
+ }
145
+ .olaf .head .hair > span:nth-of-type(1) > span:nth-of-type(2) {
146
+ left: -4px;
147
+ bottom: 18px;
148
+ height: 22px;
149
+ -moz-transform: rotate(-40deg);
150
+ -ms-transform: rotate(-40deg);
151
+ -webkit-transform: rotate(-40deg);
152
+ transform: rotate(-40deg);
153
+ -moz-border-radius: 30%;
154
+ -webkit-border-radius: 30%;
155
+ border-radius: 30%;
156
+ }
157
+ .olaf .head .hair > span:nth-of-type(1) > span:nth-of-type(2) span {
158
+ left: -3px;
159
+ bottom: 17px;
160
+ height: 16px;
161
+ -moz-transform: rotate(-35deg);
162
+ -ms-transform: rotate(-35deg);
163
+ -webkit-transform: rotate(-35deg);
164
+ transform: rotate(-35deg);
165
+ -moz-border-radius: 30%;
166
+ -webkit-border-radius: 30%;
167
+ border-radius: 30%;
168
+ }
169
+ .olaf .head .hair > span:nth-of-type(2) {
170
+ -moz-transform: rotate(-2deg);
171
+ -ms-transform: rotate(-2deg);
172
+ -webkit-transform: rotate(-2deg);
173
+ transform: rotate(-2deg);
174
+ -moz-border-radius: 10%;
175
+ -webkit-border-radius: 10%;
176
+ border-radius: 10%;
177
+ }
178
+ .olaf .head .hair > span:nth-of-type(2) span {
179
+ left: -2px;
180
+ height: 27px;
181
+ bottom: 30px;
182
+ -moz-transform: rotate(-10deg);
183
+ -ms-transform: rotate(-10deg);
184
+ -webkit-transform: rotate(-10deg);
185
+ transform: rotate(-10deg);
186
+ -moz-border-radius: 30%;
187
+ -webkit-border-radius: 30%;
188
+ border-radius: 30%;
189
+ }
190
+ .olaf .head .hair > span:nth-of-type(2) span span {
191
+ left: -4px;
192
+ bottom: 22px;
193
+ -moz-transform: rotate(-20deg);
194
+ -ms-transform: rotate(-20deg);
195
+ -webkit-transform: rotate(-20deg);
196
+ transform: rotate(-20deg);
197
+ }
198
+ .olaf .head .hair > span:nth-of-type(3) {
199
+ border-right: none;
200
+ border-left: 2px solid #533F38;
201
+ height: 30px;
202
+ left: 14px;
203
+ -moz-transform: rotate(5deg);
204
+ -ms-transform: rotate(5deg);
205
+ -webkit-transform: rotate(5deg);
206
+ transform: rotate(5deg);
207
+ -moz-border-radius: 10%;
208
+ -webkit-border-radius: 10%;
209
+ border-radius: 10%;
210
+ }
211
+ .olaf .head .hair > span:nth-of-type(3) span {
212
+ left: 1px;
213
+ height: 24px;
214
+ bottom: 25px;
215
+ border-right: none;
216
+ border-left: 2px solid #533F38;
217
+ -moz-transform: rotate(15deg);
218
+ -ms-transform: rotate(15deg);
219
+ -webkit-transform: rotate(15deg);
220
+ transform: rotate(15deg);
221
+ -moz-border-radius: 30%;
222
+ -webkit-border-radius: 30%;
223
+ border-radius: 30%;
224
+ }
225
+ .olaf .head .hair > span:nth-of-type(3) span span:nth-of-type(1) {
226
+ left: -3px;
227
+ height: 14px;
228
+ bottom: 17px;
229
+ -moz-transform: rotate(-10deg);
230
+ -ms-transform: rotate(-10deg);
231
+ -webkit-transform: rotate(-10deg);
232
+ transform: rotate(-10deg);
233
+ }
234
+ .olaf .head .hair > span:nth-of-type(3) span span:nth-of-type(2) {
235
+ left: 3px;
236
+ bottom: 17px;
237
+ -moz-transform: rotate(25deg);
238
+ -ms-transform: rotate(25deg);
239
+ -webkit-transform: rotate(25deg);
240
+ transform: rotate(25deg);
241
+ }
242
+ .olaf .head .brow {
243
+ top: -36px;
244
+ height: 5px;
245
+ width: 20px;
246
+ background: #413121;
247
+ }
248
+ .olaf .head .brow.left {
249
+ left: 26px;
250
+ -moz-transform: rotate(-13deg);
251
+ -ms-transform: rotate(-13deg);
252
+ -webkit-transform: rotate(-13deg);
253
+ transform: rotate(-13deg);
254
+ }
255
+ .olaf .head .brow.right {
256
+ right: 26px;
257
+ -moz-transform: rotate(13deg);
258
+ -ms-transform: rotate(13deg);
259
+ -webkit-transform: rotate(13deg);
260
+ transform: rotate(13deg);
261
+ }
262
+ .olaf .head .brow.left {
263
+ left: 27px;
264
+ -moz-border-radius: 40% 1% 10% 5%/70% 1% 20% 20%;
265
+ -webkit-border-radius: 40%;
266
+ border-radius: 40% 1% 10% 5%/70% 1% 20% 20%;
267
+ }
268
+ .olaf .head .brow.left:before {
269
+ left: -5px;
270
+ -moz-border-radius: 90% 0 0 0/99% 0 0 0;
271
+ -webkit-border-radius: 90%;
272
+ border-radius: 90% 0 0 0/99% 0 0 0;
273
+ -moz-box-shadow: -1px -4px 0 0 #413121;
274
+ -webkit-box-shadow: -1px -4px 0 0 #413121;
275
+ box-shadow: -1px -4px 0 0 #413121;
276
+ -moz-transform: skewX(-10deg);
277
+ -ms-transform: skewX(-10deg);
278
+ -webkit-transform: skewX(-10deg);
279
+ transform: skewX(-10deg);
280
+ }
281
+ .olaf .head .brow.right {
282
+ right: 25px;
283
+ -moz-border-radius: 1% 40% 5% 10%/1% 70% 20% 20%;
284
+ -webkit-border-radius: 1%;
285
+ border-radius: 1% 40% 5% 10%/1% 70% 20% 20%;
286
+ }
287
+ .olaf .head .brow.right:before {
288
+ right: -5px;
289
+ -moz-border-radius: 0 90% 0 0/0 99% 0 0;
290
+ -webkit-border-radius: 0;
291
+ border-radius: 0 90% 0 0/0 99% 0 0;
292
+ -moz-box-shadow: 1px -4px 0 0 #413121;
293
+ -webkit-box-shadow: 1px -4px 0 0 #413121;
294
+ box-shadow: 1px -4px 0 0 #413121;
295
+ -moz-transform: skewX(10deg);
296
+ -ms-transform: skewX(10deg);
297
+ -webkit-transform: skewX(10deg);
298
+ transform: skewX(10deg);
299
+ }
300
+ .olaf .head .brow:before {
301
+ top: 4px;
302
+ height: 12px;
303
+ width: 15px;
304
+ }
305
+ .olaf .head .eye {
306
+ top: -18px;
307
+ height: 24px;
308
+ width: 20px;
309
+ z-index: 5;
310
+ background: #FFFFFF;
311
+ -moz-box-shadow: 0 -1px 0px 1px #010100, 0 1px 1px 1px rgba(75, 120, 134, 0.8), 0 -3px 0px 2px rgba(36, 82, 94, 0.8), inset 0 -15px 10px -5px rgba(0, 0, 0, 0.2);
312
+ -webkit-box-shadow: 0 -1px 0px 1px #010100, 0 1px 1px 1px rgba(75, 120, 134, 0.8), 0 -3px 0px 2px rgba(36, 82, 94, 0.8), inset 0 -15px 10px -5px rgba(0, 0, 0, 0.2);
313
+ box-shadow: 0 -1px 0px 1px #010100, 0 1px 1px 1px rgba(75, 120, 134, 0.8), 0 -3px 0px 2px rgba(36, 82, 94, 0.8), inset 0 -15px 10px -5px rgba(0, 0, 0, 0.2);
314
+ -moz-border-radius: 50%;
315
+ -webkit-border-radius: 50%;
316
+ border-radius: 50%;
317
+ }
318
+ .olaf .head .eye.left {
319
+ left: 28px;
320
+ }
321
+ .olaf .head .eye.left .pupil {
322
+ left: 30%;
323
+ }
324
+ .olaf .head .eye.right {
325
+ right: 24px;
326
+ }
327
+ .olaf .head .eye.right .pupil {
328
+ right: 30%;
329
+ }
330
+ .olaf .head .eye .pupil {
331
+ top: 34%;
332
+ height: 44%;
333
+ width: 52%;
334
+ background: #000000;
335
+ -moz-border-radius: 50%;
336
+ -webkit-border-radius: 50%;
337
+ border-radius: 50%;
338
+ }
339
+ .olaf .head .nose {
340
+ top: 0px;
341
+ left: 42px;
342
+ height: 23px;
343
+ width: 28px;
344
+ background: #EC622A;
345
+ overflow: hidden;
346
+ -moz-border-radius: 40% 60% 40% 30%/70% 60% 40% 30%;
347
+ -webkit-border-radius: 40%;
348
+ border-radius: 40% 60% 40% 30%/70% 60% 40% 30%;
349
+ -moz-box-shadow: inset 8px -5px 5px 0 rgba(0, 0, 0, 0.3);
350
+ -webkit-box-shadow: inset 8px -5px 5px 0 rgba(0, 0, 0, 0.3);
351
+ box-shadow: inset 8px -5px 5px 0 rgba(0, 0, 0, 0.3);
352
+ z-index: 6;
353
+ }
354
+ .olaf .head .nose:before {
355
+ top: -5px;
356
+ right: 0px;
357
+ height: 110%;
358
+ width: 60%;
359
+ *zoom: 1;
360
+ filter: progid:DXImageTransform.Microsoft.gradient(gradientType=1, startColorstr='#FFFFFFFF', endColorstr='#FFFFFFFF');
361
+ background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PHJhZGlhbEdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgY3g9IjUwJSIgY3k9IjcwJSIgcj0iOTAlIj48c3RvcCBvZmZzZXQ9IjAlIiBzdG9wLWNvbG9yPSIjZmZmZmZmIiBzdG9wLW9wYWNpdHk9IjAuNSIvPjxzdG9wIG9mZnNldD0iOTAlIiBzdG9wLWNvbG9yPSIjZmZmZmZmIiBzdG9wLW9wYWNpdHk9IjAuMCIvPjwvcmFkaWFsR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');
362
+ background-size: 100%;
363
+ background-image: -moz-radial-gradient(50% 70%, ellipse cover, rgba(255, 255, 255, 0.5) 0%, rgba(255, 255, 255, 0) 90%);
364
+ background-image: -webkit-radial-gradient(50% 70%, ellipse cover, rgba(255, 255, 255, 0.5) 0%, rgba(255, 255, 255, 0) 90%);
365
+ background-image: radial-gradient(ellipse cover at 50% 70%, rgba(255, 255, 255, 0.5) 0%, rgba(255, 255, 255, 0) 90%);
366
+ -moz-transform: rotate(-30deg);
367
+ -ms-transform: rotate(-30deg);
368
+ -webkit-transform: rotate(-30deg);
369
+ transform: rotate(-30deg);
370
+ }
371
+ .olaf .head .mouth {
372
+ top: 14px;
373
+ left: calc(50% - (68px / 2) + 2px);
374
+ height: 76px;
375
+ width: 68px;
376
+ -moz-border-radius: 25% 25% 50% 50%/5% 5% 95% 95%;
377
+ -webkit-border-radius: 25%;
378
+ border-radius: 25% 25% 50% 50%/5% 5% 95% 95%;
379
+ background: #234148;
380
+ z-index: 2;
381
+ }
382
+ .olaf .head .top-lip {
383
+ top: 10px;
384
+ left: calc(50% - (82px / 2) + 2px);
385
+ width: 82px;
386
+ height: 35px;
387
+ background: #FFFFFF;
388
+ -moz-box-shadow: -2px 5px 10px -1px rgba(0, 0, 0, 0.2), inset 10px 0px 15px -5px rgba(0, 0, 0, 0.2);
389
+ -webkit-box-shadow: -2px 5px 10px -1px rgba(0, 0, 0, 0.2), inset 10px 0px 15px -5px rgba(0, 0, 0, 0.2);
390
+ box-shadow: -2px 5px 10px -1px rgba(0, 0, 0, 0.2), inset 10px 0px 15px -5px rgba(0, 0, 0, 0.2);
391
+ -moz-border-radius: 20% 20% 40% 60%/10% 20% 70% 90%;
392
+ -webkit-border-radius: 20%;
393
+ border-radius: 20% 20% 40% 60%/10% 20% 70% 90%;
394
+ z-index: 4;
395
+ }
396
+ .olaf .head .tooth {
397
+ left: 40%;
398
+ top: 40px;
399
+ width: 35px;
400
+ height: 16px;
401
+ background: #FFFFFF;
402
+ -moz-border-radius: 1% 1% 40% 50%/1% 1% 20% 20%;
403
+ -webkit-border-radius: 1%;
404
+ border-radius: 1% 1% 40% 50%/1% 1% 20% 20%;
405
+ z-index: 3;
406
+ }
407
+ .olaf .head .bottom-lip {
408
+ top: 12px;
409
+ left: calc(50% - (82px / 2) + 2px);
410
+ height: 84px;
411
+ width: 82px;
412
+ -moz-border-radius: 25% 25% 50% 50%/5% 5% 95% 95%;
413
+ -webkit-border-radius: 25%;
414
+ border-radius: 25% 25% 50% 50%/5% 5% 95% 95%;
415
+ -moz-box-shadow: 0 5px 10px -4px rgba(0, 0, 0, 0.3), inset 2px 0px 10px -5px rgba(0, 0, 0, 0.2);
416
+ -webkit-box-shadow: 0 5px 10px -4px rgba(0, 0, 0, 0.3), inset 2px 0px 10px -5px rgba(0, 0, 0, 0.2);
417
+ box-shadow: 0 5px 10px -4px rgba(0, 0, 0, 0.3), inset 2px 0px 10px -5px rgba(0, 0, 0, 0.2);
418
+ z-index: 1;
419
+ }
420
+ .olaf .body {
421
+ background: #FFFFFF;
422
+ -moz-border-radius: 35% 35% 30% 40%/60% 60% 40% 40%;
423
+ -webkit-border-radius: 35%;
424
+ border-radius: 35% 35% 30% 40%/60% 60% 40% 40%;
425
+ -moz-box-shadow: inset 2px 5px 10px -6px rgba(0, 0, 0, 0.2), inset 20px 5px 30px -6px rgba(0, 0, 0, 0.2), inset 0 -5px 15px -2px rgba(0, 0, 0, 0.2);
426
+ -webkit-box-shadow: inset 2px 5px 10px -6px rgba(0, 0, 0, 0.2), inset 20px 5px 30px -6px rgba(0, 0, 0, 0.2), inset 0 -5px 15px -2px rgba(0, 0, 0, 0.2);
427
+ box-shadow: inset 2px 5px 10px -6px rgba(0, 0, 0, 0.2), inset 20px 5px 30px -6px rgba(0, 0, 0, 0.2), inset 0 -5px 15px -2px rgba(0, 0, 0, 0.2);
428
+ top: 0;
429
+ left: calc(50% - (120px / 2));
430
+ }
431
+ .olaf .body.top {
432
+ left: calc(50% - (80px /2));
433
+ height: 60px;
434
+ width: 80px;
435
+ z-index: 2;
436
+ overflow: hidden;
437
+ }
438
+ .olaf .body.top:before {
439
+ height: 10px;
440
+ width: 50%;
441
+ left: 20%;
442
+ *zoom: 1;
443
+ filter: progid:DXImageTransform.Microsoft.gradient(gradientType=1, startColorstr='#FF000000', endColorstr='#FF000000');
444
+ background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PHJhZGlhbEdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgY3g9IjUwJSIgY3k9IiIgcj0iODAlIj48c3RvcCBvZmZzZXQ9IjAlIiBzdG9wLWNvbG9yPSIjMDAwMDAwIiBzdG9wLW9wYWNpdHk9IjAuMyIvPjxzdG9wIG9mZnNldD0iODAlIiBzdG9wLWNvbG9yPSIjMDAwMDAwIiBzdG9wLW9wYWNpdHk9IjAuMCIvPjwvcmFkaWFsR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');
445
+ background-size: 100%;
446
+ background-image: -moz-radial-gradient(center, ellipse cover, rgba(0, 0, 0, 0.3) 0%, rgba(0, 0, 0, 0) 80%);
447
+ background-image: -webkit-radial-gradient(center, ellipse cover, rgba(0, 0, 0, 0.3) 0%, rgba(0, 0, 0, 0) 80%);
448
+ background-image: radial-gradient(ellipse cover at center, rgba(0, 0, 0, 0.3) 0%, rgba(0, 0, 0, 0) 80%);
449
+ }
450
+ .olaf .body.bottom {
451
+ top: 50px;
452
+ height: 90px;
453
+ width: 120px;
454
+ z-index: 1;
455
+ }
456
+ .olaf .body .button {
457
+ height: 22px;
458
+ width: 26px;
459
+ top: 20px;
460
+ left: calc(50% - (26px) / 2);
461
+ background: #222222;
462
+ -moz-border-radius: 45% 55% 40% 50%/60% 55% 45% 40%;
463
+ -webkit-border-radius: 45%;
464
+ border-radius: 45% 55% 40% 50%/60% 55% 45% 40%;
465
+ }
466
+ .olaf .body .button ~ .button {
467
+ top: 55px;
468
+ }
469
+ .olaf .body .button:before {
470
+ right: 8px;
471
+ bottom: 7px;
472
+ height: 0;
473
+ width: 10%;
474
+ -moz-box-shadow: 0 0 8px 2px rgba(255, 255, 255, 0.4);
475
+ -webkit-box-shadow: 0 0 8px 2px rgba(255, 255, 255, 0.4);
476
+ box-shadow: 0 0 8px 2px rgba(255, 255, 255, 0.4);
477
+ }
478
+ .olaf .arm {
479
+ top: 20px;
480
+ width: 40px;
481
+ height: 10px;
482
+ }
483
+ .olaf .arm.left {
484
+ left: -17px;
485
+ -moz-transform-origin: top right;
486
+ -ms-transform-origin: top right;
487
+ -webkit-transform-origin: top right;
488
+ transform-origin: top right;
489
+ -moz-transform: rotate(40deg);
490
+ -ms-transform: rotate(40deg);
491
+ -webkit-transform: rotate(40deg);
492
+ transform: rotate(40deg);
493
+ }
494
+ .olaf .arm.left .lower-arm {
495
+ left: -40px;
496
+ }
497
+ .olaf .arm.left .upper-arm span, .olaf .arm.left .lower-arm span {
498
+ right: -2px;
499
+ }
500
+ .olaf .arm.left .hand {
501
+ left: 0px;
502
+ }
503
+ .olaf .arm.left .hand .fingers {
504
+ left: -4px;
505
+ }
506
+ .olaf .arm.left .hand .fingers span {
507
+ -moz-transform-origin: right top;
508
+ -ms-transform-origin: right top;
509
+ -webkit-transform-origin: right top;
510
+ transform-origin: right top;
511
+ }
512
+ .olaf .arm.left .hand .fingers span:nth-of-type(1) {
513
+ right: -7px;
514
+ -moz-transform: rotate(45deg);
515
+ -ms-transform: rotate(45deg);
516
+ -webkit-transform: rotate(45deg);
517
+ transform: rotate(45deg);
518
+ }
519
+ .olaf .arm.right {
520
+ right: -17px;
521
+ -moz-transform-origin: top left;
522
+ -ms-transform-origin: top left;
523
+ -webkit-transform-origin: top left;
524
+ transform-origin: top left;
525
+ -moz-transform: rotate(-40deg);
526
+ -ms-transform: rotate(-40deg);
527
+ -webkit-transform: rotate(-40deg);
528
+ transform: rotate(-40deg);
529
+ }
530
+ .olaf .arm.right .lower-arm {
531
+ right: -40px;
532
+ }
533
+ .olaf .arm.right .upper-arm span, .olaf .arm.right .lower-arm span {
534
+ left: -2px;
535
+ }
536
+ .olaf .arm.right .hand {
537
+ right: 0px;
538
+ }
539
+ .olaf .arm.right .hand .fingers {
540
+ right: -4px;
541
+ }
542
+ .olaf .arm.right .hand .fingers span {
543
+ -moz-transform-origin: left top;
544
+ -ms-transform-origin: left top;
545
+ -webkit-transform-origin: left top;
546
+ transform-origin: left top;
547
+ }
548
+ .olaf .arm.right .hand .fingers span:nth-of-type(1) {
549
+ left: -7px;
550
+ -moz-transform: rotate(-45deg);
551
+ -ms-transform: rotate(-45deg);
552
+ -webkit-transform: rotate(-45deg);
553
+ transform: rotate(-45deg);
554
+ }
555
+ .olaf .arm .lower-arm {
556
+ width: 40px;
557
+ height: 3px;
558
+ background: #533F38;
559
+ top: 0px;
560
+ }
561
+ .olaf .arm .lower-arm > span {
562
+ top: -1px;
563
+ height: 5px;
564
+ width: 7px;
565
+ background: #533F38;
566
+ -moz-border-radius: 50%;
567
+ -webkit-border-radius: 50%;
568
+ border-radius: 50%;
569
+ }
570
+ .olaf .arm .upper-arm {
571
+ width: 40px;
572
+ height: 3px;
573
+ background: #533F38;
574
+ top: -3px;
575
+ }
576
+ .olaf .arm .upper-arm > span {
577
+ top: -2px;
578
+ height: 7px;
579
+ width: 10px;
580
+ background: #533F38;
581
+ -moz-border-radius: 50%;
582
+ -webkit-border-radius: 50%;
583
+ border-radius: 50%;
584
+ }
585
+ .olaf .arm .hand > span {
586
+ top: -2px;
587
+ height: 7px;
588
+ width: 10px;
589
+ background: #533F38;
590
+ -moz-border-radius: 50%;
591
+ -webkit-border-radius: 50%;
592
+ border-radius: 50%;
593
+ }
594
+ .olaf .arm .hand .fingers span {
595
+ width: 40px;
596
+ height: 3px;
597
+ background: #533F38;
598
+ width: 15px;
599
+ }
600
+ .olaf .arm .hand .fingers span:nth-of-type(1) {
601
+ width: 10px;
602
+ }
603
+ .olaf .arm .hand .fingers span:nth-of-type(2) {
604
+ -moz-transform: rotate(-30deg);
605
+ -ms-transform: rotate(-30deg);
606
+ -webkit-transform: rotate(-30deg);
607
+ transform: rotate(-30deg);
608
+ }
609
+ .olaf .arm .hand .fingers span:nth-of-type(4) {
610
+ -moz-transform: rotate(30deg);
611
+ -ms-transform: rotate(30deg);
612
+ -webkit-transform: rotate(30deg);
613
+ transform: rotate(30deg);
614
+ }
615
+ .olaf .leg.left {
616
+ left: 20px;
617
+ }
618
+ .olaf .leg.right {
619
+ right: 20px;
620
+ }
621
+ .olaf .foot {
622
+ background: #FFFFFF;
623
+ -moz-border-radius: 35% 35% 30% 40%/60% 60% 40% 40%;
624
+ -webkit-border-radius: 35%;
625
+ border-radius: 35% 35% 30% 40%/60% 60% 40% 40%;
626
+ -moz-box-shadow: inset 2px 5px 10px -6px rgba(0, 0, 0, 0.2), inset 20px 5px 30px -6px rgba(0, 0, 0, 0.2), inset 0 -5px 15px -2px rgba(0, 0, 0, 0.2);
627
+ -webkit-box-shadow: inset 2px 5px 10px -6px rgba(0, 0, 0, 0.2), inset 20px 5px 30px -6px rgba(0, 0, 0, 0.2), inset 0 -5px 15px -2px rgba(0, 0, 0, 0.2);
628
+ box-shadow: inset 2px 5px 10px -6px rgba(0, 0, 0, 0.2), inset 20px 5px 30px -6px rgba(0, 0, 0, 0.2), inset 0 -5px 15px -2px rgba(0, 0, 0, 0.2);
629
+ bottom: 0;
630
+ height: 32px;
631
+ width: 42.85714px;
632
+ overflow: hidden;
633
+ }
634
+ .olaf .foot.left {
635
+ left: 12px;
636
+ }
637
+ .olaf .foot.right {
638
+ right: 12px;
639
+ }
640
+ .olaf .foot.left:before {
641
+ top: -3px;
642
+ }
643
+ .olaf .foot:before {
644
+ height: 15px;
645
+ width: 100%;
646
+ left: -10%;
647
+ *zoom: 1;
648
+ filter: progid:DXImageTransform.Microsoft.gradient(gradientType=1, startColorstr='#FF000000', endColorstr='#FF000000');
649
+ background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PHJhZGlhbEdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgY3g9IjUwJSIgY3k9IiIgcj0iODAlIj48c3RvcCBvZmZzZXQ9IjAlIiBzdG9wLWNvbG9yPSIjMDAwMDAwIiBzdG9wLW9wYWNpdHk9IjAuMyIvPjxzdG9wIG9mZnNldD0iODAlIiBzdG9wLWNvbG9yPSIjMDAwMDAwIiBzdG9wLW9wYWNpdHk9IjAuMCIvPjwvcmFkaWFsR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');
650
+ background-size: 100%;
651
+ background-image: -moz-radial-gradient(center, ellipse cover, rgba(0, 0, 0, 0.3) 0%, rgba(0, 0, 0, 0) 80%);
652
+ background-image: -webkit-radial-gradient(center, ellipse cover, rgba(0, 0, 0, 0.3) 0%, rgba(0, 0, 0, 0) 80%);
653
+ background-image: radial-gradient(ellipse cover at center, rgba(0, 0, 0, 0.3) 0%, rgba(0, 0, 0, 0) 80%);
654
+ }
655
+ .olaf > .shadow {
656
+ bottom: 0;
657
+ left: 50%;
658
+ height: 20px;
659
+ z-index: -1;
660
+ width: 0;
661
+ -moz-box-shadow: 0 -27px 40px 30px rgba(0, 0, 0, 0.4);
662
+ -webkit-box-shadow: 0 -27px 40px 30px rgba(0, 0, 0, 0.4);
663
+ box-shadow: 0 -27px 40px 30px rgba(0, 0, 0, 0.4);
664
+ -moz-transform: skewX(65deg);
665
+ -ms-transform: skewX(65deg);
666
+ -webkit-transform: skewX(65deg);
667
+ transform: skewX(65deg);
668
+ }
669
+
670
+ .logo {
671
+ position: fixed;
672
+ bottom: 15px;
673
+ left: 15px;
674
+ }
675
+ .logo img {
676
+ margin: -15px -10px;
677
+ }
678
+ .logo h1, .logo h2 {
679
+ font-family: "helvetica neue", helvetica, arial, sans-serif;
680
+ margin: 0;
681
+ font-size: 26px;
682
+ letter-spacing: 1px;
683
+ color: #FFFFFF;
684
+ font-weight: 100;
685
+ }
admin/img/Litespeed.icon.svg ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
3
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
4
+ <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
5
+ viewBox="0 0 300 300" enable-background="new 0 0 300 300" xml:space="preserve">
6
+ <g>
7
+ <path fill="#5E8CDA" d="M254.859,146.258l-68.508-68.516l-29.203,37.055l31.461,31.461c2.922,2.922,2.922,7.68,0,10.57
8
+ l-9.086,9.086c0,0,6.148,9.195,6.414,9.75c1.422,2.836,1.742,9.492-2.273,12.547l-71.57,54.969c0,18.422-0.016,56.336,0,56.344
9
+ c0.031,0,142.766-142.695,142.766-142.695C257.75,153.898,257.75,149.18,254.859,146.258z"/>
10
+ <path fill="#093071" d="M95.703,154.891c-2.898-2.875-2.898-7.641,0-10.531l9.109-9.125l-6.219-8.938
11
+ c-2.977-4.219-2.039-10.203,2.055-13.344l71.602-54.938l0.023-56.328l-0.023-0.031l-0.039-0.047L29.477,144.359
12
+ c-2.922,2.891-2.922,7.656,0,10.539l68.5,68.508l29.219-37.055L95.703,154.891z"/>
13
+ </g>
14
+ <path fill="#5E8CDA" d="M208.297,35.727c1.092,0,2.147,0.654,2.624,1.624c0.804,1.658-0.217,3.189-1.236,4.495l-0.04,0.051
15
+ l-62.727,79.64c-0.829,1.05-0.891,3.144-0.132,4.218c0.339,0.491,33.879,49.111,35.027,50.794c1.342,1.918,1.425,7.623-1.657,9.978
16
+ L79.348,263.915c-1.305,0.993-2.252,1.535-3.492,1.546c-0.99-0.082-2.015-0.756-2.44-1.601c-0.783-1.612,0.143-3.176,1.253-4.616
17
+ l62.727-79.607c0.83-1.114,0.908-3.081,0.152-4.231l-35.019-50.348c-2.308-3.283-1.585-7.943,1.611-10.39l100.851-77.445
18
+ C206.396,36.146,207.321,35.727,208.297,35.727 M208.297,34.727c-1.211,0-2.336,0.492-3.914,1.703l-100.852,77.445
19
+ c-3.625,2.773-4.445,8.023-1.82,11.758l35.016,50.344c0.508,0.773,0.438,2.297-0.133,3.063l-62.711,79.586
20
+ c-0.813,1.055-2.523,3.289-1.367,5.672c0.594,1.18,1.945,2.07,3.305,2.164c1.555,0,2.695-0.656,4.133-1.75l100.813-77.391
21
+ c3.508-2.68,3.523-8.977,1.867-11.344c-1.156-1.695-35.023-50.789-35.023-50.789c-0.508-0.719-0.461-2.328,0.094-3.031
22
+ l62.727-79.641c0.805-1.031,2.555-3.203,1.391-5.602C211.172,35.594,209.766,34.727,208.297,34.727L208.297,34.727z"/>
23
+ <path fill="#F5CD21" d="M178.992,176.898c0.82,1.25,1.563,5.867-0.477,7.422L77.641,261.75c-0.836,0.664-1.391,0.984-1.617,0.961
24
+ c-0.359,0.023-0.102-0.586,0.82-1.797l62.688-79.555c1.586-2.039,1.688-5.414,0.227-7.516l-34.977-50.367
25
+ C104.781,123.477,178.188,175.664,178.992,176.898z"/>
26
+ <path fill="#FDDD75" d="M178.992,176.898l-34.461-49.555c-1.438-2.125-1.336-5.492,0.242-7.508l62.695-79.578
27
+ c0.945-1.203,1.164-1.781,0.828-1.781c-0.227,0-0.805,0.281-1.625,0.945l-100.875,77.422c-2.016,1.555-2.477,4.547-1.016,6.633
28
+ L178.992,176.898z"/>
29
+ </svg>
30
+
admin/js/litespeed-cache-admin.js ADDED
@@ -0,0 +1,359 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ var _litespeed_meta ;
2
+ var _litespeed_shell_interval = 3 ;// seconds
3
+ var _litespeed_shell_interval_range = [3, 60] ;
4
+ var _litespeed_shell_handle ;
5
+ var _litespeed_shell_display_handle ;
6
+ var _litespeed_crawler_url ;
7
+ var _litespeed_dots ;
8
+
9
+ (function ($) {
10
+ 'use strict' ;
11
+
12
+ /**
13
+ * All of the code for your public-facing JavaScript source
14
+ * should reside in this file.
15
+ *
16
+ * Note: It has been assumed you will write jQuery code here, so the
17
+ * $ function reference has been prepared for usage within the scope
18
+ * of this function.
19
+ *
20
+ * This enables you to define handlers, for when the DOM is ready:
21
+ *
22
+ * $(function() {
23
+ *
24
+ * }) ;
25
+ *
26
+ * When the window is loaded:
27
+ *
28
+ * $( window ).load(function() {
29
+ *
30
+ * }) ;
31
+ *
32
+ * ...and/or other possibilities.
33
+ *
34
+ * Ideally, it is not considered best practise to attach more than a
35
+ * single DOM-ready or window-load handler for a particular page.
36
+ * Although scripts in the WordPress core, Plugins and Themes may be
37
+ * practising this, we should strive to set a better example in our own work.
38
+ */
39
+
40
+ jQuery(document).ready(function () {
41
+ /************** Common LiteSpeed JS **************/
42
+ // Arrow transform
43
+ $('.litespeed-down, .litespeed-up').click(function(event) {
44
+ $(this).toggleClass('litespeed-up litespeed-down') ;
45
+ }) ;
46
+
47
+ // Link confirm
48
+ $('[data-litespeed-cfm]').click(function(event) {
49
+ if(confirm($.trim($(this).data('litespeed-cfm')).replace(/\\n/g,"\n"))) {
50
+ return true ;
51
+ }
52
+ event.preventDefault() ;
53
+ event.stopImmediatePropagation() ;
54
+ return false ;
55
+ }) ;
56
+
57
+ /************** LSWCP JS ****************/
58
+ // FAQ show and hide
59
+ $('.litespeed-answer').hide() ;
60
+ $('.litespeed-question').click(function(event) {
61
+ $(this).next('.litespeed-answer').slideToggle('fast') ;
62
+ }) ;
63
+ $('[data-litespeed-expend-all]').click(function(event) {
64
+ var range = $(this).data('litespeed-expend-all') ;
65
+ if($(this).html() == '+'){
66
+ $(this).html('-') ;
67
+ $('[data-litespeed-layout="'+range+'"] .litespeed-answer').slideDown('fast') ;
68
+ $('[data-litespeed-layout="'+range+'"] .litespeed-question').addClass('litespeed-up').removeClass('litespeed-down') ;
69
+ }else{
70
+ $(this).html('+') ;
71
+ $('[data-litespeed-layout="'+range+'"] .litespeed-answer').slideUp('fast') ;
72
+ $('[data-litespeed-layout="'+range+'"] .litespeed-question').addClass('litespeed-down').removeClass('litespeed-up') ;
73
+ }
74
+ }) ;
75
+
76
+ // page tab switch functionality
77
+ if($('[data-litespeed-tab]').length > 0){
78
+ // display default tab
79
+ var litespeed_tab_current = document.cookie.replace(/(?:(?:^|.*;\s*)litespeed_tab\s*\=\s*([^;]*).*$)|^.*$/, "$1") ;
80
+ if(window.location.hash.substr(1)) {
81
+ litespeed_tab_current = window.location.hash.substr(1) ;
82
+ }
83
+ if(!litespeed_tab_current || !$('[data-litespeed-tab="'+litespeed_tab_current+'"]').length) {
84
+ litespeed_tab_current = $('[data-litespeed-tab]').first().data('litespeed-tab') ;
85
+ }
86
+ litespeed_display_tab(litespeed_tab_current) ;
87
+ // tab switch
88
+ $('[data-litespeed-tab]').click(function(event) {
89
+ litespeed_display_tab($(this).data('litespeed-tab')) ;
90
+ document.cookie = 'litespeed_tab='+$(this).data('litespeed-tab') ;
91
+ }) ;
92
+ }
93
+
94
+ // Manage page -> purge by
95
+ $('[name=purgeby]').change(function(event) {
96
+ $('[data-purgeby]').hide() ;
97
+ $('[data-purgeby='+this.value+']').show() ;
98
+ }) ;
99
+
100
+ // Select All and Copy to Clipboard
101
+ $("#litespeed_cache_report_copy").click(function() {
102
+ $('#litespeed-report').select() ;
103
+ document.execCommand('copy') ;
104
+ $('#copy_select_all_span').fadeIn('slow').delay(1000).fadeOut('slow') ;
105
+ }) ;
106
+
107
+ // Settings->General->Enable mobile view
108
+ $('#conf_mobileview_enabled_1').click(function() {
109
+ if($(this).is(':checked')){
110
+ if(!$('#litespeed-mobileview-rules').val()){
111
+ $('#litespeed-mobileview-rules').val($('#litespeed-mobileview-rules-default').val()) ;
112
+ }
113
+ $('#litespeed-mobileview-rules').prop('readonly', false) ;
114
+ }
115
+ }) ;
116
+ $('#conf_mobileview_enabled_0').click(function() {
117
+ if($(this).is(':checked')){
118
+ // $('#litespeed-mobileview-rules').val('') ;
119
+ $('#litespeed-mobileview-rules').prop('readonly', true) ;
120
+ }
121
+ }) ;
122
+
123
+ /*************** crawler ******************/
124
+ $('#litespeed-crawl-url-btn').click(function () {
125
+ if( ! $(this).data('url') ){
126
+ return false ;
127
+ }
128
+ $('.litespeed-shell').css('display','block') ;
129
+ _litespeed_dots = window.setInterval(_litespeed_loading_dots, 300) ;
130
+ _litespeed_crawler_url = $(this).data('url') ;
131
+ litespeed_fetch_meta() ;
132
+ $(this).hide() ;
133
+ }) ;
134
+
135
+ $('#litespeed_manual_trigger').click(function(event) {
136
+ $('#litespeed-loading-dot').before('<li>Manually Started</li>') ;
137
+ _litespeed_shell_interval = _litespeed_shell_interval_range[0] ;
138
+ litespeed_fetch_meta() ;
139
+ }) ;
140
+
141
+ $('#litespeed_crawler_cron_enable').click(function(event) {
142
+ var that = this ;
143
+ $.getJSON( $(that).data('url'), function(json){
144
+ $(that).prop('checked', json.enable) ;
145
+ } ) ;
146
+ }) ;
147
+
148
+ $('#litespeed_custom_sitemap').keyup(function(event) {
149
+ $('[data-litespeed-selfsitemap]').toggle(!$(this).val()) ;
150
+ }) ;
151
+
152
+ $('[data-litespeed-selfsitemap]').toggle(!$('#litespeed_custom_sitemap').val()) ;
153
+
154
+ /******************** Clear whm msg ********************/
155
+ $(document).on('click', '.lscwp-whm-notice .notice-dismiss', function () {
156
+ $.get(litespeed_data.ajax_url_dismiss_whm) ;
157
+ });
158
+ /******************** Clear rule conflict msg ********************/
159
+ $(document).on('click', '.lscwp-notice-ruleconflict .notice-dismiss', function () {
160
+ $.get(litespeed_data.ajax_url_dismiss_ruleconflict) ;
161
+ });
162
+ }) ;
163
+ })(jQuery) ;
164
+
165
+
166
+
167
+ function litespeed_display_tab(tab) {
168
+ // setting page -> display submit button
169
+ if ( jQuery('#litespeed-submit').length > 0 ){
170
+ jQuery('#litespeed-submit').toggle(tab != 'compatibilities') ;
171
+ }
172
+ jQuery('[data-litespeed-tab]').removeClass('nav-tab-active') ;
173
+ jQuery('[data-litespeed-tab="'+tab+'"]').addClass('nav-tab-active') ;
174
+ jQuery('[data-litespeed-layout]').hide() ;
175
+ jQuery('[data-litespeed-layout="'+tab+'"]').show() ;
176
+ }
177
+
178
+ function lscwpEsiEnabled(the_checkbox, esi_ids) {
179
+ var rdonly = the_checkbox.checked ? false : true;
180
+ var len = esi_ids.length;
181
+ for (var i = 0; i < len; i++) {
182
+ var node_id = 'saved_' + esi_ids[i].getAttribute('id');
183
+ var node_val = esi_ids[i].getAttribute('value');
184
+ var prev = document.getElementById(node_id);
185
+ if (rdonly === false) {
186
+ esi_ids[i].removeAttribute('disabled');
187
+ if (prev) {
188
+ esi_ids[i].removeChild(prev);
189
+ }
190
+ continue;
191
+ }
192
+ esi_ids[i].setAttribute('disabled', true);
193
+ if (prev !== null) {
194
+ if (esi_ids[i].checked) {
195
+ prev.setAttribute("value", node_val);
196
+ }
197
+ else {
198
+ esi_ids[i].removeChild(prev);
199
+ }
200
+ continue;
201
+ }
202
+ else if (esi_ids[i].checked === false) {
203
+ continue;
204
+ }
205
+ var hid = document.createElement("INPUT");
206
+ hid.setAttribute("type", "hidden");
207
+ hid.setAttribute("name", esi_ids[i].getAttribute('name'));
208
+ hid.setAttribute("value", node_val);
209
+ hid.setAttribute("id", node_id);
210
+ esi_ids[i].appendChild(hid);
211
+ }
212
+ }
213
+
214
+ // Append params to uri
215
+ function litespeed_append_param(uri, key, val) {
216
+ var re = new RegExp("([?&])" + key + "=.*?(&|$)", "i") ;
217
+ var separator = uri.indexOf('?') !== -1 ? "&" : "?" ;
218
+ if (uri.match(re)) {
219
+ return uri.replace(re, '$1' + key + "=" + val + '$2') ;
220
+ }
221
+ else {
222
+ return uri + separator + key + "=" + val ;
223
+ }
224
+ }
225
+
226
+ function litespeed_pulse() {
227
+ jQuery('#litespeed-shell-icon').animate({
228
+ width: 27, height: 34,
229
+ opacity: 1
230
+ }, 700, function() {
231
+ jQuery('#litespeed-shell-icon').animate({
232
+ width: 23, height: 29,
233
+ opacity: 0.5
234
+ }, 700) ;
235
+ }) ;
236
+ }
237
+
238
+ function litespeed_fetch_meta() {
239
+ window.clearTimeout(_litespeed_shell_handle) ;
240
+ jQuery('#litespeed-loading-dot').text('') ;
241
+ jQuery.ajaxSetup({ cache: false }) ;
242
+ jQuery.getJSON(_litespeed_crawler_url, function( meta ) {
243
+ litespeed_pulse() ;
244
+ var changed = false ;
245
+ if ( meta && 'list_size' in meta ) {
246
+ new_meta = meta.list_size + ' ' + meta.file_time + ' ' + meta.last_pos + ' ' + meta.last_count + ' ' + meta.last_start_time + ' ' + meta.is_running ;
247
+ if ( new_meta != _litespeed_meta ) {
248
+ _litespeed_meta = new_meta ;
249
+ changed = true ;
250
+ string = _litespeed_build_meta(meta);
251
+ jQuery('#litespeed-loading-dot').before(string) ;
252
+ // remove first log elements
253
+ log_length = jQuery('.litespeed-shell-body li').length;
254
+ if ( log_length > 50) {
255
+ jQuery('.litespeed-shell-body li:lt(' + (log_length - 50) + ')').remove();
256
+ }
257
+ // scroll to end
258
+ jQuery('.litespeed-shell-body').stop().animate({
259
+ scrollTop: jQuery('.litespeed-shell-body')[0].scrollHeight
260
+ }, 800) ;
261
+ }
262
+
263
+ // dynamic adjust the interval length
264
+ _litespeed_adjust_interval(changed) ;
265
+ }
266
+ // display interval counting
267
+ litespeed_display_interval_reset() ;
268
+ _litespeed_shell_handle = window.setTimeout(_litespeed_dynamic_timeout, _litespeed_shell_interval*1000) ;
269
+ }) ;
270
+ }
271
+
272
+ /**
273
+ * Dynamic adjust interval
274
+ */
275
+ function _litespeed_adjust_interval(changed) {
276
+ if ( changed ) {
277
+ _litespeed_shell_interval -= Math.ceil(_litespeed_shell_interval/2) ;
278
+ }
279
+ else{
280
+ _litespeed_shell_interval ++ ;
281
+ }
282
+
283
+ if(_litespeed_shell_interval < _litespeed_shell_interval_range[0]) {
284
+ _litespeed_shell_interval = _litespeed_shell_interval_range[0] ;
285
+ }
286
+ if(_litespeed_shell_interval > _litespeed_shell_interval_range[1]) {
287
+ _litespeed_shell_interval = _litespeed_shell_interval_range[1] ;
288
+ }
289
+ }
290
+
291
+ function _litespeed_build_meta(meta) {
292
+ var string = '<li>' + litespeed_date(meta.last_update_time) +
293
+ '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Size: ' + meta.list_size +
294
+ '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Position: ' + (meta.last_pos*1+1) +
295
+ '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Threads: ' + meta.last_count +
296
+ '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Status: '
297
+ ;
298
+ if ( meta.is_running ) {
299
+ string += 'crawling, ' + meta.last_status;
300
+ }
301
+ else{
302
+ string += meta.end_reason ? meta.end_reason : '-' ;
303
+ }
304
+ string += '</li>' ;
305
+ return string;
306
+ }
307
+
308
+ function _litespeed_dynamic_timeout() {
309
+ litespeed_fetch_meta() ;
310
+ }
311
+
312
+ function litespeed_display_interval_reset() {
313
+ window.clearInterval(_litespeed_shell_display_handle) ;
314
+ jQuery('.litespeed-shell-header-bar').data('num', _litespeed_shell_interval) ;
315
+ _litespeed_shell_display_handle = window.setInterval(_litespeed_display_interval, 1000) ;
316
+
317
+ jQuery('.litespeed-shell-header-bar').stop().animate({width: '100%'}, 500, function(){
318
+ jQuery('.litespeed-shell-header-bar').css('width', '0%') ;
319
+ }) ;
320
+ }
321
+
322
+ function _litespeed_display_interval() {
323
+ var num = jQuery('.litespeed-shell-header-bar').data('num') ;
324
+ jQuery('.litespeed-shell-header-bar').stop().animate({width: litespeed_get_percent(num, _litespeed_shell_interval) + '%'}, 1000) ;
325
+ if(num > 0) num-- ;
326
+ if(num < 0) num = 0 ;
327
+ jQuery('.litespeed-shell-header-bar').data('num', num) ;
328
+ }
329
+
330
+ function litespeed_get_percent(num1, num2){
331
+ num1 = num1 * 1;
332
+ num2 = num2 * 1;
333
+ num = (num2 - num1) / num2;
334
+ return num * 100;
335
+ }
336
+
337
+ function _litespeed_loading_dots() {
338
+ jQuery('#litespeed-loading-dot').append('.') ;
339
+ }
340
+
341
+ function litespeed_date(timestamp) {
342
+ var a = new Date(timestamp * 1000) ;
343
+ var months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'] ;
344
+ var year = a.getFullYear() ;
345
+ var month = months[a.getMonth()] ;
346
+ var date = litespeed_add_zero(a.getDate()) ;
347
+ var hour = litespeed_add_zero(a.getHours()) ;
348
+ var min = litespeed_add_zero(a.getMinutes()) ;
349
+ var sec = litespeed_add_zero(a.getSeconds()) ;
350
+ var time = date + ' ' + month + ' ' + year + ' ' + hour + ':' + min + ':' + sec ;
351
+ return time ;
352
+ }
353
+
354
+ function litespeed_add_zero(i) {
355
+ if (i < 10) {
356
+ i = "0" + i;
357
+ }
358
+ return i;
359
+ }
admin/litespeed-cache-admin-display.class.php ADDED
@@ -0,0 +1,863 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * The admin-panel specific functionality of the plugin.
5
+ *
6
+ *
7
+ * @since 1.0.0
8
+ * @package LiteSpeed_Cache
9
+ * @subpackage LiteSpeed_Cache/admin
10
+ * @author LiteSpeed Technologies <info@litespeedtech.com>
11
+ */
12
+ class LiteSpeed_Cache_Admin_Display
13
+ {
14
+ private static $_instance ;
15
+
16
+ const NOTICE_BLUE = 'notice notice-info' ;
17
+ const NOTICE_GREEN = 'notice notice-success' ;
18
+ const NOTICE_RED = 'notice notice-error' ;
19
+ const NOTICE_YELLOW = 'notice notice-warning' ;
20
+ const TRANSIENT_LITESPEED_MESSAGE = 'litespeed_messages' ;
21
+
22
+ const PURGEBY_CAT = '0' ;
23
+ const PURGEBY_PID = '1' ;
24
+ const PURGEBY_TAG = '2' ;
25
+ const PURGEBY_URL = '3' ;
26
+
27
+ const PURGEBYOPT_SELECT = 'purgeby' ;
28
+ const PURGEBYOPT_LIST = 'purgebylist' ;
29
+
30
+ const DISMISS_MSG = 'litespeed-cache-dismiss' ;
31
+ const RULECONFLICT_ON = 'ExpiresDefault_1' ;
32
+ const RULECONFLICT_DISMISSED = 'ExpiresDefault_0' ;
33
+
34
+ private $messages = array() ;
35
+ private $disable_all = false ;
36
+ private $default_settings = array() ;
37
+
38
+ /**
39
+ * Initialize the class and set its properties.
40
+ *
41
+ * @since 1.0.7
42
+ * @access private
43
+ */
44
+ private function __construct()
45
+ {
46
+ // load assets
47
+ if( ! empty($_GET['page']) &&
48
+ (substr($_GET['page'], 0, 8) == 'lscache-' || $_GET['page'] == 'litespeedcache') ) {
49
+ add_action('admin_enqueue_scripts', array($this, 'load_assets')) ;
50
+ }
51
+
52
+ // main css
53
+ add_action('admin_enqueue_scripts', array($this, 'enqueue_style')) ;
54
+ // Main js
55
+ add_action('admin_enqueue_scripts', array($this, 'enqueue_scripts')) ;
56
+
57
+ $is_network_admin = is_network_admin() ;
58
+
59
+ // Quick access menu
60
+ if ( is_multisite() && $is_network_admin ) {
61
+ $manage = 'manage_network_options' ;
62
+ }
63
+ else {
64
+ $manage = 'manage_options' ;
65
+ }
66
+ if ( current_user_can($manage) ) {
67
+ if ( LiteSpeed_Cache_Router::cache_enabled() ) {
68
+ add_action('wp_before_admin_bar_render', array($this, 'add_quick_purge')) ;
69
+ }
70
+ add_action('admin_enqueue_scripts', array($this, 'check_messages')) ;// We can do this cos admin_notices hook is after admin_enqueue_scripts hook in wp-admin/admin-header.php
71
+ }
72
+
73
+ // add menus
74
+ if ( $is_network_admin && is_plugin_active_for_network(LSWCP_BASENAME) ) {
75
+ add_action('network_admin_menu', array($this, 'register_admin_menu')) ;
76
+ }
77
+ else {
78
+ add_action('admin_menu', array($this, 'register_admin_menu')) ;
79
+ }
80
+
81
+ // get default setting values
82
+ $this->default_settings = LiteSpeed_Cache_Config::get_instance()->get_default_options() ;
83
+ }
84
+
85
+ /**
86
+ * Load LiteSpeed assets
87
+ *
88
+ * @since 1.1.0
89
+ * @access public
90
+ * @param array $hook WP hook
91
+ */
92
+ public function load_assets($hook)
93
+ {
94
+ // Admin footer
95
+ add_filter('admin_footer_text', array($this, 'admin_footer_text'), 1) ;
96
+
97
+ if( LiteSpeed_Cache_Router::cache_enabled() ) {
98
+ // Help tab
99
+ $this->add_help_tabs() ;
100
+
101
+ global $pagenow ;
102
+ if ( $pagenow === 'plugins.php' ) {//todo: check if work
103
+ add_action('wp_default_scripts', array($this, 'set_update_text'), 0) ;
104
+ add_action('wp_default_scripts', array($this, 'unset_update_text'), 20) ;
105
+ }
106
+ }
107
+ }
108
+
109
+ /**
110
+ * Output litespeed form info
111
+ *
112
+ * @since 1.1.0
113
+ * @access public
114
+ * @param string $action
115
+ */
116
+ public function form_action($action)
117
+ {
118
+ echo '<input type="hidden" name="' . LiteSpeed_Cache::ACTION_KEY . '" value="' . $action . '" />' ;
119
+ wp_nonce_field($action, LiteSpeed_Cache::NONCE_NAME) ;
120
+ }
121
+
122
+
123
+ /**
124
+ * Register the admin menu display.
125
+ *
126
+ * @since 1.0.0
127
+ * @access public
128
+ */
129
+ public function register_admin_menu()
130
+ {
131
+ $capability = is_network_admin() ? 'manage_network_options' : 'manage_options' ;
132
+ if ( current_user_can($capability) ) {
133
+ // root menu
134
+ add_menu_page('LiteSpeed Cache', 'LiteSpeed Cache', 'manage_options', 'lscache-dash') ;
135
+
136
+ // sub menus
137
+ $this->add_submenu(__('Manage', 'litespeed-cache'), 'lscache-dash', 'show_menu_manage') ;
138
+
139
+ $this->add_submenu(__('Settings', 'litespeed-cache'), 'lscache-settings', 'show_menu_settings') ;
140
+
141
+ if ( ! is_multisite() || is_network_admin() ) {
142
+ $this->add_submenu(__('Edit .htaccess', 'litespeed-cache'), LiteSpeed_Cache::PAGE_EDIT_HTACCESS, 'show_menu_edit_htaccess') ;
143
+ }
144
+
145
+ $this->add_submenu(__('Information', 'litespeed-cache'), 'lscache-info', 'show_info') ;
146
+ if ( ! is_multisite() || is_network_admin() ) {
147
+ $this->add_submenu(__('Environment Report', 'litespeed-cache'), 'lscache-report', 'show_report') ;
148
+ }
149
+
150
+ if ( ! is_network_admin() ) {
151
+ $this->add_submenu(__('Crawler', 'litespeed-cache'), 'lscache-crawler', 'show_crawler') ;
152
+ }
153
+
154
+ if ( LiteSpeed_Cache_Log::get_enabled() ) {
155
+ $this->add_submenu(__('Debug Log', 'litespeed-cache'), 'lscache-debug', 'show_debug_log') ;
156
+ }
157
+
158
+ // sub menus under options
159
+ add_options_page('LiteSpeed Cache', 'LiteSpeed Cache', $capability, 'litespeedcache', array($this, 'show_menu_settings')) ;
160
+ }
161
+ }
162
+
163
+ /**
164
+ * Helper function to set up a submenu page.
165
+ *
166
+ * @since 1.0.4
167
+ * @access private
168
+ * @param string $menu_title The title that appears on the menu.
169
+ * @param string $menu_slug The slug of the page.
170
+ * @param string $callback The callback to call if selected.
171
+ */
172
+ private function add_submenu($menu_title, $menu_slug, $callback)
173
+ {
174
+ add_submenu_page('lscache-dash', $menu_title, $menu_title, 'manage_options', $menu_slug, array($this, $callback)) ;
175
+ }
176
+
177
+ /**
178
+ * Register the stylesheets for the admin area.
179
+ *
180
+ * @since 1.0.14
181
+ * @access public
182
+ */
183
+ public function enqueue_style()
184
+ {
185
+ wp_enqueue_style(LiteSpeed_Cache::PLUGIN_NAME, plugin_dir_url(__FILE__) . 'css/litespeed-cache-admin.css', array(), LiteSpeed_Cache::PLUGIN_VERSION, 'all') ;
186
+ }
187
+
188
+ /**
189
+ * Register the JavaScript for the admin area.
190
+ *
191
+ * @since 1.0.0
192
+ * @access public
193
+ */
194
+ public function enqueue_scripts()
195
+ {
196
+ wp_register_script(LiteSpeed_Cache::PLUGIN_NAME, plugin_dir_url(__FILE__) . 'js/litespeed-cache-admin.js', array(), LiteSpeed_Cache::PLUGIN_VERSION, false) ;
197
+
198
+ if ( LiteSpeed_Cache_Router::has_whm_msg() ) {
199
+ $ajax_url_dismiss_whm = self::build_url(LiteSpeed_Cache::ACTION_DISMISS_WHM, LiteSpeed_Cache::ACTION_DISMISS_WHM) ;
200
+ wp_localize_script(LiteSpeed_Cache::PLUGIN_NAME, 'litespeed_data', array('ajax_url_dismiss_whm' => $ajax_url_dismiss_whm)) ;
201
+ }
202
+
203
+ if ( LiteSpeed_Cache_Router::has_msg_ruleconflict() ) {
204
+ $ajax_url = self::build_url(LiteSpeed_Cache::ACTION_DISMISS_EXPIRESDEFAULT, LiteSpeed_Cache::ACTION_DISMISS_EXPIRESDEFAULT) ;
205
+ wp_localize_script(LiteSpeed_Cache::PLUGIN_NAME, 'litespeed_data', array('ajax_url_dismiss_ruleconflict' => $ajax_url)) ;
206
+ }
207
+
208
+ wp_enqueue_script(LiteSpeed_Cache::PLUGIN_NAME) ;
209
+ }
210
+
211
+ /**
212
+ * Callback that adds LiteSpeed Cache's action links.
213
+ *
214
+ * @since 1.0.0
215
+ * @access public
216
+ * @param array $links Previously added links from other plugins.
217
+ * @return array Links array with the litespeed cache one appended.
218
+ */
219
+ public function add_plugin_links($links)
220
+ {
221
+ //$links[] = '<a href="' . admin_url('admin.php?page=litespeedcache') .'">Settings</a>';
222
+ $links[] = '<a href="' . admin_url('options-general.php?page=litespeedcache') . '">' . __('Settings', 'litespeed-cache') . '</a>' ;
223
+
224
+ return $links ;
225
+ }
226
+
227
+ /**
228
+ * Add text to recommend updating upon update success.
229
+ *
230
+ * @since 1.0.8.1
231
+ * @access public
232
+ * @param string $translations
233
+ * @param string $text
234
+ * @return string
235
+ */
236
+ public function add_update_text($translations, $text)
237
+ {
238
+ if ( $text !== 'Updated!' ) {
239
+ return $translations ;
240
+ }
241
+
242
+ return $translations . ' ' . __('It is recommended that LiteSpeed Cache be purged after updating a plugin.', 'litespeed-cache') ;
243
+ }
244
+
245
+ /**
246
+ * Add the filter to update plugin update text.
247
+ *
248
+ * @since 1.0.8.1
249
+ * @access public
250
+ */
251
+ public function set_update_text()
252
+ {
253
+ add_filter('gettext', array($this, 'add_update_text'), 10, 2) ;
254
+ }
255
+
256
+ /**
257
+ * Remove the filter to update plugin update text.
258
+ *
259
+ * @since 1.0.8.1
260
+ * @access public
261
+ */
262
+ public function unset_update_text()
263
+ {
264
+ remove_filter('gettext', array($this, 'add_update_text')) ;
265
+ }
266
+
267
+ /**
268
+ * Hooked to wp_before_admin_bar_render.
269
+ * Adds a link to the admin bar so users can quickly purge all.
270
+ *
271
+ * @access public
272
+ * @global WP_Admin_Bar $wp_admin_bar
273
+ * @global string $pagenow
274
+ */
275
+ public function add_quick_purge()
276
+ {
277
+ global $wp_admin_bar ;
278
+ $url = self::build_url(LiteSpeed_Cache::ACTION_PURGE_ALL) ;
279
+
280
+ $wp_admin_bar->add_node(array(
281
+ 'id' => 'lscache-quick-purge',
282
+ 'title' => '<span class="ab-icon"></span><span class="ab-label">' . __('LiteSpeed Cache Purge All', 'litespeed-cache') . '</span>',
283
+ 'href' => $url,
284
+ 'meta' => array('class' => 'litespeed-top-toolbar'),
285
+ )) ;
286
+ }
287
+
288
+ /**
289
+ * Builds an admin url with an action and a nonce.
290
+ *
291
+ * Assumes user capabilities are already checked.
292
+ *
293
+ * @access public
294
+ * @param string $action The LSCWP_CTRL action to do in the url.
295
+ * @param string $ajax_action AJAX call's action
296
+ * @return string The built url.
297
+ */
298
+ public static function build_url($action, $ajax_action = false)
299
+ {
300
+ global $pagenow ;
301
+ $prefix = '?' ;
302
+
303
+ if ( $ajax_action === false ) {
304
+ $params = $_GET ;
305
+
306
+ if ( ! empty($params) ) {
307
+ if ( isset($params['LSCWP_CTRL']) ) {
308
+ unset($params['LSCWP_CTRL']) ;
309
+ }
310
+ if ( isset($params['_wpnonce']) ) {
311
+ unset($params['_wpnonce']) ;
312
+ }
313
+ if ( ! empty($params) ) {
314
+ $prefix .= http_build_query($params) . '&' ;
315
+ }
316
+ }
317
+ $combined = $pagenow . $prefix . LiteSpeed_Cache::ACTION_KEY . '=' . $action ;
318
+ }
319
+ else {
320
+ $combined = 'admin-ajax.php?action=' . $ajax_action . '&' . LiteSpeed_Cache::ACTION_KEY . '=' . $action ;
321
+ }
322
+
323
+ if ( is_network_admin() ) {
324
+ $prenonce = network_admin_url($combined) ;
325
+ }
326
+ else {
327
+ $prenonce = admin_url($combined) ;
328
+ }
329
+ $url = wp_nonce_url($prenonce, $action, LiteSpeed_Cache::NONCE_NAME) ;
330
+
331
+ return $url ;
332
+ }
333
+
334
+ /**
335
+ * Change the admin footer text on LiteSpeed Cache admin pages.
336
+ *
337
+ * @since 1.0.13
338
+ * @param string $footer_text
339
+ * @return string
340
+ */
341
+ public function admin_footer_text($footer_text)
342
+ {
343
+ require_once LSWCP_DIR . 'admin/tpl/admin_footer.php' ;
344
+
345
+ return $footer_text ;
346
+ }
347
+
348
+ /**
349
+ * Whether to disable all settings or not.
350
+ *
351
+ * Currently used for 'use primary subsite settings'
352
+ *
353
+ * @since 1.0.13
354
+ * @access public
355
+ * @return bool True to disable all settings, false otherwise.
356
+ */
357
+ public function get_disable_all()
358
+ {
359
+ return $this->disable_all ;
360
+ }
361
+
362
+ /**
363
+ * Set to disable all settings.
364
+ *
365
+ * @since 1.0.13
366
+ * @access public
367
+ */
368
+ public function set_disable_all()
369
+ {
370
+ $this->disable_all = true ;
371
+ }
372
+
373
+ /**
374
+ * If show compatibility tab in settings
375
+ * @since 1.1.0
376
+ * @return bool True if shows
377
+ */
378
+ public function show_compatibility_tab()
379
+ {
380
+ return function_exists('the_views') ;
381
+ }
382
+
383
+ /**
384
+ * Displays the help tab in the admin pages.
385
+ *
386
+ * @since 1.0.0
387
+ * @access public
388
+ */
389
+ public function add_help_tabs()
390
+ {
391
+ require_once LSWCP_DIR . 'admin/tpl/help_tabs.php' ;
392
+ }
393
+
394
+ /**
395
+ * Check to make sure that caching is enabled.
396
+ *
397
+ * @since 1.0.0
398
+ * @access public
399
+ * @return mixed True if enabled, error message otherwise.
400
+ */
401
+ public function check_license()
402
+ {
403
+ if ( ! LiteSpeed_Cache_Config::get_instance()->is_caching_allowed() ) {
404
+ self::add_error(LiteSpeed_Cache_Admin_Error::E_SERVER) ;
405
+ self::display_messages() ;
406
+ }
407
+ }
408
+
409
+ /**
410
+ * Builds the html for a single notice.
411
+ *
412
+ * @since 1.0.7
413
+ * @access private
414
+ * @param string $color The color to use for the notice.
415
+ * @param string $str The notice message.
416
+ * @return string The built notice html.
417
+ */
418
+ private static function build_notice($color, $str)
419
+ {
420
+ return '<div class="' . $color . ' is-dismissible"><p>'. $str . '</p></div>' ;
421
+ }
422
+
423
+ /**
424
+ * Get the error description
425
+ *
426
+ * @since 1.1.0
427
+ * @param init $err_code
428
+ * @param mixed $args
429
+ * @return mixed String or false
430
+ */
431
+ public static function get_error($err_code, $args = null)
432
+ {
433
+ $error = LiteSpeed_Cache_Admin_Error::get_instance()->convert_code_to_error($err_code) ;
434
+ if ( empty($error) ) {
435
+ return false ;
436
+ }
437
+ $error = 'ERROR ' . $err_code . ': ' . $error ;
438
+ if ( ! is_null($args) ) {
439
+ if ( is_array($args) ) {
440
+ $error = vsprintf($error, $args) ;
441
+ }
442
+ else {
443
+ $error = sprintf($error, $args) ;
444
+ }
445
+ }
446
+ return $error ;
447
+ }
448
+
449
+ /**
450
+ * Adds an error to the admin notice system.
451
+ *
452
+ * This function will get the error message by error code and arguments
453
+ * and append it to the list of outgoing errors.
454
+ *
455
+ * @access public
456
+ * @since 1.1.0
457
+ * @param int $err_code The error code to retrieve.
458
+ * @param mixed $args Null if no arguments, an array if multiple arguments,
459
+ * else a single argument.
460
+ */
461
+ public static function add_error($err_code, $args = null)
462
+ {
463
+ $error = self::get_error($err_code, $args) ;
464
+ if( ! $error ) {
465
+ return false ;
466
+ }
467
+ self::add_notice(self::NOTICE_RED, $error) ;
468
+ }
469
+
470
+ /**
471
+ * Adds a notice to display on the admin page. Multiple messages of the
472
+ * same color may be added in a single call. If the list is empty, this
473
+ * method will add the action to display notices.
474
+ *
475
+ * @since 1.0.7
476
+ * @access public
477
+ * @param string $color One of the available constants provided by this
478
+ * class.
479
+ * @param mixed $msg May be a string for a single message or an array for
480
+ * multiple.
481
+ */
482
+ public static function add_notice($color, $msg)
483
+ {
484
+ $messages = (array)get_transient(self::TRANSIENT_LITESPEED_MESSAGE) ;
485
+ if( ! $messages ) {
486
+ $messages = array() ;
487
+ }
488
+ if ( is_array($msg) ) {
489
+ foreach ($msg as $str) {
490
+ $messages[] = self::build_notice($color, $str) ;
491
+ }
492
+ }
493
+ else {
494
+ $messages[] = self::build_notice($color, $msg) ;
495
+ }
496
+ set_transient(self::TRANSIENT_LITESPEED_MESSAGE, $messages, 86400) ;
497
+ }
498
+
499
+ /**
500
+ * Display notices and errors in dashboard
501
+ *
502
+ * @since 1.1.0
503
+ * @access public
504
+ */
505
+ public function display_messages()
506
+ {
507
+ $messages = get_transient(self::TRANSIENT_LITESPEED_MESSAGE) ;
508
+ if( is_array($messages) ) {
509
+ $messages = array_unique($messages) ;
510
+ foreach ($messages as $msg) {
511
+ echo $msg ;
512
+ }
513
+ }
514
+ delete_transient(self::TRANSIENT_LITESPEED_MESSAGE) ;
515
+ }
516
+
517
+ /**
518
+ * Check if has new messages
519
+ *
520
+ * @since 1.1.0
521
+ * @access public
522
+ */
523
+ public function check_messages()
524
+ {
525
+ $messages = get_transient(self::TRANSIENT_LITESPEED_MESSAGE) ;
526
+ if( ! $messages ) {
527
+ return ;
528
+ }
529
+ add_action(is_network_admin() ? 'network_admin_notices' : 'admin_notices', array($this, 'display_messages')) ;
530
+ }
531
+
532
+ /**
533
+ * Hooked to the in_widget_form action.
534
+ * Appends LiteSpeed Cache settings to the widget edit settings screen.
535
+ * This will append the esi on/off selector and ttl text.
536
+ *
537
+ * @access public
538
+ * @since 1.1.0
539
+ * @param type $widget
540
+ * @param type $return
541
+ * @param type $instance
542
+ */
543
+ public function show_widget_edit($widget, $return, $instance)
544
+ {
545
+ require LSWCP_DIR . 'admin/tpl/esi_widget_edit.php' ;
546
+ }
547
+
548
+ /**
549
+ * Displays the cache management page.
550
+ *
551
+ * @since 1.0.0
552
+ * @access public
553
+ */
554
+ public function show_menu_manage()
555
+ {
556
+ require_once LSWCP_DIR . 'admin/tpl/manage.php' ;
557
+ }
558
+
559
+ /**
560
+ * Outputs the LiteSpeed Cache settings page.
561
+ *
562
+ * @since 1.0.0
563
+ * @access public
564
+ */
565
+ public function show_menu_settings()
566
+ {
567
+ if ( is_network_admin() ) {
568
+ require_once LSWCP_DIR . 'admin/tpl/network_settings.php' ;
569
+ }
570
+ else {
571
+ if ( $_GET['page'] != 'litespeedcache' ) {// ls settings msg need to display manually
572
+ settings_errors() ;
573
+ }
574
+ require_once LSWCP_DIR . 'admin/tpl/settings.php' ;
575
+ }
576
+ }
577
+
578
+ /**
579
+ * Displays the edit_htaccess admin page.
580
+ *
581
+ * This function will try to load the .htaccess file contents.
582
+ * If it fails, it will echo the error message.
583
+ *
584
+ * @since 1.0.4
585
+ * @access public
586
+ */
587
+ public function show_menu_edit_htaccess()
588
+ {
589
+ require_once LSWCP_DIR . 'admin/tpl/edit_htaccess.php' ;
590
+ }
591
+
592
+ /**
593
+ * Outputs the html for the Environment Report page.
594
+ *
595
+ * @since 1.0.12
596
+ * @access public
597
+ */
598
+ public function show_report()
599
+ {
600
+ require_once LSWCP_DIR . 'admin/tpl/report.php' ;
601
+ }
602
+
603
+ /**
604
+ * Outputs the crawler operation page.
605
+ *
606
+ * @since 1.1.0
607
+ * @access public
608
+ */
609
+ public function show_crawler()
610
+ {
611
+ require_once LSWCP_DIR . 'admin/tpl/crawler.php' ;
612
+ }
613
+
614
+ /**
615
+ * Outputs the debug log.
616
+ *
617
+ * @since 1.1.5
618
+ * @access public
619
+ */
620
+ public function show_debug_log()
621
+ {
622
+ require_once LSWCP_DIR . 'admin/tpl/debug_log.php' ;
623
+ }
624
+
625
+ /**
626
+ * Outputs the html for the info page.
627
+ *
628
+ * This page includes three tabs:
629
+ * - configuration
630
+ * - third party plugin compatibilities
631
+ * - common rewrite rules.
632
+ *
633
+ * @since 1.1.0
634
+ * @access public
635
+ */
636
+ public function show_info()
637
+ {
638
+ require_once LSWCP_DIR . 'admin/tpl/info.php' ;
639
+ }
640
+
641
+ /**
642
+ * Outputs a notice to the admin panel when ExpiresDefault is detected
643
+ *
644
+ * @since 1.1.5
645
+ * @access public
646
+ */
647
+ public function show_rule_conflict()
648
+ {
649
+ require_once LSWCP_DIR . 'admin/tpl/show_rule_conflict.php' ;
650
+ }
651
+
652
+ /**
653
+ * Outputs a notice to the admin panel when the plugin is installed
654
+ * via the WHM plugin.
655
+ *
656
+ * @since 1.0.12
657
+ * @access public
658
+ */
659
+ public function show_display_installed()
660
+ {
661
+ require_once LSWCP_DIR . 'admin/tpl/show_display_installed.php' ;
662
+ }
663
+
664
+ /**
665
+ * Display error cookie msg.
666
+ *
667
+ * @since 1.0.12
668
+ * @access public
669
+ */
670
+ public static function show_error_cookie()
671
+ {
672
+ require_once LSWCP_DIR . 'admin/tpl/show_error_cookie.php' ;
673
+ }
674
+
675
+ /**
676
+ * Build a textarea
677
+ *
678
+ * @since 1.1.0
679
+ * @access public
680
+ * @param string $id
681
+ * @param string $val Value of input
682
+ * @param boolean $disabled If this input is disabled or not
683
+ * @param int $cols The width of textarea
684
+ */
685
+ public function build_textarea($id, $val = null, $disabled = false, $cols = false)
686
+ {
687
+ if ( $val === null ) {
688
+ global $_options ;
689
+ $val = $_options[$id] ;
690
+ }
691
+ $disabled = $disabled ? ' disabled ' : '' ;
692
+
693
+ if ( $cols === false ) {
694
+ $cols = 80 ;
695
+ }
696
+
697
+ echo "<textarea name='" . LiteSpeed_Cache_Config::OPTION_NAME . "[$id]' rows='5' cols='$cols' $disabled>" . esc_textarea($val) . "</textarea>" ;
698
+ }
699
+
700
+ /**
701
+ * Build a text input field
702
+ *
703
+ * @since 1.1.0
704
+ * @access public
705
+ * @param string $id
706
+ * @param string $style Appending styles
707
+ * @param boolean $disabled Disable this field
708
+ * @param boolean $readonly If is readonly
709
+ * @param string $id_attr ID for this field
710
+ * @param string $val Field value
711
+ * @param string $attrs Additional attributes
712
+ * @param string $type Input type
713
+ */
714
+ public function build_input( $id, $style = false, $disabled = false, $readonly = false, $id_attr = null, $val = null, $attrs = '', $type = 'text' )
715
+ {
716
+ if ( $val === null ) {
717
+ global $_options ;
718
+ $val = $_options[ $id ] ;
719
+ }
720
+ $disabled = $disabled ? ' disabled ' : '' ;
721
+ $readonly = $readonly ? ' readonly ' : '' ;
722
+ if ( $id_attr !== null ) {
723
+ $id_attr = " id='$id_attr' " ;
724
+ }
725
+
726
+ if ( $type == 'text' ) {
727
+ $style = "regular-text $style" ;
728
+ }
729
+
730
+ echo "<input type='$type' class='$style' name='" . LiteSpeed_Cache_Config::OPTION_NAME . "[$id]' value='" . esc_textarea( $val ) ."' $disabled $readonly $id_attr $attrs /> " ;
731
+ }
732
+
733
+ /**
734
+ * Build a switch div html snippet
735
+ *
736
+ * @since 1.1.0
737
+ * @access public
738
+ * @param string $id
739
+ * @param boolean $disabled Disable this field
740
+ * @param boolean $return Return the html or echo it
741
+ * @param boolean $checked If the value is on
742
+ * @param string $id_attr ID for this field, set to true if want to use a not specified unique value
743
+ */
744
+ public function build_switch($id, $disabled = false, $return = false, $checked = null, $id_attr = null)
745
+ {
746
+ $id_attr_on = $id_attr === null ? null : $id_attr . '_' . LiteSpeed_Cache_Config::VAL_ON ;
747
+ $id_attr_off = $id_attr === null ? null : $id_attr . '_' . LiteSpeed_Cache_Config::VAL_OFF ;
748
+ $html = '<div class="litespeed-row">
749
+ <div class="litespeed-switch litespeed-label-info">' ;
750
+ $html .= $this->build_radio($id, LiteSpeed_Cache_Config::VAL_ON, null, $checked, $disabled, $id_attr_on) ;
751
+ $html .= $this->build_radio($id, LiteSpeed_Cache_Config::VAL_OFF, null, $checked === null ? null : !$checked, $disabled, $id_attr_off) ;
752
+ $html .= ' </div>
753
+ </div>' ;
754
+
755
+ if ( $return ) {
756
+ return $html ;
757
+ }
758
+ else {
759
+ echo $html ;
760
+ }
761
+ }
762
+
763
+ /**
764
+ * Build a checkbox html snippet
765
+ *
766
+ * @since 1.1.0
767
+ * @access public
768
+ * @param string $id
769
+ * @param string $title
770
+ * @param bool $checked
771
+ */
772
+ public function build_checkbox($id, $title, $checked, $is_mini = false)
773
+ {
774
+ $checked = $checked ? ' checked ' : '' ;
775
+ $is_mini = $is_mini ? ' litespeed-mini ' : '' ;
776
+
777
+ echo "<div class='litespeed-radio $is_mini'>
778
+ <input type='checkbox' name='" . LiteSpeed_Cache_Config::OPTION_NAME . "[$id]' id='conf_$id' value='1' $checked />
779
+ <label for='conf_$id'>$title</label>
780
+ </div>" ;
781
+ }
782
+
783
+ /**
784
+ * Build a radio input html codes and output
785
+ *
786
+ * @since 1.1.0
787
+ * @access public
788
+ * @param string $id
789
+ * @param string $val Default value of this input
790
+ * @param string $txt Title of this input
791
+ * @param bool $checked If checked or not
792
+ * @param string $id_attr ID for this field, set to true if want to use a not specified unique value
793
+ */
794
+ public function build_radio($id, $val, $txt = null, $checked = null, $disabled = false, $id_attr = null)
795
+ {
796
+ if ( $checked === null ) {
797
+ global $_options ;
798
+ $to_be_checked = is_int($val) ? (int)$_options[$id] : $_options[$id] ;
799
+
800
+ $checked = $to_be_checked === $val ? true : false ;
801
+ }
802
+
803
+ if ( $id_attr === null ) {
804
+ $id_attr = is_int($val) ? "conf_{$id}_$val" : md5($val) ;
805
+ }
806
+ elseif ( $id_attr === true ) {
807
+ $id_attr = md5($val) ;
808
+ }
809
+
810
+ if ( $txt === null ){
811
+ if ( $val === LiteSpeed_Cache_Config::VAL_ON ){
812
+ $txt = __('Enable', 'litespeed-cache') ;
813
+ }
814
+
815
+ if ( $val === LiteSpeed_Cache_Config::VAL_OFF ){
816
+ $txt = __('Disable', 'litespeed-cache') ;
817
+ }
818
+ }
819
+
820
+ $checked = $checked ? ' checked ' : '' ;
821
+ $disabled = $disabled ? ' disabled ' : '' ;
822
+
823
+ return "<input type='radio' "
824
+ . " name='". LiteSpeed_Cache_Config::OPTION_NAME . "[$id]' "
825
+ . " id='$id_attr' "
826
+ . " value='$val' "
827
+ . " $checked "
828
+ . " $disabled "
829
+ . " />"
830
+ . " <label for='$id_attr'>$txt</label>" ;
831
+ }
832
+
833
+ /**
834
+ * Display default value
835
+ *
836
+ * @since 1.1.1
837
+ * @access public
838
+ * @param string $id The setting tag
839
+ */
840
+ public function recommended($id) {
841
+ $val = isset($this->default_settings[$id]) ? $this->default_settings[$id] : '' ;
842
+ if ( $val ) {
843
+ echo sprintf(__('Recommended value: %s.', 'litespeed-cache'), $val) ;
844
+ }
845
+ }
846
+
847
+ /**
848
+ * Get the current instance object.
849
+ *
850
+ * @since 1.1.0
851
+ * @access public
852
+ * @return Current class instance.
853
+ */
854
+ public static function get_instance()
855
+ {
856
+ $cls = get_called_class() ;
857
+ if ( ! isset(self::$_instance) ) {
858
+ self::$_instance = new $cls() ;
859
+ }
860
+
861
+ return self::$_instance ;
862
+ }
863
+ }
admin/litespeed-cache-admin-error.class.php ADDED
@@ -0,0 +1,263 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+
4
+
5
+ /**
6
+ * The admin errors
7
+ *
8
+ *
9
+ * @since 1.0.15
10
+ * @package LiteSpeed_Cache
11
+ * @subpackage LiteSpeed_Cache/admin
12
+ * @author LiteSpeed Technologies <info@litespeedtech.com>
13
+ */
14
+ class LiteSpeed_Cache_Admin_Error
15
+ {
16
+ private static $_instance ;
17
+
18
+ const NOTICE_BLUE = 'notice notice-info' ;
19
+ const NOTICE_GREEN = 'notice notice-success' ;
20
+ const NOTICE_RED = 'notice notice-error' ;
21
+ const NOTICE_YELLOW = 'notice notice-warning' ;
22
+ const E_PHP_VER = 1000 ;
23
+ const E_WP_VER = 1010 ;
24
+
25
+ const E_PURGE_FORM = 2000 ;
26
+ const E_PURGEBY_EMPTY = 2010 ;
27
+ const E_PURGEBY_BAD = 2020 ;
28
+ const E_PURGEBY_CAT_INV = 2030 ;
29
+ const E_PURGEBY_TAG_INV = 2040 ;
30
+ const E_PURGEBY_URL_BAD = 2050 ;
31
+
32
+ const E_PURGEBY_PID_NUM = 2500 ;
33
+ const E_PURGEBY_PID_DNE = 2510 ;
34
+ const E_PURGEBY_URL_INV = 2520 ;
35
+ const E_PURGEBY_CAT_DNE = 2530 ;
36
+ const E_PURGEBY_TAG_DNE = 2540 ;
37
+
38
+ const E_SETTING_ADMIN_IP_INV = 3000 ;
39
+ const E_SETTING_TEST_IP_INV = 3010 ;
40
+ const E_SETTING_SITE_IP = 3020 ;
41
+ const E_SETTING_CUSTOM_SITEMAP_READ = 3030 ;
42
+ const E_SETTING_CUSTOM_SITEMAP_PARSE = 3031 ;
43
+
44
+ const E_SETTING_NUMERIC = 3500 ;
45
+ const E_SETTING_CAT = 3510 ;
46
+ const E_SETTING_TAG = 3520 ;
47
+ const E_SETTING_LC = 3530 ; // login cookie setting
48
+ const E_SETTING_REWRITE = 3540 ;
49
+
50
+ const E_LC_HTA = 4000 ; // login cookie .htaccess not correct
51
+
52
+ const E_HTA_DNF = 4500 ; // .htaccess did not find.
53
+
54
+ const E_LC_MISMATCH = 5000 ; // login cookie mismatch
55
+
56
+ const E_SERVER = 6000 ;
57
+
58
+ const E_CONF = 9000 ; // general config failed to write.
59
+ const E_HTA_BU = 9010 ; // backup
60
+ const E_HTA_PUT = 9020 ; // failed to put
61
+ const E_HTA_GET = 9030 ; // failed to get
62
+ const E_HTA_RW = 9040 ; // read write
63
+ const E_HTA_R = 9041 ; // read
64
+ const E_HTA_W = 9042 ; // write
65
+ const E_HTA_ORDER = 9050 ; // prefix found after suffix
66
+ const E_HTA_SAVE = 9060 ;
67
+ const E_CONF_WRITE = 9070 ;
68
+ const E_CONF_FIND = 9080 ;
69
+
70
+ /**
71
+ * Get the error message by code.
72
+ *
73
+ * @since 1.0.15
74
+ * @access public
75
+ * @param int $err_code The error code to retrieve.
76
+ * @return string The error message if matching, else an empty string.
77
+ */
78
+ public function convert_code_to_error($err_code)
79
+ {
80
+ if ( ! is_numeric($err_code) ) {
81
+ return false ;
82
+ }
83
+
84
+ switch ($err_code){
85
+ case self::E_PHP_VER:
86
+ return '<strong>'
87
+ . __('The installed PHP version is too old for the LiteSpeed Cache Plugin.', 'litespeed-cache')
88
+ . '</strong><br /> '
89
+ . sprintf(__('The LiteSpeed Cache Plugin requires at least PHP %s.', 'litespeed-cache'), '5.3')
90
+ . ' '
91
+ . sprintf(__('The currently installed version is PHP %s, which is out-dated and insecure.', 'litespeed-cache'), PHP_VERSION)
92
+ . ' '
93
+ . sprintf(wp_kses(__('Please upgrade or go to <a href="%s">active plugins</a> and deactivate the LiteSpeed Cache plugin to hide this message.', 'litespeed-cache'),
94
+ array('a' => array('href' => array()))), 'plugins.php?plugin_status=active') ;
95
+
96
+ case self::E_WP_VER:
97
+ return '<strong>'
98
+ . __('The installed WordPress version is too old for the LiteSpeed Cache Plugin.', 'litespeed-cache')
99
+ . '</strong><br />'
100
+ . sprintf(__('The LiteSpeed Cache Plugin requires at least WordPress %s.', 'litespeed-cache'), '3.3')
101
+ . ' '
102
+ . sprintf(wp_kses(__('Please upgrade or go to <a href="%s">active plugins</a> and deactivate the LiteSpeed Cache plugin to hide this message.', 'litespeed-cache'),
103
+ array('a' => array('href' => array()))), 'plugins.php?plugin_status=active') ;
104
+
105
+ // Admin action errors.
106
+ case self::E_PURGE_FORM:
107
+ return __('Something went wrong with the form! Please try again.', 'litespeed-cache') ;
108
+
109
+ case self::E_PURGEBY_EMPTY:
110
+ return __('Tried to purge list with empty list.', 'litespeed-cache') ;
111
+
112
+ case self::E_PURGEBY_BAD:
113
+ return __('Bad Purge By selected value.', 'litespeed-cache') ;
114
+
115
+ case self::E_PURGEBY_CAT_INV:
116
+ return __('Failed to purge by category, invalid category slug.', 'litespeed-cache') ;
117
+
118
+ case self::E_PURGEBY_TAG_INV:
119
+ return __('Failed to purge by tag, invalid tag slug.', 'litespeed-cache') ;
120
+
121
+ case self::E_PURGEBY_URL_BAD:
122
+ return __('Failed to purge by url, contained "<".', 'litespeed-cache') ;
123
+
124
+ // Admin actions with expected parameters for message.
125
+ case self::E_PURGEBY_PID_NUM:
126
+ return __('Failed to purge by Post ID, given ID is not numeric: %s', 'litespeed-cache') ;
127
+
128
+ case self::E_PURGEBY_PID_DNE:
129
+ return __('Failed to purge by Post ID, given ID does not exist or is not published: %s',
130
+ 'litespeed-cache') ;
131
+
132
+ case self::E_PURGEBY_URL_INV:
133
+ return __('Failed to purge by url, invalid input: %s.', 'litespeed-cache') ;
134
+
135
+ case self::E_PURGEBY_CAT_DNE:
136
+ return __('Failed to purge by category, does not exist: %s', 'litespeed-cache') ;
137
+
138
+ case self::E_PURGEBY_TAG_DNE:
139
+ return __('Failed to purge by tag, does not exist: %s', 'litespeed-cache') ;
140
+
141
+ // Admin settings errors.
142
+ case self::E_SETTING_ADMIN_IP_INV:
143
+ return __('Invalid data in Admin IPs.', 'litespeed-cache') ;
144
+
145
+ case self::E_SETTING_TEST_IP_INV:
146
+ return __('Invalid data in Test IPs.', 'litespeed-cache') ;
147
+
148
+ case self::E_SETTING_SITE_IP:
149
+ return __('Invalid Site IP: %s', 'litespeed-cache') ;
150
+
151
+ case self::E_SETTING_CUSTOM_SITEMAP_READ:
152
+ return __('Can not fetch Custom Sitemap: %s', 'litespeed-cache') ;
153
+
154
+ case self::E_SETTING_CUSTOM_SITEMAP_PARSE:
155
+ return __('Can not parse custom sitemap xml file: %s.', 'litespeed-cache') . ' '
156
+ . sprintf(__('Please make sure the file is xml format and the %s extension is installed on the server.', 'litespeed-cache'), 'php-xml') ;
157
+
158
+ // Admin settings with expected parameters for message.
159
+ case self::E_SETTING_NUMERIC:
160
+ // %1 is the name of the option, %2 is the minimum integer allowed.
161
+ return __('%1$s must be an integer between %2$d and %3$d',
162
+ 'litespeed-cache') ;
163
+
164
+ case self::E_SETTING_CAT:
165
+ // %s is the category attempted to be added.
166
+ return __('Removed category "%s" from list, ID does not exist.',
167
+ 'litespeed-cache') ;
168
+
169
+ case self::E_SETTING_TAG:
170
+ // %s is the tag attempted to be added.
171
+ return __('Removed tag "%s" from list, ID does not exist.',
172
+ 'litespeed-cache') ;
173
+
174
+ case self::E_SETTING_LC:
175
+ return __('Invalid login cookie. Invalid characters found: %s',
176
+ 'litespeed-cache') ;
177
+
178
+ case self::E_SETTING_REWRITE:
179
+ return __('Invalid Rewrite List.', 'litespeed-cache') . ' '
180
+ . __('Empty or invalid rule.', 'litespeed-cache') . ' '
181
+ . __('Rule: %1$s, list: %2$s', 'litespeed-cache') ;
182
+
183
+ // Login cookie in settings did not match .htaccess.
184
+ case self::E_LC_HTA:
185
+ return __('Tried to parse for existing login cookie.', 'litespeed-cache') . ' '
186
+ . sprintf(__('%s file not valid. Please verify contents.', 'litespeed-cache'), '.htaccess') ;
187
+
188
+ // Could not find something in the .htaccess file. Expect parameter.
189
+ case self::E_HTA_DNF:
190
+ return __('Could not find %s.', 'litespeed-cache') ;
191
+
192
+ // Mismatched login cookie.
193
+ case self::E_LC_MISMATCH:
194
+ return __('This site is a subdirectory install.', 'litespeed-cache') . ' '
195
+ . __('Login cookies do not match.', 'litespeed-cache') . ' '
196
+ . __('Please remove both and set the login cookie in LiteSpeed Cache advanced settings.', 'litespeed-cache') ;
197
+
198
+ // Either running another server or doesn't have cache module.
199
+ case self::E_SERVER:
200
+ return __('Notice: This plugin requires a LiteSpeed Server with the LSCache Module enabled.', 'litespeed-cache') . ' '
201
+ . __('If you are unable to change your server stack, please contact your hosting provider to request the required changes.', 'litespeed-cache') . ' '
202
+ . __('This plugin will NOT work properly.', 'litespeed-cache') ;
203
+
204
+ case self::E_CONF:
205
+ return __('LiteSpeed Cache was unable to write to the wp-config.php file.', 'litespeed-cache') . ' '
206
+ . sprintf(__('Please add the following to the wp-config.php file: %s', 'litespeed-cache'), '<br><pre>define(\'WP_CACHE\', true);</pre>') ;
207
+
208
+ // .htaccess problem.
209
+ case self::E_HTA_BU:
210
+ return __('Failed to back up file, aborted changes.', 'litespeed-cache') ;
211
+
212
+ case self::E_HTA_PUT:
213
+ return sprintf(__('Failed to put contents into %s', 'litespeed-cache'), '.htaccess') ;
214
+
215
+ case self::E_HTA_GET:
216
+ return sprintf(__('Failed to get %s file contents.', 'litespeed-cache'), '.htaccess') ;
217
+
218
+ case self::E_HTA_RW:
219
+ return sprintf(__('%s file not readable or not writable.', 'litespeed-cache'), '.htaccess') ;
220
+
221
+ case self::E_HTA_R:
222
+ return sprintf(__('%s file not readable.', 'litespeed-cache'), '.htaccess') ;
223
+
224
+ case self::E_HTA_W:
225
+ return sprintf(__('%s file not writable.', 'litespeed-cache'), '.htaccess') ;
226
+
227
+ case self::E_HTA_SAVE:
228
+ return sprintf(__('Failed to overwrite %s.', 'litespeed-cache'), '.htaccess') ;
229
+
230
+ // wp-config problem.
231
+ case self::E_CONF_WRITE:
232
+ $err = sprintf(__('The %1$s file not writeable for %2$s', 'litespeed-cache'), 'wp-config', '\'WP_CACHE\'') ;
233
+ break ;
234
+
235
+ case self::E_CONF_FIND:
236
+ $err = sprintf(__('%s file did not find a place to insert define.', 'litespeed-cache'), 'wp-config') ;
237
+ break ;
238
+
239
+ default:
240
+ return false ;
241
+ }
242
+
243
+ return $err . '<br />' . __('LiteSpeed Cache was unable to write to the wp-config.php file.', 'litespeed-cache') . ' '
244
+ . sprintf(__('Please add the following to the wp-config.php file: %s', 'litespeed-cache'), '<br><pre>define(\'WP_CACHE\', true);</pre>') ;
245
+ }
246
+
247
+ /**
248
+ * Get the current instance object.
249
+ *
250
+ * @since 1.1.0
251
+ * @access public
252
+ * @return Current class instance.
253
+ */
254
+ public static function get_instance()
255
+ {
256
+ $cls = get_called_class() ;
257
+ if ( ! isset(self::$_instance) ) {
258
+ self::$_instance = new $cls() ;
259
+ }
260
+
261
+ return self::$_instance ;
262
+ }
263
+ }
admin/litespeed-cache-admin-report.class.php ADDED
@@ -0,0 +1,198 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * The report class
5
+ *
6
+ *
7
+ * @since 1.1.0
8
+ * @package LiteSpeed_Cache
9
+ * @subpackage LiteSpeed_Cache/admin
10
+ * @author LiteSpeed Technologies <info@litespeedtech.com>
11
+ */
12
+ class LiteSpeed_Cache_Admin_Report
13
+ {
14
+ private static $_instance;
15
+
16
+ /**
17
+ * Gathers the environment details and creates the report.
18
+ * Will write to the environment report file.
19
+ *
20
+ * @since 1.0.12
21
+ * @access public
22
+ * @param mixed $options Array of options to output. If null, will skip
23
+ * the options section.
24
+ * @return string The built report.
25
+ */
26
+ public function generate_environment_report($options = null)
27
+ {
28
+ global $wp_version, $_SERVER ;
29
+ $frontend_htaccess = LiteSpeed_Cache_Admin_Rules::get_frontend_htaccess() ;
30
+ $backend_htaccess = LiteSpeed_Cache_Admin_Rules::get_backend_htaccess() ;
31
+ $paths = array($frontend_htaccess) ;
32
+ if ( $frontend_htaccess != $backend_htaccess ) {
33
+ $paths[] = $backend_htaccess ;
34
+ }
35
+
36
+ if ( is_multisite() ) {
37
+ $active_plugins = get_site_option('active_sitewide_plugins') ;
38
+ if ( ! empty($active_plugins) ) {
39
+ $active_plugins = array_keys($active_plugins) ;
40
+ }
41
+ }
42
+ else {
43
+ $active_plugins = get_option('active_plugins') ;
44
+ }
45
+
46
+ if ( function_exists('wp_get_theme') ) {
47
+ $theme_obj = wp_get_theme() ;
48
+ $active_theme = $theme_obj->get('Name') ;
49
+ }
50
+ else {
51
+ $active_theme = get_current_theme() ;
52
+ }
53
+
54
+ $extras = array(
55
+ 'wordpress version' => $wp_version,
56
+ 'locale' => get_locale(),
57
+ 'active theme' => $active_theme,
58
+ 'active plugins' => $active_plugins,
59
+ ) ;
60
+ if ( is_null($options) ) {
61
+ $options = LiteSpeed_Cache_Config::get_instance()->get_options() ;
62
+ }
63
+
64
+ if ( ! is_null($options) && is_multisite() ) {
65
+ $blogs = LiteSpeed_Cache_Activation::get_network_ids() ;
66
+ if ( ! empty($blogs) ) {
67
+ foreach ( $blogs as $blog_id ) {
68
+ $opts = get_blog_option($blog_id, LiteSpeed_Cache_Config::OPTION_NAME, array()) ;
69
+ if ( isset($opts[LiteSpeed_Cache_Config::OPID_ENABLED_RADIO]) ) {
70
+ $options['blog ' . $blog_id . ' radio select'] = $opts[LiteSpeed_Cache_Config::OPID_ENABLED_RADIO] ;
71
+ }
72
+ }
73
+ }
74
+ }
75
+
76
+ $report = $this->build_environment_report($_SERVER, $options, $extras, $paths) ;
77
+ $this->write_environment_report($report) ;
78
+ return $report ;
79
+ }
80
+
81
+ /**
82
+ * Write the environment report to the report location.
83
+ *
84
+ * @since 1.0.12
85
+ * @access private
86
+ * @param string $content What to write to the environment report.
87
+ */
88
+ private function write_environment_report( $content )
89
+ {
90
+ $content = "<" . "?php die() ; ?" . ">\n\n" . $content ;
91
+
92
+ $ret = Litespeed_File::save( LSWCP_DIR . 'environment_report.php', $content, false, false, false ) ;
93
+
94
+ if ( $ret !== true && LiteSpeed_Cache_Log::get_enabled() ) {
95
+ LiteSpeed_Cache_Log::push( $ret ) ;
96
+ }
97
+ }
98
+
99
+ /**
100
+ * Builds the environment report buffer with the given parameters
101
+ *
102
+ * @access private
103
+ * @param array $server - server variables
104
+ * @param array $options - cms options
105
+ * @param array $extras - cms specific attributes
106
+ * @param array $htaccess_paths - htaccess paths to check.
107
+ * @return string The Environment Report buffer.
108
+ */
109
+ private function build_environment_report($server, $options, $extras = array(), $htaccess_paths = array())
110
+ {
111
+ $server_keys = array(
112
+ 'DOCUMENT_ROOT'=>'',
113
+ 'SERVER_SOFTWARE'=>'',
114
+ 'X-LSCACHE'=>'',
115
+ 'HTTP_X_LSCACHE'=>''
116
+ ) ;
117
+ $server_vars = array_intersect_key($server, $server_keys) ;
118
+ $server_vars[] = "LSWCP_TAG_PREFIX = " . LSWCP_TAG_PREFIX ;
119
+
120
+ $buf = $this->format_report_section('Server Variables', $server_vars) ;
121
+
122
+ $buf .= $this->format_report_section('LSCache Plugin Options', $options) ;
123
+
124
+ $buf .= $this->format_report_section('Wordpress Specific Extras', $extras) ;
125
+
126
+ if ( empty($htaccess_paths) ) {
127
+ return $buf ;
128
+ }
129
+
130
+ foreach ( $htaccess_paths as $path ) {
131
+ if ( ! file_exists($path) || ! is_readable($path) ) {
132
+ $buf .= $path . " does not exist or is not readable.\n" ;
133
+ continue ;
134
+ }
135
+
136
+ $content = file_get_contents($path) ;
137
+ if ( $content === false ) {
138
+ $buf .= $path . " returned false for file_get_contents.\n" ;
139
+ continue ;
140
+ }
141
+ $buf .= $path . " contents:\n" . $content . "\n\n" ;
142
+ }
143
+ return $buf ;
144
+ }
145
+
146
+ /**
147
+ * Creates a part of the environment report based on a section header
148
+ * and an array for the section parameters.
149
+ *
150
+ * @since 1.0.12
151
+ * @access private
152
+ * @param string $section_header The section heading
153
+ * @param array $section An array of information to output
154
+ * @return string The created report block.
155
+ */
156
+ private function format_report_section($section_header, $section)
157
+ {
158
+ $tab = ' ' ; // four spaces
159
+ $nl = "\n" ;
160
+
161
+ if ( empty($section) ) {
162
+ return 'No matching ' . $section_header . $nl . $nl ;
163
+ }
164
+ $buf = $section_header ;
165
+
166
+ foreach ( $section as $key=>$val ) {
167
+ $buf .= $nl . $tab ;
168
+ if ( ! is_numeric($key) ) {
169
+ $buf .= $key . ' = ' ;
170
+ }
171
+
172
+ if ( ! is_string($val) ) {
173
+ $buf .= print_r($val, true) ;
174
+ }
175
+ else {
176
+ $buf .= $val ;
177
+ }
178
+ }
179
+ return $buf . $nl . $nl ;
180
+ }
181
+
182
+ /**
183
+ * Get the current instance object.
184
+ *
185
+ * @since 1.1.0
186
+ * @access public
187
+ * @return Current class instance.
188
+ */
189
+ public static function get_instance()
190
+ {
191
+ $cls = get_called_class() ;
192
+ if ( ! isset(self::$_instance) ) {
193
+ self::$_instance = new $cls() ;
194
+ }
195
+
196
+ return self::$_instance ;
197
+ }
198
+ }
admin/litespeed-cache-admin-rules.class.php ADDED
@@ -0,0 +1,891 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The admin-panel specific functionality of the plugin.
4
+ *
5
+ *
6
+ * @since 1.0.0
7
+ * @package LiteSpeed_Cache
8
+ * @subpackage LiteSpeed_Cache/admin
9
+ * @author LiteSpeed Technologies <info@litespeedtech.com>
10
+ */
11
+ class LiteSpeed_Cache_Admin_Rules
12
+ {
13
+ private static $_instance ;
14
+
15
+ const EDITOR_TEXTAREA_NAME = 'lscwp_ht_editor' ;
16
+
17
+ private $frontend_htaccess = null ;
18
+ private $backend_htaccess = null ;
19
+ private $theme_htaccess = null ;
20
+ private $frontend_htaccess_readable = false ;
21
+ private $frontend_htaccess_writable = false ;
22
+ private $backend_htaccess_readable = false ;
23
+ private $backend_htaccess_writable = false ;
24
+ private $theme_htaccess_readable = false ;
25
+ private $theme_htaccess_writable = false ;
26
+
27
+ private static $RW_LOOKUP ;
28
+ const RW_LOOKUP_PUBLIC = "CacheLookup Public on" ;
29
+ const RW_LOOKUP_BOTH = "CacheLookup on" ;
30
+ const RW_PRIV_BYPASS_POST_PURGE = "RewriteRule .* - [E=Cache-Control:no-autoflush]" ;
31
+
32
+ const LS_MODULE_START = '<IfModule LiteSpeed>' ;
33
+ const LS_MODULE_END = '</IfModule>' ;
34
+ private static $LS_MODULE_REWRITE_ON ;
35
+ const LS_MODULE_DONOTEDIT = "## LITESPEED WP CACHE PLUGIN - Do not edit the contents of this block! ##" ;
36
+ const MARKER = 'LSCACHE' ;
37
+ const MARKER_LOGIN_COOKIE = '### marker LOGIN COOKIE' ;
38
+ const MARKER_MOBILE = '### marker MOBILE' ;
39
+ const MARKER_NOCACHE_COOKIES = '### marker NOCACHE COOKIES' ;
40
+ const MARKER_NOCACHE_USER_AGENTS = '### marker NOCACHE USER AGENTS' ;
41
+ const MARKER_CACHE_RESOURCE = '### marker CACHE RESOURCE' ;
42
+ const MARKER_FAVICON = '### marker FAVICON' ;
43
+ const MARKER_START = ' start ###' ;
44
+ const MARKER_END = ' end ###' ;
45
+
46
+ const RW_PATTERN_RES = 'wp-content/.*/[^/]*(responsive|css|js|dynamic|loader|fonts)\.php' ;
47
+
48
+ /**
49
+ * Initialize the class and set its properties.
50
+ *
51
+ * @since 1.0.7
52
+ * @access private
53
+ */
54
+ private function __construct()
55
+ {
56
+ $this->path_set() ;
57
+ clearstatcache() ;
58
+
59
+ // frontend .htaccess privilege
60
+ $test_permissions = file_exists($this->frontend_htaccess) ? $this->frontend_htaccess : dirname($this->frontend_htaccess) ;
61
+ if ( is_readable($test_permissions) ) {
62
+ $this->frontend_htaccess_readable = true ;
63
+ }
64
+ if ( is_writable($test_permissions) ) {
65
+ $this->frontend_htaccess_writable = true ;
66
+ }
67
+ if ( LITESPEED_SERVER_TYPE == 'LITESPEED_SERVER_OLS' ) {
68
+ self::$RW_LOOKUP = self::RW_LOOKUP_PUBLIC ;
69
+ }
70
+ else {
71
+ self::$RW_LOOKUP = self::RW_LOOKUP_BOTH ;
72
+ }
73
+ self::$LS_MODULE_REWRITE_ON = "RewriteEngine on\n" . self::$RW_LOOKUP . "\n" . self::RW_PRIV_BYPASS_POST_PURGE ;
74
+
75
+ // backend .htaccess privilege
76
+ if ( $this->frontend_htaccess === $this->backend_htaccess ) {
77
+ $this->backend_htaccess_readable = $this->frontend_htaccess_readable;
78
+ $this->backend_htaccess_writable = $this->frontend_htaccess_writable;
79
+ }
80
+ else{
81
+ $test_permissions = file_exists($this->backend_htaccess) ? $this->backend_htaccess : dirname($this->backend_htaccess);
82
+ if ( is_readable($test_permissions) ) {
83
+ $this->backend_htaccess_readable = true;
84
+ }
85
+ if ( is_writable($test_permissions) ) {
86
+ $this->backend_htaccess_writable = true;
87
+ }
88
+ }
89
+ }
90
+
91
+ /**
92
+ * Get if htaccess file is readable
93
+ *
94
+ * @since 1.1.0
95
+ * @return string
96
+ */
97
+ public static function readable($kind = 'frontend')
98
+ {
99
+ if( $kind === 'frontend' ) {
100
+ return self::get_instance()->frontend_htaccess_readable ;
101
+ }
102
+ if( $kind === 'backend' ) {
103
+ return self::get_instance()->backend_htaccess_readable ;
104
+ }
105
+ }
106
+
107
+ /**
108
+ * Get if htaccess file is writable
109
+ *
110
+ * @since 1.1.0
111
+ * @return string
112
+ */
113
+ public static function writable($kind = 'frontend')
114
+ {
115
+ if( $kind === 'frontend' ) {
116
+ return self::get_instance()->frontend_htaccess_writable ;
117
+ }
118
+ if( $kind === 'backend' ) {
119
+ return self::get_instance()->backend_htaccess_writable ;
120
+ }
121
+ }
122
+
123
+ /**
124
+ * Get frontend htaccess path
125
+ *
126
+ * @since 1.1.0
127
+ * @return string
128
+ */
129
+ public static function get_frontend_htaccess()
130
+ {
131
+ return self::get_instance()->frontend_htaccess ;
132
+ }
133
+
134
+ /**
135
+ * Get backend htaccess path
136
+ *
137
+ * @since 1.1.0
138
+ * @return string
139
+ */
140
+ public static function get_backend_htaccess()
141
+ {
142
+ return self::get_instance()->backend_htaccess ;
143
+ }
144
+
145
+ /**
146
+ * Check to see if .htaccess exists starting at $start_path and going up directories until it hits DOCUMENT_ROOT.
147
+ *
148
+ * As dirname() strips the ending '/', paths passed in must exclude the final '/'
149
+ *
150
+ * If can't find, return false
151
+ *
152
+ * @since 1.0.11
153
+ * @access private
154
+ * @param string $start_path The first directory level to search.
155
+ * @return string The deepest path where .htaccess exists, False if not.
156
+ */
157
+ private function htaccess_search( $start_path )
158
+ {
159
+ while ( ! file_exists( $start_path . '/.htaccess' ) ) {
160
+ if ( $start_path === '/' || ! $start_path ) {
161
+ return false ;
162
+ }
163
+ if ( ! empty( $_SERVER[ 'DOCUMENT_ROOT' ] ) && $start_path === $_SERVER[ 'DOCUMENT_ROOT' ] ) {
164
+ return false ;
165
+ }
166
+ $start_path = dirname( $start_path ) ;
167
+ }
168
+
169
+ return $start_path ;
170
+ }
171
+
172
+ /**
173
+ * Set the path class variables.
174
+ *
175
+ * @since 1.0.11
176
+ * @access private
177
+ */
178
+ private function path_set()
179
+ {
180
+ $this->theme_htaccess = LSWCP_CONTENT_DIR ;
181
+
182
+ $frontend = rtrim( get_home_path(), '/' ) ; // /home/user/public_html/frontend
183
+ // get home path failed. Trac ticket #37668 (e.g. frontend:/blog backend:/wordpress)
184
+ if ( ! $frontend ) {
185
+ $frontend = parse_url( get_option( 'home' ) ) ;
186
+ $frontend = ! empty( $frontend[ 'path' ] ) ? $frontend[ 'path' ] : '' ;
187
+ $frontend = $_SERVER["DOCUMENT_ROOT"] . $frontend ;
188
+ }
189
+ $frontend = realpath( $frontend ) ;
190
+ $frontend_htaccess_search = $this->htaccess_search( $frontend ) ;// The existing .htaccess path to be used for frontend .htaccess
191
+ $this->frontend_htaccess = ( $frontend_htaccess_search ?: $frontend ) . '/.htaccess' ;
192
+
193
+ $backend = realpath( ABSPATH ) ; // /home/user/public_html/backend/
194
+ if ( $frontend == $backend ) {
195
+ $this->backend_htaccess = $this->frontend_htaccess ;
196
+ return ;
197
+ }
198
+
199
+ // Backend is a different path
200
+ $backend_htaccess_search = $this->htaccess_search( $backend ) ;
201
+ // Found affected .htaccess
202
+ if ( $backend_htaccess_search ) {
203
+ $this->backend_htaccess = $backend_htaccess_search . '/.htaccess' ;
204
+ return ;
205
+ }
206
+
207
+ // Frontend path is the parent of backend path
208
+ if ( stripos( $backend, $frontend . '/' ) === 0 ) {
209
+ // backend use frontend htaccess
210
+ $this->backend_htaccess = $this->frontend_htaccess ;
211
+ return ;
212
+ }
213
+
214
+ $this->backend_htaccess = $backend . '/.htaccess' ;
215
+ }
216
+
217
+ /**
218
+ * Get corresponding htaccess path
219
+ *
220
+ * @since 1.1.0
221
+ * @param string $kind Frontend or backend
222
+ * @return string Path
223
+ */
224
+ public function htaccess_path($kind = 'frontend')
225
+ {
226
+ switch ( $kind ) {
227
+ case 'frontend':
228
+ $path = $this->frontend_htaccess ;
229
+ break ;
230
+
231
+ case 'backend':
232
+ $path = $this->backend_htaccess ;
233
+ break ;
234
+
235
+ default:
236
+ $path = $this->frontend_htaccess ;
237
+ break ;
238
+ }
239
+ return $path ;
240
+ }
241
+
242
+ /**
243
+ * Get the content of the rules file.
244
+ * If can't read, will add error msg to dashboard
245
+ * Only when need to add error msg, this function is used, otherwise use file_get_contents directly
246
+ *
247
+ * @since 1.0.4
248
+ * @access public
249
+ * @param string $path The path to get the content from.
250
+ * @return boolean True if succeeded, false otherwise.
251
+ */
252
+ public function htaccess_read($kind = 'frontend')
253
+ {
254
+ $path = $this->htaccess_path($kind) ;
255
+
256
+ if( ! $path || ! file_exists($path) ) {
257
+ return "\n" ;
258
+ }
259
+ if ( ! self::readable($kind) || ! self::writable($kind) ) {
260
+ LiteSpeed_Cache_Admin_Display::add_error(LiteSpeed_Cache_Admin_Error::E_HTA_RW) ;
261
+ return false ;
262
+ }
263
+
264
+ $content = file_get_contents($path) ;
265
+ if ( $content === false ) {
266
+ LiteSpeed_Cache_Admin_Display::add_error(LiteSpeed_Cache_Admin_Error::E_HTA_GET) ;
267
+ return false ;
268
+ }
269
+
270
+ // Remove ^M characters.
271
+ $content = str_ireplace("\x0D", "", $content) ;
272
+ return $content ;
273
+ }
274
+
275
+ /**
276
+ * Try to save the rules file changes.
277
+ *
278
+ * This function is used by both the edit .htaccess admin page and
279
+ * the common rewrite rule configuration options.
280
+ *
281
+ * This function will create a backup with _lscachebak appended to the file name
282
+ * prior to making any changese. If creating the backup fails, an error is returned.
283
+ *
284
+ * @since 1.0.4
285
+ * @since 1.0.12 - Introduce $backup parameter and make function public
286
+ * @access public
287
+ * @param string $content The new content to put into the rules file.
288
+ * @param string $kind The htaccess to edit. Default is frontend htaccess file.
289
+ * @param boolean $backup Whether to create backups or not.
290
+ * @return boolean true on success, else false.
291
+ */
292
+ public function htaccess_save($content, $kind = 'frontend', $backup = true)
293
+ {
294
+ $path = $this->htaccess_path($kind) ;
295
+
296
+ if ( ! self::readable($kind) ) {
297
+ LiteSpeed_Cache_Admin_Display::add_error(LiteSpeed_Cache_Admin_Error::E_HTA_R) ;
298
+ return false ;
299
+ }
300
+
301
+ if ( ! self::writable($kind) ) {
302
+ LiteSpeed_Cache_Admin_Display::add_error(LiteSpeed_Cache_Admin_Error::E_HTA_W) ;
303
+ return false ;
304
+ }
305
+
306
+ //failed to backup, not good.
307
+ if ( $backup && $this->htaccess_backup($kind) === false ) {
308
+ LiteSpeed_Cache_Admin_Display::add_error(LiteSpeed_Cache_Admin_Error::E_HTA_BU) ;
309
+ return false ;
310
+ }
311
+
312
+ // File put contents will truncate by default. Will create file if doesn't exist.
313
+ $ret = file_put_contents($path, $content, LOCK_EX) ;
314
+ if ( $ret === false ) {
315
+ LiteSpeed_Cache_Admin_Display::add_error(LiteSpeed_Cache_Admin_Error::E_HTA_SAVE) ;
316
+ return false ;
317
+ }
318
+
319
+ return true ;
320
+ }
321
+
322
+ /**
323
+ * Try to backup the .htaccess file.
324
+ * This function will attempt to create a .htaccess_lscachebak_orig first.
325
+ * If that is already created, it will attempt to create .htaccess_lscachebak_[1-10]
326
+ * If 10 are already created, zip the current set of backups (sans _orig).
327
+ * If a zip already exists, overwrite it.
328
+ *
329
+ * @since 1.0.10
330
+ * @access private
331
+ * @param string $kind The htaccess to edit. Default is frontend htaccess file.
332
+ * @return boolean True on success, else false on failure.
333
+ */
334
+ private function htaccess_backup($kind = 'frontend')
335
+ {
336
+ $path = $this->htaccess_path($kind) ;
337
+ $bak = '_lscachebak_orig' ;
338
+ $i = 1 ;
339
+
340
+ if ( ! file_exists($path) ) {
341
+ return true ;
342
+ }
343
+
344
+ if ( file_exists($path . $bak) ) {
345
+ $bak = sprintf("_lscachebak_%02d", $i) ;
346
+ while (file_exists($path . $bak)) {
347
+ $i++ ;
348
+ $bak = sprintf("_lscachebak_%02d", $i) ;
349
+ }
350
+ }
351
+
352
+ if ( $i <= 10 || ! class_exists('ZipArchive') ) {
353
+ $ret = copy($path, $path . $bak) ;
354
+ return $ret ;
355
+ }
356
+
357
+ $zip = new ZipArchive ;
358
+ $dir = dirname($path) ;
359
+ $arr = scandir($dir) ;
360
+ $parsed = preg_grep('/\.htaccess_lscachebak_[0-9]+/', $arr) ;
361
+
362
+ if ( empty($parsed) ) {
363
+ return false ;
364
+ }
365
+
366
+ $res = $zip->open($dir . '/lscache_htaccess_bak.zip', ZipArchive::CREATE | ZipArchive::OVERWRITE) ;
367
+ if ( $res !== true ) {
368
+ error_log('Warning: Failed to archive wordpress backups in ' . $dir) ;
369
+ $ret = copy($path, $path . $bak) ;
370
+ return $ret ;
371
+ }
372
+
373
+ foreach ($parsed as $key => $val) {
374
+ $parsed[$key] = $dir . '/' . $val ;
375
+ if ( ! $zip->addFile($parsed[$key], $val) ) {
376
+ error_log('Warning: Failed to archive backup file ' . $val) ;
377
+ $zip->close() ;
378
+ $ret = copy($path, $path . $bak) ;
379
+ return $ret ;
380
+ }
381
+ }
382
+
383
+ $ret = $zip->close() ;
384
+ if ( ! $ret ) {
385
+ error_log('Warning: Failed to close archive.') ;
386
+ return $ret ;
387
+ }
388
+ $bak = '_lscachebak_01' ;
389
+
390
+ foreach ($parsed as $delFile) {
391
+ unlink($delFile) ;
392
+ }
393
+
394
+ $ret = copy($path, $path . $bak) ;
395
+ return $ret ;
396
+ }
397
+
398
+ /**
399
+ * Get mobile view rule from htaccess file
400
+ *
401
+ * @since 1.1.0
402
+ * @return string Mobile Agents value
403
+ */
404
+ public function get_rewrite_rule_mobile_agents()
405
+ {
406
+ $rules = $this->get_rewrite_rule(self::MARKER_MOBILE) ;
407
+ if( ! isset($rules[0]) ) {
408
+ LiteSpeed_Cache_Admin_Display::add_error(LiteSpeed_Cache_Admin_Error::E_HTA_DNF, self::MARKER_MOBILE) ;
409
+ return false ;
410
+ }
411
+ $rule = trim($rules[0]) ;
412
+ $pattern = '/RewriteCond\s%{HTTP_USER_AGENT}\s+([^[\n]*)\s+[[]*/' ;
413
+ $matches = array() ;
414
+ $num_matches = preg_match($pattern, $rule, $matches) ;
415
+ if ( $num_matches === false ) {
416
+ LiteSpeed_Cache_Admin_Display::add_error(LiteSpeed_Cache_Admin_Error::E_HTA_DNF, 'a match') ;
417
+ return false ;
418
+ }
419
+ $match = trim($matches[1]) ;
420
+ return $match ;
421
+ }
422
+
423
+ /**
424
+ * Parse rewrites rule from the .htaccess file.
425
+ *
426
+ * @since 1.1.0
427
+ * @access public
428
+ * @param string $kind The kind of htaccess to search in
429
+ * @return array
430
+ */
431
+ public function get_rewrite_rule_login_cookie($kind = 'frontend')
432
+ {
433
+ $rule = $this->get_rewrite_rule(self::MARKER_LOGIN_COOKIE, $kind) ;
434
+ if( substr($rule, 0, strlen('RewriteRule .? - [E=')) !== 'RewriteRule .? - [E=' ) {//todo: use regex
435
+ return false ;
436
+ }
437
+
438
+ return substr($rule, strlen('RewriteRule .? - [E='), -1) ;//todo:user trim('"')
439
+ }
440
+
441
+ /**
442
+ * Get rewrite rules based on tags
443
+ * @param string $cond The tag to be used
444
+ * @param string $kind Frontend or backend .htaccess file
445
+ * @return mixed Rules
446
+ */
447
+ private function get_rewrite_rule($cond, $kind = 'frontend')
448
+ {
449
+ clearstatcache() ;
450
+ $path = $this->htaccess_path($kind) ;
451
+ if ( ! self::readable($kind) ) {
452
+ return false ;
453
+ }
454
+
455
+ $rules = Litespeed_File::extract_from_markers($path, self::MARKER) ;
456
+ if( ! in_array($cond . self::MARKER_START, $rules) || ! in_array($cond . self::MARKER_END, $rules) ) {
457
+ return false ;
458
+ }
459
+
460
+ $key_start = array_search($cond . self::MARKER_START, $rules) ;
461
+ $key_end = array_search($cond . self::MARKER_END, $rules) ;
462
+ if( $key_start === false || $key_end === false ) {
463
+ return false ;
464
+ }
465
+
466
+ $results = array_slice($rules, $key_start+1, $key_end-$key_start-1) ;
467
+ if( ! $results ) {
468
+ return false ;
469
+ }
470
+ if( count($results) == 1 ) {
471
+ return trim($results[0]) ;
472
+ }
473
+ return array_filter($results) ;
474
+ }
475
+
476
+ /**
477
+ * Parses the input to see if there is a need to edit the .htaccess file.
478
+ *
479
+ * @since 1.0.8
480
+ * @access public
481
+ * @param array $options The current options
482
+ * @param array $input The input
483
+ * @param array $errors Errors array to add error messages to.
484
+ * @return mixed False if there is an error, diff array otherwise.
485
+ */
486
+ public function check_input_for_rewrite($options, $input, &$errors)
487
+ {
488
+ $diff = array() ;
489
+ $val_check = array(
490
+ LiteSpeed_Cache_Config::OPID_CACHE_MOBILE,
491
+ LiteSpeed_Cache_Config::OPID_CACHE_FAVICON,
492
+ LiteSpeed_Cache_Config::OPID_CACHE_RES
493
+ ) ;
494
+ $has_error = false ;
495
+
496
+ foreach ($val_check as $opt) {
497
+ $input[$opt] = LiteSpeed_Cache_Admin_Settings::parse_onoff( $input, $opt ) ;
498
+ if ( $input[$opt] || $options[$opt] != $input[$opt] ) {
499
+ $diff[$opt] = $input[$opt] ;
500
+ }
501
+ }
502
+
503
+ // check mobile agents
504
+ $id = LiteSpeed_Cache_Config::ID_MOBILEVIEW_LIST ;
505
+ if ( $input[LiteSpeed_Cache_Config::OPID_CACHE_MOBILE] ) {
506
+ $list = $input[$id] ;
507
+ if ( empty($list) || $this->check_rewrite($list) === false ) {
508
+ $errors[] = LiteSpeed_Cache_Admin_Display::get_error(LiteSpeed_Cache_Admin_Error::E_SETTING_REWRITE, array($id, empty($list) ? 'EMPTY' : esc_html($list))
509
+ ) ;
510
+ $has_error = true ;
511
+ }
512
+ $diff[$id] = $list ;
513
+ }
514
+ elseif ( isset($diff[LiteSpeed_Cache_Config::OPID_CACHE_MOBILE]) ) {
515
+ $diff[$id] = false ;
516
+ }
517
+
518
+ $id = LiteSpeed_Cache_Config::ID_NOCACHE_COOKIES ;
519
+ if ( isset($input[$id]) && $input[$id] ) {
520
+ $cookie_list = preg_replace("/[\r\n]+/", '|', $input[$id]) ;
521
+ }
522
+ else {
523
+ $cookie_list = '' ;
524
+ }
525
+
526
+ if ( empty($cookie_list) || $this->check_rewrite($cookie_list) ) {
527
+ $diff[$id] = $cookie_list ;
528
+ }
529
+ else {
530
+ $errors[] = LiteSpeed_Cache_Admin_Display::get_error(LiteSpeed_Cache_Admin_Error::E_SETTING_REWRITE, array($id, esc_html($cookie_list))) ;
531
+ $has_error = true ;
532
+ }
533
+
534
+ $id = LiteSpeed_Cache_Config::ID_NOCACHE_USERAGENTS ;
535
+ if ( isset($input[$id]) && $this->check_rewrite($input[$id]) ) {
536
+ $diff[$id] = $input[$id] ;
537
+ }
538
+ else {
539
+ $err_args = array($id) ;
540
+ if ( ! isset($input[$id]) || empty($input[$id]) ) {
541
+ $err_args[] = 'EMPTY' ;
542
+ }
543
+ else {
544
+ $err_args[] = esc_html($input[$id]) ;
545
+ }
546
+ $errors[] = LiteSpeed_Cache_Admin_Display::get_error(LiteSpeed_Cache_Admin_Error::E_SETTING_REWRITE, $err_args) ;
547
+ $has_error = true ;
548
+ }
549
+
550
+ $id = LiteSpeed_Cache_Config::OPID_LOGIN_COOKIE ;
551
+ $aExceptions = array('-', '_') ;
552
+ if ( isset($input[$id]) ) {
553
+ if ( $input[$id] === '' || (ctype_alnum(str_replace($aExceptions, '', $input[$id])) && $this->check_rewrite($input[$id])) ) {
554
+ $diff[$id] = $input[$id] ;
555
+ }
556
+ else {
557
+ $errors[] = LiteSpeed_Cache_Admin_Display::get_error(LiteSpeed_Cache_Admin_Error::E_SETTING_LC, esc_html($input[$id])) ;
558
+ $has_error = true ;
559
+ }
560
+ }
561
+
562
+ if ( $has_error ) {
563
+ return false ;
564
+ }
565
+ return $diff ;
566
+ }
567
+
568
+ /**
569
+ * Parse rewrite input to check for possible issues (e.g. unescaped spaces).
570
+ *
571
+ * Issues tracked:
572
+ * Starts with |
573
+ * Ends with |
574
+ * Double |
575
+ * Unescaped space
576
+ * Invalid character (NOT \w, -, \, |, \s, /, ., +, *, (, ))
577
+ *
578
+ * @since 1.0.9
579
+ * @access private
580
+ * @param String $rule Input rewrite rule.
581
+ * @return boolean True for valid rules, false otherwise.
582
+ */
583
+ private function check_rewrite($rule)
584
+ {
585
+ $escaped = str_replace('@', '\@', $rule) ;
586
+ return @preg_match('@' . $escaped . '@', null) !== false ;//todo: improve to try catch
587
+ }
588
+
589
+ /**
590
+ * Validate common rewrite rules configured by the admin.
591
+ *
592
+ * @since 1.0.4
593
+ * @access public
594
+ * @param array $diff The rules that need to be set.
595
+ * @param array $errors Returns error messages added if failed.
596
+ * @return mixed Returns updated options array on success, false otherwise.
597
+ */
598
+ public function validate_common_rewrites($diff, &$errors)
599
+ {
600
+ if ( ! self::readable() ) {
601
+ $errors[] = LiteSpeed_Cache_Admin_Display::get_error(LiteSpeed_Cache_Admin_Error::E_HTA_R) ;
602
+ return false ;
603
+ }
604
+
605
+ if ( $this->frontend_htaccess !== $this->backend_htaccess ) {
606
+ if ( ! self::readable('backend') ) {
607
+ $errors[] = LiteSpeed_Cache_Admin_Display::get_error(LiteSpeed_Cache_Admin_Error::E_HTA_R) ;
608
+ return false ;
609
+ }
610
+ }
611
+
612
+ // check login cookie
613
+ if ( LITESPEED_SERVER_TYPE === 'LITESPEED_SERVER_OLS' ) {
614
+ $id = LiteSpeed_Cache_Config::OPID_LOGIN_COOKIE ;
615
+ if ( $diff[$id] ) {
616
+ $diff[$id] .= ',wp-postpass_' . COOKIEHASH ;
617
+ }
618
+ else {
619
+ $diff[$id] = 'wp-postpass_' . COOKIEHASH ;
620
+ }
621
+
622
+ $tp_cookies = apply_filters('litespeed_cache_api_vary', array()) ;
623
+ if ( ! empty($tp_cookies) && is_array($tp_cookies) ) {
624
+ $diff[$id] .= ',' . implode(',', $tp_cookies) ;
625
+ }
626
+ }
627
+
628
+ $new_rules = array() ;
629
+ $new_rules_backend = array() ;
630
+ // mobile agents
631
+ $id = LiteSpeed_Cache_Config::ID_MOBILEVIEW_LIST ;
632
+ if ( isset($diff[$id]) && $diff[$id] ) {
633
+ $new_rules[] = self::MARKER_MOBILE . self::MARKER_START ;
634
+ $new_rules[] = 'RewriteCond %{HTTP_USER_AGENT} ' . $diff[$id] . ' [NC]' ;
635
+ $new_rules[] = 'RewriteRule .* - [E=Cache-Control:vary=ismobile]' ;
636
+ $new_rules[] = self::MARKER_MOBILE . self::MARKER_END ;
637
+ $new_rules[] = '' ;
638
+ }
639
+
640
+ // nocache cookie
641
+ $id = LiteSpeed_Cache_Config::ID_NOCACHE_COOKIES ;
642
+ if ( isset($diff[$id]) && $diff[$id] ) {
643
+ $new_rules[] = self::MARKER_NOCACHE_COOKIES . self::MARKER_START ;
644
+ $new_rules[] = 'RewriteCond %{HTTP_COOKIE} ' . $diff[$id] ;
645
+ $new_rules[] = 'RewriteRule .* - [E=Cache-Control:no-cache]' ;
646
+ $new_rules[] = self::MARKER_NOCACHE_COOKIES . self::MARKER_END ;
647
+ $new_rules[] = '' ;
648
+ }
649
+
650
+ // nocache user agents
651
+ $id = LiteSpeed_Cache_Config::ID_NOCACHE_USERAGENTS ;
652
+ if ( isset($diff[$id]) && $diff[$id] ) {
653
+ $new_rules[] = self::MARKER_NOCACHE_USER_AGENTS . self::MARKER_START ;
654
+ $new_rules[] = 'RewriteCond %{HTTP_USER_AGENT} ' . $diff[$id] ;
655
+ $new_rules[] = 'RewriteRule .* - [E=Cache-Control:no-cache]' ;
656
+ $new_rules[] = self::MARKER_NOCACHE_USER_AGENTS . self::MARKER_END ;
657
+ $new_rules[] = '' ;
658
+ }
659
+
660
+ // caching php resource
661
+ $id = LiteSpeed_Cache_Config::OPID_CACHE_RES ;
662
+ if ( isset($diff[$id]) && $diff[$id] ) {
663
+ $new_rules[] = $new_rules_backend[] = self::MARKER_CACHE_RESOURCE . self::MARKER_START ;
664
+ $new_rules[] = $new_rules_backend[] = 'RewriteRule ' . self::RW_PATTERN_RES . ' - [E=cache-control:max-age=3600]' ;
665
+ $new_rules[] = $new_rules_backend[] = self::MARKER_CACHE_RESOURCE . self::MARKER_END ;
666
+ $new_rules[] = $new_rules_backend[] = '' ;
667
+ }
668
+
669
+ // login cookie
670
+ // frontend and backend
671
+ $id = LiteSpeed_Cache_Config::OPID_LOGIN_COOKIE ;
672
+ if ( isset($diff[$id]) && $diff[$id] ) {
673
+ $env = 'Cache-Vary:' . $diff[$id] ;
674
+ if ( LITESPEED_SERVER_TYPE === 'LITESPEED_SERVER_OLS' ) {
675
+ $env = '"' . $env . '"' ;
676
+ }
677
+ $new_rules[] = $new_rules_backend[] = self::MARKER_LOGIN_COOKIE . self::MARKER_START ;
678
+ $new_rules[] = $new_rules_backend[] = 'RewriteRule .? - [E=' . $env . ']' ;
679
+ $new_rules[] = $new_rules_backend[] = self::MARKER_LOGIN_COOKIE . self::MARKER_END ;
680
+ $new_rules[] = '' ;
681
+ }
682
+
683
+ // favicon
684
+ // frontend and backend
685
+ $id = LiteSpeed_Cache_Config::OPID_CACHE_FAVICON ;
686
+ if ( isset($diff[$id]) && $diff[$id] ) {
687
+ $new_rules[] = $new_rules_backend[] = self::MARKER_FAVICON . self::MARKER_START ;
688
+ $new_rules[] = $new_rules_backend[] = 'RewriteRule favicon\.ico$ - [E=cache-control:max-age=86400]' ;
689
+ $new_rules[] = $new_rules_backend[] = self::MARKER_FAVICON . self::MARKER_END ;
690
+ $new_rules[] = '' ;
691
+ }
692
+
693
+ // todo: is this still needed?
694
+ // if (!is_null($haystack)) {
695
+ // if ( LITESPEED_SERVER_TYPE !== 'LITESPEED_SERVER_OLS' ) {
696
+ // $haystack = str_replace(self::RW_LOOKUP_PUBLIC,
697
+ // self::RW_LOOKUP_BOTH, $haystack) ;
698
+ // }
699
+ // $beginning .= $haystack ;
700
+ // }
701
+
702
+ $this->deprecated_clear_rules() ;
703
+ if ( ! $this->insert_wrapper($new_rules) ) {
704
+ $errors[] = LiteSpeed_Cache_Admin_Display::get_error(LiteSpeed_Cache_Admin_Error::E_HTA_W) ;
705
+ $errors[] = $this->rewrite_codes_msg( $this->frontend_htaccess, $new_rules ) ;
706
+ return false ;
707
+ }
708
+ if ( $this->frontend_htaccess !== $this->backend_htaccess ) {
709
+ if ( ! $this->insert_wrapper($new_rules_backend, 'backend') ) {
710
+ $errors[] = LiteSpeed_Cache_Admin_Display::get_error(LiteSpeed_Cache_Admin_Error::E_HTA_W) ;
711
+ $errors[] = $this->rewrite_codes_msg( $this->backend_htaccess, $new_rules ) ;
712
+ return false ;
713
+ }
714
+ }
715
+ return $diff ;
716
+ }
717
+
718
+ /**
719
+ * Output the msg with rules plain data for manual insert
720
+ *
721
+ * @since 1.1.5
722
+ * @param string $file
723
+ * @param array $rules
724
+ * @return string final msg to output
725
+ */
726
+ private function rewrite_codes_msg( $file, $rules )
727
+ {
728
+ return sprintf( __( '<p>Please add/replace the following codes into the beginning of %1$s:</p> %2$s' , 'litespeed-cache' ),
729
+ $file,
730
+ '<textarea style="width:100%;" rows="10" readonly>' . htmlspecialchars( $this->wrap_rules_with_marker( $rules ) ) . '</textarea>'
731
+ ) ;
732
+ }
733
+
734
+ /**
735
+ * Generate rules plain data for manual insert
736
+ *
737
+ * @since 1.1.5
738
+ * @param array $rules
739
+ * @return array final rules data for htaccess
740
+ */
741
+ private function wrap_rules_with_marker( $rules )
742
+ {
743
+ $marker = self::MARKER ;
744
+ $start_marker = "# BEGIN {$marker}" ;
745
+ $end_marker = "# END {$marker}" ;
746
+ $new_file_data = implode( "\n", array_merge(
747
+ array( $start_marker ),
748
+ $this->wrap_rules($rules),
749
+ array( $end_marker )
750
+ ) ) ;
751
+
752
+ return $new_file_data ;
753
+ }
754
+
755
+ /**
756
+ * wrap rules with module on info
757
+ *
758
+ * @since 1.1.5
759
+ * @param array $rules
760
+ * @return array wrapped rules with module info
761
+ */
762
+ private function wrap_rules( $rules )
763
+ {
764
+ if ( $rules !== false ) {
765
+ $rules = array_merge(
766
+ array(self::LS_MODULE_DONOTEDIT),
767
+ array(self::LS_MODULE_START),
768
+ array(self::$LS_MODULE_REWRITE_ON),
769
+ array(''),
770
+ $rules,
771
+ array(self::LS_MODULE_END),
772
+ array(self::LS_MODULE_DONOTEDIT)
773
+ ) ;
774
+ }
775
+ return $rules ;
776
+ }
777
+
778
+ /**
779
+ * Write to htaccess with rules
780
+ *
781
+ * @since 1.1.0
782
+ * @param array $rules
783
+ * @param string $kind which htaccess
784
+ */
785
+ public function insert_wrapper( $rules = array(), $kind = 'frontend' )
786
+ {
787
+ $res = $this->htaccess_backup( $kind ) ;
788
+ if ( ! $res ) {
789
+ return false ;
790
+ }
791
+
792
+ return Litespeed_File::insert_with_markers( $this->htaccess_path($kind), $this->wrap_rules( $rules ), self::MARKER, true ) ;
793
+ }
794
+
795
+ /**
796
+ * Clear the rules file of any changes added by the plugin specifically.
797
+ *
798
+ * @since 1.0.4
799
+ * @access public
800
+ */
801
+ public function clear_rules( $clear_all = false )
802
+ {
803
+ $keep_wrapper = $clear_all === true ? false : array() ;
804
+ $this->deprecated_clear_rules() ;
805
+ $this->insert_wrapper( $keep_wrapper ) ;
806
+ if ( $this->frontend_htaccess !== $this->backend_htaccess ) {
807
+ $this->insert_wrapper( $keep_wrapper, 'backend' ) ;
808
+ }
809
+ }
810
+
811
+ /**
812
+ * Only used to clear old rules when upgrade to v1.1.0
813
+ */
814
+ public function deprecated_clear_rules()
815
+ {
816
+ $RW_WRAPPER = 'PLUGIN - Do not edit the contents of this block!' ;
817
+ $pattern = '/###LSCACHE START ' . $RW_WRAPPER . '###.*###LSCACHE END ' . $RW_WRAPPER . '###\n?/s' ;
818
+ clearstatcache() ;
819
+ if ( ! file_exists($this->frontend_htaccess) || ! self::writable() ) {
820
+ return ;
821
+ }
822
+ $content = file_get_contents($this->frontend_htaccess) ;
823
+ if( ! $content ) {
824
+ return ;
825
+ }
826
+
827
+ $buf = preg_replace($pattern, '', $content) ;
828
+ $buf = preg_replace("|<IfModule LiteSpeed>\s*</IfModule>|isU", '', $buf) ;
829
+
830
+ $this->htaccess_save($buf) ;
831
+
832
+ // clear backend htaccess
833
+ if ( $this->frontend_htaccess === $this->backend_htaccess ) {
834
+ return ;
835
+ }
836
+
837
+ if ( ! file_exists($this->backend_htaccess) || ! self::writable('backend') ) {
838
+ return ;
839
+ }
840
+ $content = file_get_contents($this->backend_htaccess) ;
841
+ if( ! $content ) {
842
+ return ;
843
+ }
844
+
845
+ $buf = preg_replace($pattern, '', $content) ;
846
+ $buf = preg_replace("|<IfModule LiteSpeed>\n*</IfModule>|isU", '', $buf) ;
847
+ $this->htaccess_save($buf, 'backend') ;
848
+ }
849
+
850
+ /**
851
+ * Parses the .htaccess buffer when the admin saves changes in the edit .htaccess page.
852
+ * Only admin can do this
853
+ *
854
+ * @since 1.0.4
855
+ * @access public
856
+ */
857
+ public function htaccess_editor_save()
858
+ {
859
+ if ( isset($_POST[self::EDITOR_TEXTAREA_NAME]) ) {
860
+ $content = LiteSpeed_Cache_Admin::cleanup_text($_POST[self::EDITOR_TEXTAREA_NAME]) ;
861
+ $msg = $this->htaccess_save($content) ;
862
+ if ( $msg === true ) {
863
+ $msg = __('File Saved.', 'litespeed-cache') ;
864
+ $color = LiteSpeed_Cache_Admin_Display::NOTICE_GREEN ;
865
+ }
866
+ else {
867
+ $color = LiteSpeed_Cache_Admin_Display::NOTICE_RED ;
868
+ }
869
+ LiteSpeed_Cache_Admin_Display::add_notice($color, $msg) ;
870
+ }
871
+
872
+ }
873
+
874
+ /**
875
+ * Get the current instance object.
876
+ *
877
+ * @since 1.1.0
878
+ * @access public
879
+ * @return Current class instance.
880
+ */
881
+ public static function get_instance()
882
+ {
883
+ $cls = get_called_class() ;
884
+ if ( ! isset(self::$_instance) ) {
885
+ self::$_instance = new $cls() ;
886
+ }
887
+
888
+ return self::$_instance ;
889
+ }
890
+ }
891
+
admin/litespeed-cache-admin-settings.class.php ADDED
@@ -0,0 +1,910 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The admin settings handler of the plugin.
4
+ *
5
+ *
6
+ * @since 1.1.0
7
+ * @package LiteSpeed_Cache
8
+ * @subpackage LiteSpeed_Cache/admin
9
+ * @author LiteSpeed Technologies <info@litespeedtech.com>
10
+ */
11
+ class LiteSpeed_Cache_Admin_Settings
12
+ {
13
+ private static $_instance ;
14
+
15
+ /**
16
+ * Helper function to validate TTL settings. Will check if it's set,
17
+ * is an integer, and is greater than 0 and less than INT_MAX.
18
+ *
19
+ * @since 1.0.12
20
+ * @access public
21
+ * @param array $input Input array
22
+ * @param string $id Option ID
23
+ * @param number $min Minimum number
24
+ * @param number $max Maximum number
25
+ * @return bool True if valid, false otherwise.
26
+ */
27
+ public function validate_ttl($input, $id, $min = false, $max = 2147483647)
28
+ {
29
+ if ( ! isset($input[ $id ]) ) {
30
+ return false ;
31
+ }
32
+
33
+ $val = $input[ $id ] ;
34
+
35
+ $ival = intval($val) ;
36
+ $sval = strval($val) ;
37
+
38
+ if( $min && $ival < $min ) {
39
+ return false ;
40
+ }
41
+
42
+ return ctype_digit($sval) && $ival >= 0 && $ival < $max ;
43
+ }
44
+
45
+ /**
46
+ * Hooked to the wp_redirect filter.
47
+ * This will only hook if there was a problem when saving the widget.
48
+ *
49
+ * @since 1.1.3
50
+ * @access public
51
+ * @param string $location The location string.
52
+ * @return string the updated location string.
53
+ */
54
+ public static function widget_save_err($location)
55
+ {
56
+ return str_replace('?message=0', '?error=0', $location) ;
57
+ }
58
+
59
+ /**
60
+ * Hooked to the widget_update_callback filter.
61
+ * Validate the LiteSpeed Cache settings on edit widget save.
62
+ *
63
+ * @since 1.1.3
64
+ * @access public
65
+ * @param array $instance The new settings.
66
+ * @param array $new_instance
67
+ * @param array $old_instance The original settings.
68
+ * @param WP_Widget $widget The widget
69
+ * @return mixed Updated settings on success, false on error.
70
+ */
71
+ public static function validate_widget_save($instance, $new_instance, $old_instance, $widget)
72
+ {
73
+ if ( empty($_POST[LiteSpeed_Cache_Config::OPTION_NAME]) ) {
74
+ return $instance ;
75
+ }
76
+ $current = ! empty($old_instance[LiteSpeed_Cache_Config::OPTION_NAME]) ? $old_instance[LiteSpeed_Cache_Config::OPTION_NAME] : false ;
77
+ $input = $_POST[LiteSpeed_Cache_Config::OPTION_NAME] ;
78
+ $esistr = $input[LiteSpeed_Cache_ESI::WIDGET_OPID_ESIENABLE] ;
79
+ $ttlstr = $input[LiteSpeed_Cache_ESI::WIDGET_OPID_TTL] ;
80
+
81
+ if ( ! is_numeric($ttlstr) || ! is_numeric($esistr) ) {
82
+ add_filter('wp_redirect', 'LiteSpeed_Cache_Admin_Settings::widget_save_err') ;
83
+ return false ;
84
+ }
85
+
86
+ $esi = self::is_checked($esistr) ;
87
+ $ttl = intval($ttlstr) ;
88
+
89
+ if ( $ttl != 0 && $ttl < 30 ) {
90
+ add_filter('wp_redirect', 'LiteSpeed_Cache_Admin_Settings::widget_save_err') ;
91
+ return false ; // invalid ttl.
92
+ }
93
+
94
+ if ( empty($instance[LiteSpeed_Cache_Config::OPTION_NAME]) ) {
95
+ $instance[LiteSpeed_Cache_Config::OPTION_NAME] = array() ;
96
+ }
97
+ $instance[LiteSpeed_Cache_Config::OPTION_NAME][LiteSpeed_Cache_ESI::WIDGET_OPID_ESIENABLE] = $esi ;
98
+ $instance[LiteSpeed_Cache_Config::OPTION_NAME][LiteSpeed_Cache_ESI::WIDGET_OPID_TTL] = $ttl ;
99
+
100
+ if ( ! $current || $esi != $current[LiteSpeed_Cache_ESI::WIDGET_OPID_ESIENABLE] ) {
101
+ LiteSpeed_Cache_Purge::purge_all() ;
102
+ }
103
+ elseif ( $ttl != 0 && $ttl != $current[LiteSpeed_Cache_ESI::WIDGET_OPID_TTL] ) {
104
+ LiteSpeed_Cache_Purge::add(LiteSpeed_Cache_Tag::TYPE_WIDGET . $widget->id) ;
105
+ }
106
+
107
+ LiteSpeed_Cache_Purge::purge_all() ;
108
+ return $instance ;
109
+ }
110
+
111
+ /**
112
+ * Validates the general settings.
113
+ *
114
+ * @since 1.0.12
115
+ * @access private
116
+ * @param array $input The input options.
117
+ * @param array $options The current options.
118
+ * @param array $errors The errors list.
119
+ */
120
+ private function validate_general( &$input, &$options, &$errors )
121
+ {
122
+ $num_err = LiteSpeed_Cache_Admin_Display::get_error(LiteSpeed_Cache_Admin_Error::E_SETTING_NUMERIC) ;
123
+ $max_ttl = 2147483647 ;
124
+
125
+ // enabled setting
126
+ $id = LiteSpeed_Cache_Config::OPID_ENABLED_RADIO ;
127
+ if( ! isset($input[ $id ]) ) {
128
+ $enabled = 0 ;
129
+ }
130
+ else {
131
+ $options[ $id ] = self::is_checked_radio($input[ $id ]) ;
132
+
133
+ if( $options[ $id ] !== LiteSpeed_Cache_Config::VAL_NOTSET ){
134
+ $enabled = $options[ $id ] ;
135
+ }
136
+ else{
137
+ if ( is_multisite() ) {
138
+ $enabled = $options[LiteSpeed_Cache_Config::NETWORK_OPID_ENABLED] ;
139
+ }
140
+ else{
141
+ $enabled = LiteSpeed_Cache_Config::VAL_ON ;
142
+ }
143
+ }
144
+ }
145
+
146
+ // $enabled temporary variable
147
+ $id = LiteSpeed_Cache_Config::OPID_ENABLED ;
148
+ if ( $enabled !== $options[ $id ] ) {
149
+ $options[ $id ] = $enabled ;
150
+ $ret = LiteSpeed_Cache_Config::wp_cache_var_setter($enabled) ;
151
+ if ( $ret !== true ) {
152
+ $errors[] = $ret ;
153
+ }
154
+ if ( ! $enabled ) {
155
+ LiteSpeed_Cache_Purge::purge_all() ;
156
+ }
157
+ elseif ( $options[LiteSpeed_Cache_Config::OPID_CACHE_FAVICON] ) {
158
+ $options[LiteSpeed_Cache_Config::OPID_CACHE_FAVICON] = false ;
159
+ }
160
+ $input[ $id ] = 'changed' ;
161
+ }
162
+ else {
163
+ $input[ $id ] = $enabled ;
164
+ }
165
+
166
+ $id = LiteSpeed_Cache_Config::OPID_PUBLIC_TTL ;
167
+ if ( ! $this->validate_ttl($input, $id, 30) ) {
168
+ $errors[] = sprintf($num_err, __('Default Public Cache', 'litespeed-cache'), 30, $max_ttl) ;
169
+ }
170
+ else {
171
+ $options[ $id ] = $input[ $id ] ;
172
+ }
173
+
174
+ $id = LiteSpeed_Cache_Config::OPID_FRONT_PAGE_TTL ;
175
+ if ( ! $this->validate_ttl($input, $id, 30) ) {
176
+ $errors[] = sprintf($num_err, __('Default Front Page', 'litespeed-cache'), 30, $max_ttl) ;
177
+ }
178
+ else {
179
+ $options[ $id ] = $input[ $id ] ;
180
+ }
181
+
182
+ $id = LiteSpeed_Cache_Config::OPID_FEED_TTL ;
183
+ if ( ! $this->validate_ttl($input, $id) ) {
184
+ $errors[] = sprintf($num_err, __('Feed', 'litespeed-cache'), 0, $max_ttl) ;
185
+ }
186
+ elseif ( $input[ $id ] < 30 ) {
187
+ $options[ $id ] = 0 ;
188
+ }
189
+ else {
190
+ $options[ $id ] = intval($input[ $id ]) ;
191
+ }
192
+
193
+ $id = LiteSpeed_Cache_Config::OPID_404_TTL ;
194
+ if ( ! $this->validate_ttl($input, $id) ) {
195
+ $errors[] = sprintf($num_err, __('404', 'litespeed-cache'), 0, $max_ttl) ;
196
+ }
197
+ elseif ( $input[ $id ] < 30 ) {
198
+ $options[ $id ] = 0 ;
199
+ }
200
+ else {
201
+ $options[ $id ] = intval($input[ $id ]) ;
202
+ }
203
+
204
+ $id = LiteSpeed_Cache_Config::OPID_403_TTL ;
205
+ if ( ! $this->validate_ttl($input, $id) ) {
206
+ $errors[] = sprintf($num_err, __('403', 'litespeed-cache'), 0, $max_ttl) ;
207
+ }
208
+ elseif ( $input[ $id ] < 30 ) {
209
+ $options[ $id ] = 0 ;
210
+ }
211
+ else {
212
+ $options[ $id ] = intval($input[ $id ]) ;
213
+ }
214
+
215
+ $id = LiteSpeed_Cache_Config::OPID_500_TTL ;
216
+ if ( ! $this->validate_ttl($input, $id) ) {
217
+ $errors[] = sprintf($num_err, __('500', 'litespeed-cache'), 0, $max_ttl) ;
218
+ }
219
+ elseif ( $input[ $id ] < 30 ) {
220
+ $options[ $id ] = 0 ;
221
+ }
222
+ else {
223
+ $options[ $id ] = intval($input[ $id ]) ;
224
+ }
225
+
226
+ }
227
+
228
+ /**
229
+ * Validates the cache control settings.
230
+ *
231
+ * @since 1.1.6
232
+ * @access private
233
+ * @param array $input The input options.
234
+ * @param array $options The current options.
235
+ * @param array $errors The errors list.
236
+ */
237
+ private function validate_cache( &$input, &$options, &$errors )
238
+ {
239
+ $id = LiteSpeed_Cache_Config::OPID_CACHE_PRIV ;
240
+ $options[ $id ] = self::parse_onoff( $input, $id ) ;
241
+
242
+ $id = LiteSpeed_Cache_Config::OPID_CACHE_COMMENTER ;
243
+ $options[ $id ] = self::parse_onoff( $input, $id ) ;
244
+
245
+ $id = LiteSpeed_Cache_Config::OPID_CACHE_REST ;
246
+ $options[ $id ] = self::parse_onoff( $input, $id ) ;
247
+
248
+ $id = LiteSpeed_Cache_Config::OPID_CACHE_PAGE_LOGIN ;
249
+ $options[ $id ] = self::parse_onoff( $input, $id ) ;
250
+ if( ! $options[ $id ] ) {
251
+ LiteSpeed_Cache_Purge::add(LiteSpeed_Cache_Tag::TYPE_LOGIN) ;
252
+ }
253
+ }
254
+
255
+ /**
256
+ * Validates the purge settings.
257
+ *
258
+ * @since 1.0.12
259
+ * @access private
260
+ * @param array $input The input options.
261
+ * @param array $options The current options.
262
+ * @param array $errors The errors list.
263
+ */
264
+ private function validate_purge( $input, &$options, &$errors )
265
+ {
266
+ $id = LiteSpeed_Cache_Config::OPID_PURGE_ON_UPGRADE ;
267
+ $options[ $id ] = self::parse_onoff( $input, $id ) ;
268
+
269
+ // get auto purge rules options
270
+ $pvals = array(
271
+ LiteSpeed_Cache_Config::PURGE_ALL_PAGES,
272
+ LiteSpeed_Cache_Config::PURGE_FRONT_PAGE,
273
+ LiteSpeed_Cache_Config::PURGE_HOME_PAGE,
274
+ LiteSpeed_Cache_Config::PURGE_PAGES,
275
+ LiteSpeed_Cache_Config::PURGE_PAGES_WITH_RECENT_POSTS,
276
+ LiteSpeed_Cache_Config::PURGE_AUTHOR,
277
+ LiteSpeed_Cache_Config::PURGE_YEAR,
278
+ LiteSpeed_Cache_Config::PURGE_MONTH,
279
+ LiteSpeed_Cache_Config::PURGE_DATE,
280
+ LiteSpeed_Cache_Config::PURGE_TERM,
281
+ LiteSpeed_Cache_Config::PURGE_POST_TYPE,
282
+ ) ;
283
+ $input_purge_options = array() ;
284
+ foreach ($pvals as $pval) {
285
+ $input_name = 'purge_' . $pval ;
286
+ if ( self::parse_onoff( $input, $input_name ) ) {
287
+ $input_purge_options[] = $pval ;
288
+ }
289
+ }
290
+ sort( $input_purge_options ) ;
291
+ $purge_by_post = implode( '.', $input_purge_options ) ;
292
+ if ( $purge_by_post !== $options[ LiteSpeed_Cache_Config::OPID_PURGE_BY_POST ] ) {
293
+ $options[ LiteSpeed_Cache_Config::OPID_PURGE_BY_POST ] = $purge_by_post ;
294
+ }
295
+
296
+ // Filter scheduled purge URLs
297
+ $id = LiteSpeed_Cache_Config::OPID_TIMED_URLS ;
298
+ $options[ $id ] = '' ;
299
+ if ( isset( $input[ $id ] ) ) {
300
+ if ( ! empty( $input[ $id ] ) ) {
301
+ $list = array() ;
302
+ foreach ( explode( "\n", $input[ $id ] ) as $val ) {
303
+ $val = LiteSpeed_Cache_Utility::make_relative( $val ) ;
304
+ if ( $val ) {
305
+ $list[] = $val ;
306
+ }
307
+ }
308
+ if ( $list ) {
309
+ $options[ $id ] = implode( "\n", $list ) ;
310
+ }
311
+ }
312
+ }
313
+
314
+ // Schduled Purge Time
315
+ $id = LiteSpeed_Cache_Config::OPID_TIMED_URLS_TIME ;
316
+ $options[ $id ] = $input[ $id ] ;
317
+ }
318
+
319
+ /**
320
+ * Validates the exclude settings.
321
+ *
322
+ * @since 1.0.12
323
+ * @access private
324
+ * @param array $input The input options.
325
+ * @param array $options The current options.
326
+ * @param array $errors The errors list.
327
+ */
328
+ private function validate_exclude($input, &$options, &$errors)
329
+ {
330
+ $id = LiteSpeed_Cache_Config::OPID_EXCLUDES_URI ;
331
+ if ( isset($input[ $id ]) ) {
332
+ $uri_arr = array_map('trim', explode("\n", $input[ $id ])) ;
333
+ $options[ $id ] = implode("\n", array_filter($uri_arr)) ;
334
+ }
335
+
336
+ $id = LiteSpeed_Cache_Config::OPID_EXCLUDES_CAT ;
337
+ $options[ $id ] = '' ;
338
+ if ( isset($input[ $id ]) ) {
339
+ $cat_ids = array() ;
340
+ $cats = explode("\n", $input[ $id ]) ;
341
+ foreach ($cats as $cat) {
342
+ $cat_name = trim($cat) ;
343
+ if ( $cat_name == '' ) {
344
+ continue ;
345
+ }
346
+ $cat_id = get_cat_ID($cat_name) ;
347
+ if ( $cat_id == 0 ) {
348
+ $errors[] = LiteSpeed_Cache_Admin_Display::get_error(LiteSpeed_Cache_Admin_Error::E_SETTING_CAT, $cat_name) ;
349
+ }
350
+ else {
351
+ $cat_ids[] = $cat_id ;
352
+ }
353
+ }
354
+ if ( ! empty($cat_ids) ) {
355
+ $options[ $id ] = implode(',', $cat_ids) ;
356
+ }
357
+ }
358
+
359
+ $id = LiteSpeed_Cache_Config::OPID_EXCLUDES_TAG ;
360
+ $options[ $id ] = '' ;
361
+ if ( isset($input[ $id ]) ) {
362
+ $tag_ids = array() ;
363
+ $tags = explode("\n", $input[ $id ]) ;
364
+ foreach ($tags as $tag) {
365
+ $tag_name = trim($tag) ;
366
+ if ( $tag_name == '' ) {
367
+ continue ;
368
+ }
369
+ $term = get_term_by('name', $tag_name, 'post_tag') ;
370
+ if ( $term == 0 ) {
371
+ $errors[] = LiteSpeed_Cache_Admin_Display::get_error(LiteSpeed_Cache_Admin_Error::E_SETTING_TAG, $tag_name) ;
372
+ }
373
+ else {
374
+ $tag_ids[] = $term->term_id ;
375
+ }
376
+ }
377
+ if ( ! empty($tag_ids) ) {
378
+ $options[ $id ] = implode(',', $tag_ids) ;
379
+ }
380
+ }
381
+ }
382
+
383
+ /**
384
+ * Validates the single site specific settings.
385
+ *
386
+ * @since 1.0.12
387
+ * @access private
388
+ * @param array $input The input options.
389
+ * @param array $options The current options.
390
+ * @param array $errors The errors list.
391
+ */
392
+ private function validate_singlesite($input, &$options, &$errors)
393
+ {
394
+ $rules = LiteSpeed_Cache_Admin_Rules::get_instance() ;
395
+
396
+ $id = LiteSpeed_Cache_Config::OPID_ENABLED ;
397
+ if ( $input[ $id ] !== 'changed' ) {
398
+ $diff = $rules->check_input_for_rewrite($options, $input, $errors) ;
399
+ }
400
+ elseif ( $options[ $id ] ) {
401
+ $reset = LiteSpeed_Cache_Config::get_rule_reset_options() ;
402
+ $added_and_changed = $rules->check_input_for_rewrite($reset, $input, $errors) ;
403
+ // Merge to include the newly disabled options
404
+ $diff = array_merge($reset, $added_and_changed) ;
405
+ }
406
+ else {
407
+ $rules->clear_rules() ;
408
+ $diff = $rules->check_input_for_rewrite($options, $input, $errors) ;
409
+ }
410
+
411
+ if ( ! empty($diff) && ($options[ $id ] == false || $rules->validate_common_rewrites($diff, $errors) !== false) ) {//todo: check if need to use ===
412
+ $options = array_merge($options, $diff) ;
413
+ }
414
+
415
+ $id = LiteSpeed_Cache_Config::OPID_CHECK_ADVANCEDCACHE ;
416
+ $options[ $id ] = self::parse_onoff( $input, $id ) ;
417
+ }
418
+
419
+ /**
420
+ * Validates the debug settings.
421
+ *
422
+ * @since 1.0.12
423
+ * @access private
424
+ * @param array $input The input options.
425
+ * @param array $options The current options.
426
+ * @param array $errors The errors list.
427
+ */
428
+ private function validate_debug($input, &$options, &$errors)
429
+ {
430
+ $num_err = LiteSpeed_Cache_Admin_Display::get_error(LiteSpeed_Cache_Admin_Error::E_SETTING_NUMERIC) ;
431
+
432
+ $id = LiteSpeed_Cache_Config::OPID_ADMIN_IPS ;
433
+ if ( isset($input[ $id ]) ) {
434
+ $admin_ips = array_map('trim', explode("\n", trim($input[ $id ]))) ;
435
+ $admin_ips = array_filter($admin_ips) ;
436
+ $has_err = false ;
437
+ if ( $admin_ips ) {
438
+ foreach ($admin_ips as $ip) {
439
+ if ( ! WP_Http::is_ip_address($ip) ) {
440
+ $has_err = true ;
441
+ break ;
442
+ }
443
+ }
444
+ }
445
+ $admin_ips = implode("\n", $admin_ips) ;
446
+
447
+ if ( $has_err ) {
448
+ $errors[] = LiteSpeed_Cache_Admin_Display::get_error(LiteSpeed_Cache_Admin_Error::E_SETTING_ADMIN_IP_INV) ;
449
+ }
450
+ elseif ( $admin_ips != $options[ $id ] ) {
451
+ $options[ $id ] = $admin_ips ;
452
+ }
453
+ }
454
+
455
+ $id = LiteSpeed_Cache_Config::OPID_TEST_IPS ;
456
+ if ( isset($input[ $id ]) ) {
457
+ // this feature has not implemented yet
458
+ $test_ips = array_map('trim', explode("\n", trim($input[ $id ]))) ;
459
+ $test_ips = array_filter($test_ips) ;
460
+ $has_err = false ;
461
+ if ( $test_ips ) {
462
+ foreach ($test_ips as $ip) {
463
+ if ( ! WP_Http::is_ip_address($ip) ) {
464
+ $has_err = true ;
465
+ break ;
466
+ }
467
+ }
468
+ }
469
+ $test_ips = implode("\n", $test_ips) ;
470
+
471
+ if ( $has_err ) {
472
+ $errors[] = LiteSpeed_Cache_Admin_Display::get_error(LiteSpeed_Cache_Admin_Error::E_SETTING_TEST_IP_INV) ;
473
+ }
474
+ elseif ( $test_ips != $options[ $id ] ) {
475
+ $options[ $id ] = $test_ips ;
476
+ }
477
+ }
478
+
479
+ $id = LiteSpeed_Cache_Config::OPID_DEBUG ;
480
+ $debug_level = self::is_checked_radio($input[ $id ]) ;
481
+ if ( $debug_level != $options[ $id ] ){
482
+ $options[ $id ] = $debug_level ;
483
+ }
484
+
485
+ $id = LiteSpeed_Cache_Config::OPID_DEBUG_LEVEL ;
486
+ $options[ $id ] = self::parse_onoff( $input, $id ) ;
487
+
488
+ $id = LiteSpeed_Cache_Config::OPID_LOG_FILE_SIZE ;
489
+ if ( ! $this->validate_ttl( $input, $id, 3, 3000 ) ) {
490
+ $errors[] = sprintf( $num_err, __( 'Log File Size Limit', 'litespeed-cache' ), 3, 3000 ) ;
491
+ }
492
+ else {
493
+ $options[ $id ] = $input[ $id ] ;
494
+ }
495
+
496
+ $id = LiteSpeed_Cache_Config::OPID_HEARTBEAT ;
497
+ $options[ $id ] = self::parse_onoff( $input, $id ) ;
498
+
499
+ $id = LiteSpeed_Cache_Config::OPID_DEBUG_COOKIE ;
500
+ $options[ $id ] = self::parse_onoff( $input, $id ) ;
501
+
502
+ $id = LiteSpeed_Cache_Config::OPID_COLLAPS_QS ;
503
+ $options[ $id ] = self::parse_onoff( $input, $id ) ;
504
+
505
+ $id = LiteSpeed_Cache_Config::OPID_LOG_FILTERS ;
506
+ $options[ $id ] = self::parse_onoff( $input, $id ) ;
507
+
508
+ $id = LiteSpeed_Cache_Config::OPID_LOG_IGNORE_FILTERS ;
509
+ if ( isset( $input[ $id ] ) ) {
510
+ $items = array_map( 'trim', explode( "\n", trim( $input[ $id ] ) ) ) ;
511
+ $items = implode( "\n", array_filter( $items ) ) ;
512
+ $options[ $id ] = $items ;
513
+ }
514
+
515
+ $id = LiteSpeed_Cache_Config::OPID_LOG_IGNORE_PART_FILTERS ;
516
+ if ( isset( $input[ $id ] ) ) {
517
+ $items = array_map( 'trim', explode( "\n", trim( $input[ $id ] ) ) ) ;
518
+ $items = implode( "\n", array_filter( $items ) ) ;
519
+ $options[ $id ] = $items ;
520
+ }
521
+
522
+ }
523
+
524
+ /**
525
+ * Validates the crawler settings.
526
+ *
527
+ * @since 1.0.12
528
+ * @access private
529
+ * @param array $input The input options.
530
+ * @param array $options The current options.
531
+ * @param array $errors The errors list.
532
+ */
533
+ private function validate_crawler($input, &$options, &$errors)
534
+ {
535
+ $num_err = LiteSpeed_Cache_Admin_Display::get_error(LiteSpeed_Cache_Admin_Error::E_SETTING_NUMERIC) ;
536
+
537
+ $id = LiteSpeed_Cache_Config::CRWL_POSTS ;
538
+ $options[ $id ] = self::parse_onoff( $input, $id ) ;
539
+
540
+ $id = LiteSpeed_Cache_Config::CRWL_PAGES ;
541
+ $options[ $id ] = self::parse_onoff( $input, $id ) ;
542
+
543
+ $id = LiteSpeed_Cache_Config::CRWL_CATS ;
544
+ $options[ $id ] = self::parse_onoff( $input, $id ) ;
545
+
546
+ $id = LiteSpeed_Cache_Config::CRWL_TAGS ;
547
+ $options[ $id ] = self::parse_onoff( $input, $id ) ;
548
+
549
+ $id = LiteSpeed_Cache_Config::CRWL_EXCLUDES_CPT ;
550
+ if ( isset($input[ $id ]) ) {
551
+ $arr = array_map('trim', explode("\n", $input[ $id ])) ;
552
+ $arr = array_filter($arr) ;
553
+ $ori = array_diff(get_post_types( '', 'names' ), array('post', 'page')) ;
554
+ $options[ $id ] = implode("\n", array_intersect($arr, $ori)) ;
555
+ }
556
+
557
+ $id = LiteSpeed_Cache_Config::CRWL_ORDER_LINKS ;
558
+ if( ! isset($input[ $id ]) || ! in_array($input[ $id ], array(
559
+ LiteSpeed_Cache_Config::CRWL_DATE_DESC,
560
+ LiteSpeed_Cache_Config::CRWL_DATE_ASC,
561
+ LiteSpeed_Cache_Config::CRWL_ALPHA_DESC,
562
+ LiteSpeed_Cache_Config::CRWL_ALPHA_ASC,
563
+ )) ) {
564
+ $input[ $id ] = LiteSpeed_Cache_Config::CRWL_DATE_DESC ;
565
+ }
566
+ $options[ $id ] = $input[ $id ] ;
567
+
568
+ $id = LiteSpeed_Cache_Config::CRWL_USLEEP ;
569
+ if ( ! $this->validate_ttl($input, $id, 0, 30000) ) {
570
+ $errors[] = sprintf($num_err, __('Delay', 'litespeed-cache'), 0, 30000) ;
571
+ }
572
+ else {
573
+ $options[ $id ] = $input[ $id ] ;
574
+ }
575
+
576
+ $id = LiteSpeed_Cache_Config::CRWL_RUN_DURATION ;
577
+ if ( ! $this->validate_ttl($input, $id) ) {
578
+ $errors[] = sprintf($num_err, __('Run Duration', 'litespeed-cache'), 0, 2147483647) ;
579
+ }
580
+ else {
581
+ $options[ $id ] = $input[ $id ] ;
582
+ }
583
+
584
+ $id = LiteSpeed_Cache_Config::CRWL_RUN_INTERVAL ;
585
+ if ( ! $this->validate_ttl($input, $id, 60) ) {
586
+ $errors[] = sprintf($num_err, __('Cron Interval', 'litespeed-cache'), 60, 2147483647) ;
587
+ }
588
+ else {
589
+ $options[ $id ] = $input[ $id ] ;
590
+ }
591
+
592
+ $id = LiteSpeed_Cache_Config::CRWL_CRAWL_INTERVAL ;
593
+ if ( ! $this->validate_ttl($input, $id) ) {
594
+ $errors[] = sprintf($num_err, __('Whole Interval', 'litespeed-cache'), 0, 2147483647) ;
595
+ }
596
+ else {
597
+ $options[ $id ] = $input[ $id ] ;
598
+ }
599
+
600
+ $id = LiteSpeed_Cache_Config::CRWL_THREADS ;
601
+ if ( ! $this->validate_ttl($input, $id, 1) ) {
602
+ $errors[] = sprintf($num_err, __('Threads', 'litespeed-cache'), 1, 16) ;
603
+ }
604
+ else {
605
+ $options[ $id ] = $input[ $id ] ;
606
+ }
607
+
608
+ $id = LiteSpeed_Cache_Config::CRWL_LOAD_LIMIT ;
609
+ $options[ $id ] = $input[ $id ] ;
610
+
611
+ $id = LiteSpeed_Cache_Config::CRWL_DOMAIN_IP ;
612
+ if ( ! empty($input[ $id ]) && ! WP_Http::is_ip_address($input[ $id ]) ) {
613
+ $errors[] = LiteSpeed_Cache_Admin_Display::get_error(LiteSpeed_Cache_Admin_Error::E_SETTING_SITE_IP, $input[ $id ]) ;
614
+ }
615
+ else {
616
+ $options[ $id ] = $input[ $id ] ;
617
+ }
618
+
619
+ $id = LiteSpeed_Cache_Config::CRWL_CUSTOM_SITEMAP ;
620
+ if ( ! empty($input[ $id ]) && ($err = $this->validate_custom_sitemap($input[ $id ])) !== true ) {
621
+ $errors[] = LiteSpeed_Cache_Admin_Display::get_error($err, $input[ $id ]) ;
622
+ }
623
+ else {
624
+ $options[ $id ] = $input[ $id ] ;
625
+ }
626
+
627
+ }
628
+
629
+ /**
630
+ * Validates the custom sitemap settings.
631
+ *
632
+ * @since 1.1.1
633
+ * @access private
634
+ * @param string $url The sitemap url
635
+ */
636
+ private function validate_custom_sitemap($url)
637
+ {
638
+ return LiteSpeed_Cache_Crawler::get_instance()->parse_custom_sitemap($url, false) ;
639
+ }
640
+
641
+ /**
642
+ * Validates the third party settings.
643
+ *
644
+ * @since 1.0.12
645
+ * @access private
646
+ * @param array $input The input options.
647
+ * @param array $options The current options.
648
+ */
649
+ private function validate_thirdparty($input, $options)
650
+ {
651
+ $tp_default_options = LiteSpeed_Cache_Config::get_instance()->get_thirdparty_options() ;
652
+ if ( empty($tp_default_options) ) {
653
+ return $options ;
654
+ }
655
+ $tp_input = array_intersect_key($input, $tp_default_options) ;
656
+ if ( empty($tp_input) ) {
657
+ return $options ;
658
+ }
659
+ $tp_options = apply_filters('litespeed_cache_save_options', array_intersect_key($options, $tp_default_options), $tp_input) ;
660
+ if ( ! empty($tp_options) && is_array($tp_options) ) {
661
+ $options = array_merge($options, $tp_options) ;
662
+ }
663
+ return $options ;
664
+ }
665
+
666
+ /**
667
+ * Validates the esi settings.
668
+ *
669
+ * @since 1.1.3
670
+ * @access private
671
+ * @param array $input The input options.
672
+ * @param array $options The current options.
673
+ * @param array $errors The errors list.
674
+ */
675
+ private function validate_esi($input, &$options, &$errors)
676
+ {
677
+ $id = LiteSpeed_Cache_Config::OPID_ESI_ENABLE ;
678
+ $options[ $id ] = self::parse_onoff( $input, $id ) ;
679
+
680
+ $id = LiteSpeed_Cache_Config::OPID_ESI_CACHE ;
681
+ $options[ $id ] = self::parse_onoff( $input, $id ) ;
682
+ }
683
+
684
+ /**
685
+ * Callback function that will validate any changes made in the settings
686
+ * page.
687
+ *
688
+ * NOTE: Anytime that validate_plugin_settings is called, `convert_options_to_input` must be done first if not from option page
689
+ *
690
+ * @since 1.0.0
691
+ * @access public
692
+ * @param array $input The configuration selected by the admin when
693
+ * clicking save.
694
+ * @return array The updated configuration options.
695
+ */
696
+ public function validate_plugin_settings($input)
697
+ {
698
+ LiteSpeed_Cache_Log::debug('settings->validate_plugin_settings called') ;
699
+ $options = LiteSpeed_Cache_Config::get_instance()->get_options() ;
700
+ $errors = array() ;
701
+
702
+ if ( LiteSpeed_Cache_Admin_Display::get_instance()->get_disable_all() ) {
703
+ add_settings_error(LiteSpeed_Cache_Config::OPTION_NAME, LiteSpeed_Cache_Config::OPTION_NAME, __('\'Use primary site settings\' set by Network Administrator.', 'litespeed-cache')) ;
704
+
705
+ return $options ;
706
+ }
707
+
708
+ $this->validate_general($input, $options, $errors) ;
709
+
710
+ $this->validate_cache($input, $options, $errors) ;
711
+
712
+ $this->validate_purge($input, $options, $errors) ;
713
+
714
+ $this->validate_exclude($input, $options, $errors) ;
715
+
716
+ $this->validate_debug($input, $options, $errors) ;
717
+
718
+ if ( ! is_multisite() ) {
719
+ $this->validate_singlesite($input, $options, $errors) ;
720
+ }
721
+
722
+ if ( ! is_network_admin() ) {
723
+ $this->validate_crawler($input, $options, $errors) ;
724
+ }
725
+
726
+ if ( LSWCP_ESI_SUPPORT ) {
727
+ $orig_enabled = $options[LiteSpeed_Cache_Config::OPID_ENABLED] ;
728
+ $orig_esi_enabled = $options[LiteSpeed_Cache_Config::OPID_ESI_ENABLE] ;
729
+
730
+ $this->validate_esi($input, $options, $errors) ;
731
+
732
+ $new_enabled = $options[LiteSpeed_Cache_Config::OPID_ENABLED] ;
733
+ $new_esi_enabled = $options[LiteSpeed_Cache_Config::OPID_ESI_ENABLE] ;
734
+
735
+ if ( $orig_enabled !== $new_enabled || $orig_esi_enabled !== $new_esi_enabled ) {
736
+ LiteSpeed_Cache_Purge::purge_all() ;
737
+ }
738
+ }
739
+
740
+ if ( ! empty($errors) ) {
741
+ add_settings_error(LiteSpeed_Cache_Config::OPTION_NAME, LiteSpeed_Cache_Config::OPTION_NAME, implode('<br />', $errors)) ;
742
+
743
+ return $options ;
744
+ }
745
+
746
+ $cron_changed = false ;
747
+ if ( LiteSpeed_Cache_Router::is_cli() ) {
748
+ $id = LiteSpeed_Cache_Config::CRWL_CRON_ACTIVE ;
749
+ $cron_val = $options[ $id ] ;
750
+ // assign crawler_cron_active to $options if exists in $input separately for CLI
751
+ // This has to be specified cos crawler cron activation is not set in admin setting page
752
+ $options[ $id ] = self::parse_onoff( $input, $id ) ;
753
+ if ( $cron_val != $options[ $id ] ) {
754
+ $cron_changed = true ;
755
+ }
756
+ }
757
+
758
+ // check if need to enable crawler cron
759
+ if ( $input[LiteSpeed_Cache_Config::OPID_ENABLED] === 'changed' || $cron_changed ) {
760
+ LiteSpeed_Cache_Task::update($options) ;
761
+ }
762
+
763
+ $options = $this->validate_thirdparty($input, $options) ;
764
+
765
+ return $options ;
766
+ }
767
+
768
+ /**
769
+ * Parses any changes made by the network admin on the network settings.
770
+ *
771
+ * @since 1.0.4
772
+ * @access public
773
+ */
774
+ public function validate_network_settings()
775
+ {
776
+ $input = array_map("LiteSpeed_Cache_Admin::cleanup_text", $_POST[LiteSpeed_Cache_Config::OPTION_NAME]) ;
777
+ $options = LiteSpeed_Cache_Config::get_instance()->get_site_options() ;
778
+ $errors = array() ;
779
+
780
+ $id = LiteSpeed_Cache_Config::NETWORK_OPID_ENABLED ;
781
+ $network_enabled = self::parse_onoff( $input, $id ) ;
782
+ if ( $options[ $id ] != $network_enabled ) {
783
+ $options[ $id ] = $network_enabled ;
784
+ if ( $network_enabled ) {
785
+ $ret = LiteSpeed_Cache_Config::wp_cache_var_setter(true) ;
786
+ if ( $ret !== true ) {
787
+ $errors[] = $ret ;
788
+ }
789
+ }
790
+ else {
791
+ LiteSpeed_Cache_Purge::purge_all() ;
792
+ }
793
+ $input[ $id ] = 'changed' ;
794
+ $reset = LiteSpeed_Cache_Config::get_rule_reset_options() ;
795
+ }
796
+
797
+ $id = LiteSpeed_Cache_Config::NETWORK_OPID_USE_PRIMARY ;
798
+ $orig_primary = $options[ $id ] ;
799
+ $options[ $id ] = self::parse_onoff( $input, $id ) ;
800
+ if ( $orig_primary != $options[ $id ] ) {
801
+ LiteSpeed_Cache_Purge::purge_all() ;
802
+ }
803
+
804
+ $id = LiteSpeed_Cache_Config::OPID_PURGE_ON_UPGRADE ;
805
+ $options[ $id ] = self::parse_onoff( $input, $id ) ;
806
+
807
+ $id = LiteSpeed_Cache_Config::OPID_CHECK_ADVANCEDCACHE ;
808
+ $options[ $id ] = self::parse_onoff( $input, $id ) ;
809
+
810
+ $rules = LiteSpeed_Cache_Admin_Rules::get_instance() ;
811
+
812
+ if ( $input[LiteSpeed_Cache_Config::NETWORK_OPID_ENABLED] !== 'changed' ) {
813
+ $diff = $rules->check_input_for_rewrite($options, $input, $errors) ;
814
+ }
815
+ elseif ( $network_enabled ) {
816
+ $added_and_changed = $rules->check_input_for_rewrite($reset, $input, $errors) ;
817
+ // Merge to include the newly disabled options
818
+ $diff = array_merge($reset, $added_and_changed) ;
819
+ }
820
+ else {
821
+ $rules->validate_common_rewrites($reset, $errors) ;
822
+ $diff = $rules->check_input_for_rewrite($options, $input, $errors) ;
823
+ }
824
+
825
+ if ( ! empty($diff) && ($network_enabled === false || $rules->validate_common_rewrites($diff, $errors) !== false) ) {
826
+ $options = array_merge($options, $diff) ;
827
+ }
828
+
829
+ if ( ! empty($errors) ) {
830
+ LiteSpeed_Cache_Admin_Display::add_notice(LiteSpeed_Cache_Admin_Display::NOTICE_RED, $errors) ;
831
+ return ;
832
+ }
833
+ LiteSpeed_Cache_Admin_Display::add_notice(LiteSpeed_Cache_Admin_Display::NOTICE_GREEN, __('File saved.', 'litespeed-cache')) ;
834
+ update_site_option(LiteSpeed_Cache_Config::OPTION_NAME, $options) ;
835
+ return $options ;
836
+ }
837
+
838
+ /**
839
+ * Filter the value for checkbox via input and id (enabled/disabled)
840
+ *
841
+ * @since 1.1.6
842
+ * @access public
843
+ * @param int $input The whole input array
844
+ * @param string $id The ID of the option
845
+ * @return bool Filtered value
846
+ */
847
+ public static function parse_onoff( $input, $id )
848
+ {
849
+ return isset( $input[ $id ] ) && self::is_checked( $input[ $id ] ) ;
850
+ }
851
+
852
+ /**
853
+ * Filter the value for checkbox (enabled/disabled)
854
+ *
855
+ * @since 1.1.0
856
+ * @access public
857
+ * @param int $val The checkbox value
858
+ * @return bool Filtered value
859
+ */
860
+ public static function is_checked($val)
861
+ {
862
+ $val = intval($val) ;
863
+
864
+ if( $val === LiteSpeed_Cache_Config::VAL_ON ){
865
+ return true ;
866
+ }
867
+
868
+ return false ;
869
+ }
870
+
871
+ /**
872
+ * Filter the value for radio (enabled/disabled/notset)
873
+ *
874
+ * @since 1.1.0
875
+ * @access public
876
+ * @param int $val The radio value
877
+ * @return int Filtered value
878
+ */
879
+ public static function is_checked_radio($val)
880
+ {
881
+ $val = intval($val) ;
882
+
883
+ if( $val === LiteSpeed_Cache_Config::VAL_ON ){
884
+ return LiteSpeed_Cache_Config::VAL_ON ;
885
+ }
886
+
887
+ if( $val === LiteSpeed_Cache_Config::VAL_NOTSET ){
888
+ return LiteSpeed_Cache_Config::VAL_NOTSET ;
889
+ }
890
+
891
+ return LiteSpeed_Cache_Config::VAL_OFF ;
892
+ }
893
+
894
+ /**
895
+ * Get the current instance object.
896
+ *
897
+ * @since 1.1.0
898
+ * @access public
899
+ * @return Current class instance.
900
+ */
901
+ public static function get_instance()
902
+ {
903
+ $cls = get_called_class() ;
904
+ if ( ! isset(self::$_instance) ) {
905
+ self::$_instance = new $cls() ;
906
+ }
907
+
908
+ return self::$_instance ;
909
+ }
910
+ }
admin/litespeed-cache-admin.class.php ADDED
@@ -0,0 +1,277 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The admin-panel specific functionality of the plugin.
4
+ *
5
+ *
6
+ * @since 1.0.0
7
+ * @package LiteSpeed_Cache
8
+ * @subpackage LiteSpeed_Cache/admin
9
+ * @author LiteSpeed Technologies <info@litespeedtech.com>
10
+ */
11
+ class LiteSpeed_Cache_Admin
12
+ {
13
+ private static $_instance ;
14
+ private $config ;
15
+ private $display ;
16
+ private $main ;
17
+
18
+ /**
19
+ * Initialize the class and set its properties.
20
+ * Run in hook `after_setup_theme` when is_admin()
21
+ *
22
+ * @since 1.0.0
23
+ */
24
+ private function __construct()
25
+ {
26
+ // Additional litespeed assets on admin display
27
+ // Also register menu
28
+ $this->display = LiteSpeed_Cache_Admin_Display::get_instance() ;
29
+
30
+ $this->config = LiteSpeed_Cache_Config::get_instance() ;
31
+
32
+ if ( ! function_exists( 'is_plugin_active_for_network' ) ) {
33
+ require_once( ABSPATH . '/wp-admin/includes/plugin.php' ) ;//todo: check if needed
34
+ }
35
+
36
+ // initialize admin actions
37
+ add_action( 'admin_init', array( $this, 'admin_init' ) ) ;
38
+ // add link to plugin list page
39
+ add_filter( 'plugin_action_links_' . LSWCP_BASENAME, array( $this->display, 'add_plugin_links' ) ) ;
40
+
41
+ if ( LiteSpeed_Cache_Router::cache_enabled() ) {
42
+ // register purge_all actions
43
+ $purge_all_events = array(
44
+ 'switch_theme',
45
+ 'wp_create_nav_menu', 'wp_update_nav_menu', 'wp_delete_nav_menu',
46
+ 'create_term', 'edit_terms', 'delete_term',
47
+ 'add_link', 'edit_link', 'delete_link'
48
+ ) ;
49
+ // purge all on upgrade
50
+ if ( LiteSpeed_Cache::config( LiteSpeed_Cache_Config::OPID_PURGE_ON_UPGRADE ) ) {
51
+ $purge_all_events[] = 'upgrader_process_complete' ;
52
+ $purge_all_events[] = 'admin_action_do-plugin-upgrade' ;
53
+ }
54
+ foreach ( $purge_all_events as $event ) {
55
+ add_action( $event, 'LiteSpeed_Cache_Purge::purge_all' ) ;
56
+ }
57
+ // add_filter( 'upgrader_pre_download', 'LiteSpeed_Cache_Purge::filter_with_purge_all' ) ;
58
+ }
59
+ }
60
+
61
+ /**
62
+ * Callback that initializes the admin options for LiteSpeed Cache.
63
+ *
64
+ * @since 1.0.0
65
+ * @access public
66
+ */
67
+ public function admin_init()
68
+ {
69
+ // check for upgrade
70
+ // NOTE: upgrade checking needs to be before `register_setting` to avoid update_options() be checked by our filter
71
+ $this->config->plugin_upgrade() ;
72
+ if ( is_network_admin() && current_user_can('manage_network_options') ) {
73
+ $this->config->plugin_site_upgrade() ;
74
+ }
75
+
76
+ load_plugin_textdomain(LiteSpeed_Cache::PLUGIN_NAME, false, 'litespeed-cache/languages/') ;
77
+
78
+ $this->proceed_admin_action() ;
79
+
80
+ // Terminate if user doesn't have the access to settings
81
+ if( is_network_admin() ) {
82
+ $capability = 'manage_network_options' ;
83
+ }
84
+ else {
85
+ $capability = 'manage_options' ;
86
+ }
87
+ if ( ! current_user_can($capability) ) {
88
+ return ;
89
+ }
90
+
91
+ // Save setting from admin settings page
92
+ // NOTE: cli will call `validate_plugin_settings` manually. Cron activation doesn't need to validate
93
+ global $pagenow ;
94
+ if ( ! is_network_admin() && $pagenow === 'options.php' ) {
95
+ register_setting(LiteSpeed_Cache_Config::OPTION_NAME, LiteSpeed_Cache_Config::OPTION_NAME, array(LiteSpeed_Cache_Admin_Settings::get_instance(), 'validate_plugin_settings')) ;
96
+ }
97
+
98
+ // step out if plugin is not enabled
99
+ if ( ! LiteSpeed_Cache_Router::cache_enabled() ) {
100
+ return ;
101
+ }
102
+
103
+ LiteSpeed_Cache_Control::set_nocache( 'Admin page' ) ;
104
+
105
+ if ( LSWCP_ESI_SUPPORT && LiteSpeed_Cache::config(LiteSpeed_Cache_Config::OPID_ESI_ENABLE) ) {
106
+ add_action('in_widget_form', array(LiteSpeed_Cache_Admin_Display::get_instance(), 'show_widget_edit'), 100, 3) ;
107
+ add_filter('widget_update_callback', 'LiteSpeed_Cache_Admin_Settings::validate_widget_save', 10, 4) ;
108
+ }
109
+
110
+ // check if WP_CACHE is defined and true in the wp-config.php file.
111
+ if ( ! defined('WP_CACHE') || ! WP_CACHE ) {
112
+ $add_var = LiteSpeed_Cache_Config::wp_cache_var_setter(true) ;
113
+ if ( $add_var !== true ) {
114
+ LiteSpeed_Cache_Admin_Display::add_error($add_var) ;
115
+ }
116
+ }
117
+
118
+ // check management action
119
+ if ( defined('WP_CACHE') && WP_CACHE ) {
120
+ $this->check_advanced_cache() ;
121
+ }
122
+
123
+ if ( ! is_multisite() ) {
124
+ if( ! current_user_can('manage_options') ){
125
+ return ;
126
+ }
127
+ }
128
+ elseif ( ! is_network_admin() ) {
129
+ if ( ! current_user_can('manage_options') ) {
130
+ return ;
131
+ }
132
+ if ( get_current_blog_id() !== BLOG_ID_CURRENT_SITE ) {
133
+ $use_primary = LiteSpeed_Cache_Config::NETWORK_OPID_USE_PRIMARY ;
134
+ $site_options = $this->config->get_site_options() ;
135
+ if ( isset($site_options[$use_primary]) && $site_options[$use_primary] ) {
136
+ $this->display->set_disable_all() ;
137
+ }
138
+ }
139
+ return ;
140
+ }
141
+ elseif ( ! current_user_can('manage_network_options') ) {
142
+ return ;
143
+ }
144
+
145
+ if ( LiteSpeed_Cache_Router::has_whm_msg() ) {
146
+ $this->display->show_display_installed() ;
147
+ }
148
+ }
149
+
150
+ /**
151
+ * Run litespeed admin actions
152
+ *
153
+ * @since 1.1.0
154
+ */
155
+ public function proceed_admin_action()
156
+ {
157
+ // handle actions
158
+ switch (LiteSpeed_Cache_Router::get_action()) {
159
+
160
+ // Save htaccess
161
+ case LiteSpeed_Cache::ACTION_SAVE_HTACCESS:
162
+ LiteSpeed_Cache_Admin_Rules::get_instance()->htaccess_editor_save() ;
163
+ break ;
164
+
165
+ // Save network settings
166
+ case LiteSpeed_Cache::ACTION_SAVE_SETTINGS_NETWORK:
167
+ $options = LiteSpeed_Cache_Admin_Settings::get_instance()->validate_network_settings() ;// todo: use wp network setting saving
168
+ LiteSpeed_Cache_Admin_Report::get_instance()->generate_environment_report($options) ;
169
+ break ;
170
+
171
+ default:
172
+ break ;
173
+ }
174
+
175
+ }
176
+
177
+ /**
178
+ * Check to make sure that the advanced-cache.php file is ours.
179
+ * If it doesn't exist, try to make it ours.
180
+ *
181
+ * If it is not ours and the config is set to check, output an error.
182
+ *
183
+ * @since 1.0.11
184
+ * @access private
185
+ */
186
+ private function check_advanced_cache()
187
+ {
188
+ $capability = is_network_admin() ? 'manage_network_options' : 'manage_options' ;
189
+ if ( (defined('LSCACHE_ADV_CACHE') && LSCACHE_ADV_CACHE) || ! current_user_can($capability) ) {
190
+ if ( ! LiteSpeed_Cache::config(LiteSpeed_Cache_Config::OPID_CHECK_ADVANCEDCACHE) ) {
191
+ // If it exists because I added it at runtime, try to create the file anyway.
192
+ // Result does not matter.
193
+ LiteSpeed_Cache_Activation::try_copy_advanced_cache() ;
194
+ }
195
+ return ;
196
+ }
197
+
198
+ if ( LiteSpeed_Cache_Activation::try_copy_advanced_cache() ) {
199
+ return ;
200
+ }
201
+
202
+ if ( is_multisite() && ( ! is_network_admin() || ! current_user_can('manage_network_options')) ) {
203
+ $third = __('For this scenario only, the network admin may uncheck "Check Advanced Cache" in LiteSpeed Cache settings.', 'litespeed-cache') ;
204
+ }else {
205
+ $third = __('For this scenario only, please uncheck "Check Advanced Cache" in LiteSpeed Cache settings.', 'litespeed-cache') ;
206
+ }
207
+ $msg = __('Please disable/deactivate any other Full Page Cache solutions that are currently being used.', 'litespeed-cache') . ' '
208
+ . __('LiteSpeed Cache does work with other cache solutions, but only their non-page caching offerings—such as minifying css/js files.', 'litespeed-cache') . ' '
209
+ . $third ;
210
+
211
+ $this->display->add_notice(LiteSpeed_Cache_Admin_Display::NOTICE_YELLOW, $msg) ;
212
+ }
213
+
214
+ /**
215
+ * Clean up the input string of any extra slashes/spaces.
216
+ *
217
+ * @since 1.0.4
218
+ * @access public
219
+ * @param string $input The input string to clean.
220
+ * @return string The cleaned up input.
221
+ */
222
+ public static function cleanup_text($input)
223
+ {
224
+ return stripslashes(trim($input)) ;
225
+ }
226
+
227
+ /**
228
+ * After a LSCWP_CTRL action, need to redirect back to the same page
229
+ * without the nonce and action in the query string.
230
+ *
231
+ * @since 1.0.12
232
+ * @access public
233
+ * @global string $pagenow
234
+ */
235
+ public static function redirect()
236
+ {
237
+ global $pagenow ;
238
+ $qs = '' ;
239
+
240
+ if ( ! empty($_GET) ) {
241
+ if ( isset($_GET[LiteSpeed_Cache::ACTION_KEY]) ) {
242
+ unset($_GET[LiteSpeed_Cache::ACTION_KEY]) ;
243
+ }
244
+ if ( isset($_GET[LiteSpeed_Cache::NONCE_NAME]) ) {
245
+ unset($_GET[LiteSpeed_Cache::NONCE_NAME]) ;
246
+ }
247
+ if ( ! empty($_GET) ) {
248
+ $qs = '?' . http_build_query($_GET) ;
249
+ }
250
+ }
251
+ if ( is_network_admin() ) {
252
+ $url = network_admin_url($pagenow . $qs) ;
253
+ }
254
+ else {
255
+ $url = admin_url($pagenow . $qs) ;
256
+ }
257
+ wp_redirect($url) ;
258
+ exit() ;
259
+ }
260
+
261
+ /**
262
+ * Get the current instance object.
263
+ *
264
+ * @since 1.1.0
265
+ * @access public
266
+ * @return Current class instance.
267
+ */
268
+ public static function get_instance()
269
+ {
270
+ $cls = get_called_class() ;
271
+ if ( ! isset(self::$_instance) ) {
272
+ self::$_instance = new $cls() ;
273
+ }
274
+
275
+ return self::$_instance ;
276
+ }
277
+ }
admin/tpl/admin_footer.php ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if (!defined('WPINC')) die;
3
+
4
+
5
+ $rate_us = sprintf(__('Rate <strong>LiteSpeed Cache</strong> with %s on WordPress.org if you like us!', 'litespeed-cache'),
6
+ '<a href="https://wordpress.org/support/plugin/litespeed-cache/reviews/?filter=5#new-post" rel="noopener noreferer" target="_blank">&#10030;&#10030;&#10030;&#10030;&#10030;</a>'
7
+ );
8
+ $questions = sprintf(__('If there are any questions that are not answered in the <a %s>FAQs</a>, do not hesitate to ask them on the <a %s>support forum</a>.', 'litespeed-cache'),
9
+ 'href="' . get_admin_url() . 'admin.php?page=lscache-info"',
10
+ 'href="https://wordpress.org/support/plugin/litespeed-cache" rel="noopener noreferrer" target="_blank"');
11
+ // Change the footer text
12
+ if ( !is_multisite()
13
+ || is_network_admin())
14
+ {
15
+ $footer_text = $rate_us . ' ' . $questions;
16
+ }
17
+ else{
18
+ $footer_text = $questions;
19
+ }
admin/tpl/crawler.php ADDED
@@ -0,0 +1,229 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if (!defined('WPINC')) die ;
3
+
4
+ $_options = LiteSpeed_Cache_Config::get_instance()->get_options() ;
5
+
6
+ $sitemap_time = LiteSpeed_Cache_Crawler::get_instance()->sitemap_time() ;
7
+
8
+ $disabled = LiteSpeed_Cache_Router::can_crawl() ? '' : 'disabled' ;
9
+
10
+ ?>
11
+
12
+ <div class="wrap">
13
+ <h2>
14
+ <?php echo __('LiteSpeed Cache Crawler', 'litespeed-cache') ; ?>
15
+ <span class="litespeed-desc">
16
+ v<?php echo LiteSpeed_Cache::PLUGIN_VERSION; ?>
17
+ </span>
18
+ </h2>
19
+ </div>
20
+ <div class="wrap">
21
+ <div class="litespeed-cache-welcome-panel">
22
+ <h3 class="litespeed-title"><?php echo __('Crawler File', 'litespeed-cache') ; ?></h3>
23
+ <a href="<?php echo $this->build_url(LiteSpeed_Cache::ACTION_CRAWLER_GENERATE_FILE) ; ?>" class="litespeed-btn litespeed-btn-success">
24
+ <?php echo __('Generate Crawler File', 'litespeed-cache') ; ?>
25
+ </a>
26
+
27
+ <?php
28
+ if ( $sitemap_time ) {
29
+ echo sprintf(__('Generated at %s', 'litespeed-cache'), $sitemap_time) ;
30
+ }
31
+ ?>
32
+ <div class="litespeed-desc">
33
+ <?php echo sprintf(__('On click, this will create a crawler sitemap file in plugin directory %s.', 'litespeed-cache'), '`./var`') ; ?>
34
+ </div>
35
+
36
+ <?php
37
+ $seconds = $_options[LiteSpeed_Cache_Config::CRWL_RUN_INTERVAL] ;
38
+ if($seconds > 0):
39
+ $recurrence = '' ;
40
+ $hours = (int)floor($seconds / 3600) ;
41
+ if ( $hours ) {
42
+ if ( $hours > 1) {
43
+ $recurrence .= sprintf(__('%d hours', 'litespeed-cache'), $hours);
44
+ }
45
+ else {
46
+ $recurrence .= sprintf(__('%d hour', 'litespeed-cache'), $hours);
47
+ }
48
+ }
49
+ $minutes = (int)floor( ($seconds % 3600 ) / 60 ) ;
50
+ if ( $minutes ) {
51
+ $recurrence .= ' ' ;
52
+ if ( $minutes > 1) {
53
+ $recurrence .= sprintf(__('%d minutes', 'litespeed-cache'), $minutes);
54
+ }
55
+ else {
56
+ $recurrence .= sprintf(__('%d minute', 'litespeed-cache'), $minutes);
57
+ }
58
+ }
59
+ ?>
60
+ <h3 class="litespeed-title"><?php echo __('Crawler Cron', 'litespeed-cache') ; ?></h3>
61
+ <?php if ( ! LiteSpeed_Cache_Router::can_crawl() ): ?>
62
+ <div class="litespeed-callout litespeed-callout-danger">
63
+ <p><span class="attention"><?php echo __('WARNING', 'litespeed-cache'); ?></span></p>
64
+ <p><?php echo __('The crawler feature is not enabled on the LiteSpeed server. Please consult your server admin.', 'litespeed-cache'); ?></p>
65
+ <p><?php echo sprintf(__('See <a %s>Introduction for Enabling the Crawler</a> for detailed infomation.', 'litespeed-cache'), 'href="https://www.litespeedtech.com/support/wiki/doku.php/litespeed_wiki:cache:lscwp:configuration:enabling_the_crawler" target="_blank"') ; ?></p>
66
+ </div>
67
+ <?php endif; ?>
68
+ <table class="widefat striped">
69
+ <thead><tr >
70
+ <th scope="col"><?php echo __('Cron Name', 'litespeed-cache') ; ?></th>
71
+ <th scope="col"><?php echo __('Run Frequency', 'litespeed-cache') ; ?></th>
72
+ <th scope="col"><?php echo __('Last Status', 'litespeed-cache') ; ?></th>
73
+ <th scope="col"><?php echo __('Activation', 'litespeed-cache') ; ?></th>
74
+ <th scope="col"><?php echo __('Actions', 'litespeed-cache') ; ?></th>
75
+ </tr></thead>
76
+ <tbody>
77
+ <tr>
78
+ <td>
79
+ <?php
80
+ echo __('LiteSpeed Cache Crawler', 'litespeed-cache');
81
+ ?>
82
+ <div class='litespeed-desc'>
83
+ <?php
84
+ $meta = LiteSpeed_Cache_Crawler::get_instance()->get_meta() ;
85
+ $is_running = $meta && $meta->is_running && time() - $meta->is_running <= $_options[LiteSpeed_Cache_Config::CRWL_RUN_DURATION] ;
86
+ if ( $meta && $meta->this_full_beginning_time ) {
87
+ if ( $is_running ) {
88
+ echo sprintf(__('The current sitemap crawl started at %s', 'litespeed-cache'),
89
+ date('m/d/Y H:i:s' ,$meta->this_full_beginning_time));
90
+
91
+ }
92
+ else {
93
+ echo sprintf(__('The current sitemap crawl started at %s', 'litespeed-cache'),
94
+ date('m/d/Y H:i:s' ,$meta->this_full_beginning_time));
95
+ echo "</div><div class='litespeed-desc'>";
96
+ echo sprintf(__('The next complete sitemap crawl will start at %s', 'litespeed-cache'),
97
+ date('m/d/Y H:i:s',$meta->this_full_beginning_time
98
+ + $meta->last_full_time_cost + $_options[LiteSpeed_Cache_Config::CRWL_CRAWL_INTERVAL]));
99
+ }
100
+
101
+ }
102
+ ?>
103
+ </div>
104
+ </td>
105
+ <td>
106
+ <?php echo $recurrence ; ?>
107
+ <div class='litespeed-desc'>
108
+ <?php
109
+ if ( $meta && $meta->last_full_time_cost ) {
110
+ echo sprintf(__('The last complete run cost %s seconds', 'litespeed-cache'), $meta->last_full_time_cost) ;
111
+ }
112
+ ?>
113
+ </div>
114
+ </td>
115
+ <td>
116
+ <?php
117
+ if ( $meta ) {
118
+ echo "Size: {$meta->list_size}<br />Position: " . ($meta->last_pos + 1) ;
119
+ if ( $is_running ) {
120
+ echo "<br /><div class='litespeed-label litespeed-label-success'>" . __('Is running', 'litespeed-cache') . "</div>" ;
121
+ }
122
+ }
123
+ else {
124
+ echo "-" ;
125
+ }
126
+ ?>
127
+ </td>
128
+ <td>
129
+ <label class="litespeed-switch-onoff">
130
+ <input type="checkbox"
131
+ name="litespeed_crawler_cron_enable"
132
+ id="litespeed_crawler_cron_enable"
133
+ value="1"
134
+ data-url="<?php echo $this->build_url(LiteSpeed_Cache::ACTION_CRAWLER_CRON_ENABLE, 'cron_enable') ; ?>"
135
+ <?php if( $_options[LiteSpeed_Cache_Config::CRWL_CRON_ACTIVE] && LiteSpeed_Cache_Router::can_crawl() ) echo "checked"; ?>
136
+ <?php echo $disabled ; ?>
137
+ />
138
+ <span data-on="<?php echo __('Enable', 'litespeed-cache'); ?>" data-off="<?php echo __('Disable', 'litespeed-cache'); ?>"></span>
139
+ <span></span>
140
+ </label>
141
+ </td>
142
+ <td>
143
+ <?php
144
+ echo " <a href='" . $this->build_url(LiteSpeed_Cache::ACTION_CRAWLER_RESET_POS) . "' class='litespeed-btn litespeed-btn-warning litespeed-btn-xs'>" . __('Reset position', 'litespeed-cache') . "</a>" ;
145
+
146
+ $href = LiteSpeed_Cache_Router::can_crawl() ? $this->build_url(LiteSpeed_Cache::ACTION_DO_CRAWL) : 'javascript:;' ;
147
+ echo " <a href='$href' id='litespeed_manual_trigger' target='litespeedHiddenIframe' class='litespeed-btn litespeed-btn-success litespeed-btn-xs' $disabled>" . __('Manually run', 'litespeed-cache') . "</a>" ;
148
+ ?>
149
+ <?php if ( $meta && $meta->last_start_time ): ?>
150
+ <div class='litespeed-desc'>
151
+ <?php echo sprintf(__('<b>Last interval:</b> %s', 'litespeed-cache'), date('m/d/Y H:i:s' ,$meta->last_start_time)) ; ?>
152
+ </div>
153
+ <?php endif ; ?>
154
+
155
+ <?php if ( $meta && $meta->end_reason ): ?>
156
+ <div class='litespeed-desc'>
157
+ <?php echo sprintf(__('<b>Ended reason:</b> %s', 'litespeed-cache'), $meta->end_reason) ; ?>
158
+ </div>
159
+ <?php endif ; ?>
160
+
161
+ <?php if ( $meta && $meta->last_crawled ): ?>
162
+ <div class='litespeed-desc'>
163
+ <?php echo sprintf(__('<b>Last crawled:</b> %s item(s)', 'litespeed-cache'), $meta->last_crawled) ; ?>
164
+ </div>
165
+ <?php endif ; ?>
166
+ </td>
167
+ </tr>
168
+ </tbody>
169
+ </table>
170
+ <div class="litespeed-desc">
171
+ <div><?php echo __('Run frequency is set by the Interval Between Runs setting.','litespeed-cache') ; ?></div>
172
+ <div><?php echo __('Only one crawler can run concurrently.', 'litespeed-cache')
173
+ . __('If both the cron and manual run start at a similar time, the first one to start will run.','litespeed-cache') ; ?></div>
174
+ <div><?php echo sprintf(__('Please follow <a %s>Hooking WP-Cron Into the System Task Scheduler</a> to create the system cron task.','litespeed-cache'), ' href="https://developer.wordpress.org/plugins/cron/hooking-into-the-system-task-scheduler/" target="_blank" ') ; ?></div>
175
+ </div>
176
+ <?php endif ; ?>
177
+
178
+
179
+ <h3 class="litespeed-title"><?php echo __('Watch Crawler Status', 'litespeed-cache') ; ?></h3>
180
+
181
+ <?php
182
+ $ajaxUrl = LiteSpeed_Cache_Crawler::get_instance()->get_crawler_json_path() ;
183
+ if ( $ajaxUrl ):
184
+ ?>
185
+
186
+ <input type="button" id="litespeed-crawl-url-btn" value="<?php echo __('Show crawler status', 'litespeed-cache') ; ?>" class="litespeed-btn litespeed-btn-primary" data-url="<?php echo $ajaxUrl ; ?>" />
187
+
188
+ <div class="litespeed-shell litespeed-hide">
189
+ <div class="litespeed-shell-header-bar"></div>
190
+ <div class="litespeed-shell-header">
191
+ <div class="litespeed-shell-header-bg"></div>
192
+ <div class="litespeed-shell-header-icon-container">
193
+ <img id="litespeed-shell-icon" src="<?php echo plugins_url('img/Litespeed.icon.svg', dirname(__FILE__)); ?>" />
194
+ </div>
195
+ </div>
196
+ <ul class="litespeed-shell-body">
197
+ <li>Start watching...</li>
198
+ <li id="litespeed-loading-dot"></li>
199
+ </ul>
200
+ </div>
201
+
202
+ <?php else: ?>
203
+ <p>
204
+ <?php echo __('No crawler meta file generated yet', 'litespeed-cache') ; ?>
205
+ </p>
206
+ <?php endif ; ?>
207
+
208
+
209
+ <h3 class="litespeed-title"><?php echo __('Sitemap Generation Blacklist', 'litespeed-cache') ; ?></h3>
210
+
211
+ <form method="post" action="admin.php?page=lscache-crawler">
212
+ <?php $this->form_action(LiteSpeed_Cache::ACTION_BLACKLIST_SAVE); ?>
213
+ <p>
214
+ <textarea name="<?php echo LiteSpeed_Cache_Crawler::CRWL_BLACKLIST; ?>" rows="10" class="code litespeed-cache-blacklist"><?php echo LiteSpeed_Cache_Crawler::get_instance()->get_blacklist(); ?></textarea>
215
+ </p>
216
+
217
+ <p>
218
+ <button type="submit" class="litespeed-btn litespeed-btn-success"><?php echo __('Save', 'litespeed-cache'); ?></button>
219
+ </p>
220
+ </form>
221
+ <div class="litespeed-desc">
222
+ <p><?php echo sprintf(__('Current blacklist has %s item(s).', 'litespeed-cache'), LiteSpeed_Cache_Crawler::get_instance()->count_blacklist()); ?></p>
223
+ <p><?php echo __('All Urls which returned no-cache tags will be added here, after the initial crawling.', 'litespeed-cache'); ?></p>
224
+ </div>
225
+
226
+ </div>
227
+ </div>
228
+
229
+ <iframe name="litespeedHiddenIframe" src="" width="0" height="0" frameborder="0"></iframe>
admin/tpl/debug_log.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( ! defined( 'WPINC' ) ) die ;
3
+
4
+
5
+ ?>
6
+
7
+ <div class="wrap">
8
+ <h2>
9
+ <?php echo __( 'LiteSpeed Cache Debug Log Viewer', 'litespeed-cache' ) ; ?>
10
+ <span class="litespeed-desc">
11
+ v<?php echo LiteSpeed_Cache::PLUGIN_VERSION ; ?>
12
+ </span>
13
+ </h2>
14
+ </div>
15
+ <div class="wrap">
16
+ <?php
17
+
18
+ $file = LSWCP_CONTENT_DIR . '/debug.log' ;
19
+ $lines = Litespeed_File::count_lines( $file ) ;
20
+ $start = $lines > 1000 ? $lines - 1000 : 0 ;
21
+ $logs = Litespeed_File::read( $file, $start ) ;
22
+ $logs = implode( "\n", $logs ) ;
23
+
24
+ echo nl2br( htmlspecialchars( $logs ) ) ;
25
+
26
+ ?>
27
+ </div>
admin/tpl/edit_htaccess.php ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if (!defined('WPINC')) die;
3
+
4
+ $readonly = LiteSpeed_Cache_Admin_Rules::writable() ? '' : 'readonly';
5
+ $content = LiteSpeed_Cache_Admin_Rules::get_instance()->htaccess_read();
6
+
7
+ // Check if there is `ExpiresDefault` in .htaccess
8
+ if ( LiteSpeed_Cache::config( LiteSpeed_Cache_Config::OPID_ENABLED ) ) {
9
+ $htaccess_con = Litespeed_File::read( LiteSpeed_Cache_Admin_Rules::get_frontend_htaccess() ) ;
10
+ if ( $content && stripos( $content, "\nExpiresDefault" ) !== false ) {
11
+ $is_dismissed = get_option( self::DISMISS_MSG ) ;
12
+ if ( $is_dismissed !== self::RULECONFLICT_DISMISSED ) {
13
+ // Need to add a notice for browser cache compatibility
14
+ if ( $is_dismissed !== self::RULECONFLICT_ON ) {
15
+ update_option( self::DISMISS_MSG, self::RULECONFLICT_ON ) ;
16
+ }
17
+ $this->show_rule_conflict() ;
18
+ }
19
+ }
20
+ // don't dismiss the msg automatically
21
+ // elseif ( $is_dismissed === LiteSpeed_Cache_Admin_Display::RULECONFLICT_ON ) {
22
+ // update_option( self::DISMISS_MSG, LiteSpeed_Cache_Admin_Display::RULECONFLICT_DISMISSED ) ;
23
+ // }
24
+ }
25
+
26
+
27
+ ?>
28
+
29
+ <div class="wrap">
30
+ <h2>
31
+ <?php echo __('LiteSpeed Cache Edit .htaccess', 'litespeed-cache'); ?>
32
+ <span class="litespeed-desc">
33
+ v<?php echo LiteSpeed_Cache::PLUGIN_VERSION; ?>
34
+ </span>
35
+ </h2>
36
+ </div>
37
+ <div class="wrap">
38
+ <div class="litespeed-cache-welcome-panel">
39
+ <div class="litespeed-callout litespeed-callout-danger">
40
+ <p><span class="attention"><?php echo __('WARNING: This page is meant for advanced users.', 'litespeed-cache'); ?></span></p>
41
+ <?php echo __('Any changes made to the .htaccess file may break the site.', 'litespeed-cache'); ?>
42
+ <?php echo __('Please consult the host/server admin before making any changes.', 'litespeed-cache'); ?>
43
+ </div>
44
+
45
+ <?php if (defined('DISALLOW_FILE_EDIT') && DISALLOW_FILE_EDIT): ?>
46
+ <h3><?php echo __('File editing is disabled in configuration.', 'litespeed-cache'); ?></h3>
47
+
48
+ <?php elseif($content === false): ?>
49
+ <h3><?php $this->display_messages(); ?></h3>
50
+
51
+ <?php else: ?>
52
+
53
+ <form method="post" action="admin.php?page=<?php echo LiteSpeed_Cache::PAGE_EDIT_HTACCESS; ?>">
54
+ <?php $this->form_action(LiteSpeed_Cache::ACTION_SAVE_HTACCESS); ?>
55
+
56
+ <h3><?php echo sprintf(__('Current %s contents:', 'litespeed-cache'), '.htaccess'); ?></h3>
57
+
58
+ <!--p><span class="attention"><?php echo sprintf(__('DO NOT EDIT ANYTHING WITHIN %s', 'litespeed-cache'), LiteSpeed_Cache_Admin_Rules::LS_MODULE_DONOTEDIT); ?></span></p-->
59
+
60
+ <p><?php echo __('These are added by the LS Cache plugin and may cause problems if they are changed.', 'litespeed-cache'); ?></p>
61
+
62
+ <textarea id="wpwrap" name="<?php echo LiteSpeed_Cache_Admin_Rules::EDITOR_TEXTAREA_NAME; ?>" wrap="off" rows="30" class="code"
63
+ <?php echo $readonly; ?>
64
+ ><?php echo esc_textarea($content); ?></textarea>
65
+
66
+ <button type="submit" class="litespeed-btn litespeed-btn-success"><?php echo __('Save', 'litespeed-cache'); ?></button>
67
+ </form>
68
+
69
+ <?php require LSWCP_DIR . 'admin/tpl/info_common_rewrite.php'; ?>
70
+
71
+ <?php endif; ?>
72
+ </div>
73
+ </div>
admin/tpl/esi_widget_edit.php ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( !defined('WPINC') ) die;
3
+ // $widget, $return, $instance
4
+
5
+ $options = LiteSpeed_Cache_ESI::widget_load_get_options($widget) ;
6
+ if ( empty($options) ) {
7
+ $options = array(
8
+ LiteSpeed_Cache_ESI::WIDGET_OPID_ESIENABLE => false,
9
+ LiteSpeed_Cache_ESI::WIDGET_OPID_TTL => '28800'
10
+ ) ;
11
+ $options = apply_filters('litespeed_cache_widget_default_options', $options, $widget) ;
12
+ }
13
+
14
+ if ( empty($options) ) {
15
+ $esi = false ;
16
+ $ttl = '28800' ;
17
+ }
18
+ else {
19
+ $esi = $options[LiteSpeed_Cache_ESI::WIDGET_OPID_ESIENABLE] ;
20
+ $ttl = $options[LiteSpeed_Cache_ESI::WIDGET_OPID_TTL] ;
21
+ }
22
+
23
+ ?>
24
+ <div class="litespeed-widget-setting">
25
+
26
+ <h4>LiteSpeed Cache:</h4>
27
+
28
+ <b><?php echo __('Enable ESI', 'litespeed-cache') ; ?>:</b>
29
+ &nbsp;&nbsp;
30
+ <div class="litespeed-inline">
31
+ <?php LiteSpeed_Cache_Admin_Display::get_instance()->build_switch(LiteSpeed_Cache_ESI::WIDGET_OPID_ESIENABLE, false, false, $esi, 'litespeed-cfg-'.$widget->id) ; ?>
32
+ </div>
33
+ <br /><br />
34
+
35
+ <b><?php echo __('Widget Cache TTL:', 'litespeed-cache') ; ?></b>
36
+ &nbsp;&nbsp;
37
+ <?php LiteSpeed_Cache_Admin_Display::get_instance()->build_input(LiteSpeed_Cache_ESI::WIDGET_OPID_TTL, 'litespeed-reset', false, false, null, $ttl, 'size="7"') ; ?>
38
+ <?php echo __('seconds', 'litespeed-cache') ; ?>
39
+
40
+ <p class="install-help">
41
+ <?php echo __('Recommended value: 28800 seconds (8 hours).', 'litespeed-cache') ; ?>
42
+ <?php echo __('A TTL of 0 indicates do not cache.', 'litespeed-cache') ; ?>
43
+ </p>
44
+ </div>
45
+
46
+ <br />
admin/tpl/help_tabs.php ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if (!defined('WPINC')) die;
3
+
4
+ $screen = get_current_screen();
5
+ $screen->add_help_tab(array(
6
+ 'id' => 'lsc-overview',
7
+ 'title' => __('Overview', 'litespeed-cache'),
8
+ 'content' => '<p>'
9
+ . __('LiteSpeed Cache is a page cache built into LiteSpeed Web Server.', 'litespeed-cache') . ' '
10
+ . __('This plugin communicates with LiteSpeed Web Server to let it know which pages are cacheable and when to purge them.', 'litespeed-cache')
11
+ . '</p><p>' . __('A LiteSpeed server (OLS, LSWS, WebADC) and its LSCache module must be installed and enabled.', 'litespeed-cache')
12
+ . '</p>',
13
+ ));
14
+
15
+ // $screen->add_help_tab(array(
16
+ // 'id' => 'lst-purgerules',
17
+ // 'title' => __('Auto Purge Rules', 'litespeed-cache'),
18
+ // 'content' => '<p>' . __('You can set what pages will be purged when a post is published or updated.', 'litespeed-cache') . '</p>',
19
+ // ));
20
+
21
+ $screen->set_help_sidebar(
22
+ '<p><strong>' . __('For more information:', 'litespeed-cache') . '</strong></p>' .
23
+ // '<p><a href="https://www.litespeedtech.com/support/wiki/doku.php/litespeed_wiki:cache" rel="noopener noreferrer" target="_blank">' . __('LSCache Documentation', 'litespeed-cache') . '</a></p>' .
24
+ '<p><a href="https://wordpress.org/support/plugin/litespeed-cache" rel="noopener noreferrer" target="_blank">' . __('Support Forum', 'litespeed-cache') . '</a></p>'
25
+ );
26
+
admin/tpl/info.php ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if (!defined('WPINC')) die;
3
+
4
+ $menuArr = array(
5
+ 'faqs' => __('FAQs', 'litespeed-cache'),
6
+ 'config' => __('Configuration', 'litespeed-cache'),
7
+ 'compatibility' => __('Plugin Compatibilities', 'litespeed-cache'),
8
+ 'common_rewrite' => __('Common Rewrite Rules', 'litespeed-cache'),
9
+ 'admin_ip' => __('Admin IP Commands', 'litespeed-cache'),
10
+ 'crawler' => __('Crawler', 'litespeed-cache'),
11
+ );
12
+
13
+ ?>
14
+ <div class="wrap">
15
+ <h2>
16
+ <?php echo __('LiteSpeed Cache Information', 'litespeed-cache'); ?>
17
+ <span class="litespeed-desc">
18
+ v<?php echo LiteSpeed_Cache::PLUGIN_VERSION ; ?>
19
+ </span>
20
+ </h2>
21
+ </div>
22
+ <div class="wrap">
23
+ <h2 class="nav-tab-wrapper">
24
+ <?php
25
+ foreach ($menuArr as $tab => $val){
26
+ echo "<a class='nav-tab litespeed-tab' href='?page=lscache-info#$tab' data-litespeed-tab='$tab'>$val</a>";
27
+ }
28
+ ?>
29
+ </h2>
30
+ <div class="litespeed-cache-welcome-panel">
31
+
32
+ <?php
33
+ // include all tpl for faster UE
34
+ foreach ($menuArr as $tab => $val) {
35
+ echo "<div data-litespeed-layout='$tab'>";
36
+ require LSWCP_DIR . "admin/tpl/info_$tab.php";
37
+ echo "</div>";
38
+ }
39
+
40
+ ?>
41
+ </div>
42
+ </div>
admin/tpl/info_admin_ip.php ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if (!defined('WPINC')) die;
3
+
4
+ $nocache_desc =
5
+ __('This is used to display a page without caching it.', 'litespeed-cache').' '.
6
+ __('An example use case is to compare a cached version of a page with an uncached version.', 'litespeed-cache');
7
+
8
+ $purge_desc =
9
+ __('This is used to purge most cache tags associated with the page.', 'litespeed-cache').' '.
10
+ __('The lone exception is the blog ID tag.', 'litespeed-cache').' '.
11
+ __('Note that this means that pages with the same cache tag will be purged as well.', 'litespeed-cache');
12
+
13
+ $showheaders_desc =
14
+ __('This is used to show all the cache headers associated with a page.', 'litespeed-cache').' '.
15
+ __('This may be useful for debugging purposes.', 'litespeed-cache');
16
+
17
+ ?>
18
+
19
+ <h3 class="litespeed-title"><?php echo __('Admin IP Query String Actions', 'litespeed-cache'); ?></h3>
20
+
21
+ <h4><?php echo __('The following commands are available to the admin and do not require log-in, providing quick access to actions on the various pages.', 'litespeed-cache'); ?></h4>
22
+
23
+ <h4><?php echo __('Action List:', 'litespeed-cache'); ?></h4>
24
+
25
+ <ul>
26
+ <li><?php echo LiteSpeed_Cache::ACTION_QS_NOCACHE; ?> - <?php echo $nocache_desc; ?></li>
27
+ <li><?php echo LiteSpeed_Cache::ACTION_QS_PURGE; ?> - <?php echo $purge_desc; ?></li>
28
+ <li><?php echo LiteSpeed_Cache::ACTION_QS_PURGE_SINGLE; ?> - <?php echo __('This is used to purge the first cache tag associated with the page.', 'litespeed-cache'); ?></li>
29
+ <li><?php echo LiteSpeed_Cache::ACTION_QS_SHOW_HEADERS; ?> - <?php echo $showheaders_desc; ?></li>
30
+ </ul>
31
+
32
+ <h5><?php echo sprintf(__('To trigger the action for a page, access the page with the query string %s', 'litespeed-cache'),
33
+ '<code>?'.LiteSpeed_Cache::ACTION_KEY.'=ACTION</code>'); ?></h5>
admin/tpl/info_common_rewrite.php ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if (!defined('WPINC')) die;
3
+
4
+ $notice_title = '';
5
+ $notice_content = '';
6
+
7
+ if ((is_multisite()) && (!is_network_admin())) {
8
+ $notice_title = __('NOTE:', 'litespeed-cache');
9
+ $notice_content =
10
+ '<p>'.__('The following configuration can only be changed by the network admin.', 'litespeed-cache').'</p>'.
11
+ '<p>'.__('Please contact the network admin to make any changes.', 'litespeed-cache').'</p>';
12
+ }
13
+ else {
14
+ $notice_title = __('NOTICE:', 'litespeed-cache');
15
+ $notice_content =
16
+ '<p>'.
17
+ __('The following rewrite rules can be configured in the LiteSpeed Cache settings page.', 'litespeed-cache').' '.
18
+ __('Please make any needed changes on that page.', 'litespeed-cache').' '.
19
+ __('It will automatically generate the correct rules in the htaccess file.', 'litespeed-cache').
20
+ '</p>';
21
+ }
22
+ ?>
23
+
24
+ <h3 class="litespeed-title"><?php echo __('LiteSpeed Cache Common Rewrite Rules', 'litespeed-cache'); ?></h3>
25
+
26
+ <div class="litespeed-callout litespeed-callout-warning">
27
+ <h4><?php echo $notice_title; ?></h4>
28
+ <?php echo $notice_content; ?>
29
+ </div>
30
+
31
+ <h4 class="litespeed-question litespeed-down"><?php echo __('Mobile Views:', 'litespeed-cache'); ?></h4>
32
+ <div class="litespeed-answer">
33
+ <p>
34
+ <?php echo __('Some sites have adaptive views, meaning the page sent will adapt to the browser type (desktop vs mobile).', 'litespeed-cache'); ?>
35
+ <?php echo __('This rewrite rule is used for sites that load a different page for each type.', 'litespeed-cache'); ?>
36
+ </p>
37
+ <p>
38
+ <?php echo __('This configuration can be added on the settings page in the General tab.', 'litespeed-cache'); ?>
39
+ </p>
40
+ <textarea id="wpwrap" rows="2" readonly>RewriteCond %{HTTP_USER_AGENT} Mobile|Android|Silk/|Kindle|BlackBerry|Opera\ Mini|Opera\ Mobi [NC]
41
+ RewriteRule .* - [E=Cache-Control:vary=ismobile]</textarea>
42
+ </div>
43
+
44
+ <h4 class="litespeed-question litespeed-down"><?php echo __('Do Not Cache Cookies:', 'litespeed-cache'); ?></h4>
45
+ <div class="litespeed-answer">
46
+ <p><?php echo __('Another common rewrite rule is to notify the cache not to cache when it sees a specified cookie name.', 'litespeed-cache'); ?></p>
47
+ <p><?php echo __('This configuration can be added on the settings page in the Do Not Cache tab.', 'litespeed-cache'); ?></p>
48
+ <textarea id="wpwrap" rows="2" readonly>RewriteCond %{HTTP_COOKIE} dontcachecookie
49
+ RewriteRule .* - [E=Cache-Control:no-cache]</textarea>
50
+ </div>
51
+
52
+ <h4 class="litespeed-question litespeed-down"><?php echo __('Do Not Cache User Agent:', 'litespeed-cache'); ?></h4>
53
+ <div class="litespeed-answer">
54
+ <p><?php echo __('A not so commonly used rewrite rule is to notify the cache not to cache when it sees a specified User Agent.', 'litespeed-cache'); ?></p>
55
+ <p><?php echo __('This configuration can be added on the settings page in the Do Not Cache tab.', 'litespeed-cache'); ?></p>
56
+ <textarea id="wpwrap" rows="2" readonly>RewriteCond %{HTTP_USER_AGENT} dontcacheuseragent
57
+ RewriteRule .* - [E=Cache-Control:no-cache]</textarea>
58
+ </div>
admin/tpl/info_compatibility.php ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if (!defined('WPINC')) die;
3
+
4
+ $known_compat = array(
5
+ 'bbPress',
6
+ 'WooCommerce',
7
+ 'Contact Form 7',
8
+ 'Google XML Sitemaps',
9
+ 'Yoast SEO',
10
+ 'Wordfence Security',
11
+ 'NextGen Gallery',
12
+ 'Aelia CurrencySwitcher',
13
+ 'Fast Velocity Minify, thanks to Raul Peixoto',
14
+ 'Autoptimize',
15
+ 'Better WP Minify',
16
+ 'WP Touch',
17
+ 'Theme My Login',
18
+ 'wpForo',
19
+ 'WPLister',
20
+ 'Avada',
21
+ 'WP-PostRatings',
22
+ );
23
+
24
+ $known_uncompat = array();
25
+
26
+ ?>
27
+ <h3 class="litespeed-title"><?php echo __('LiteSpeed Cache Plugin Compatibility', 'litespeed-cache'); ?></h3>
28
+
29
+ <p><a href="https://wordpress.org/support/topic/known-supported-plugins?replies=1" rel="noopener noreferrer" target="_blank"><?php echo __('Link Here', 'litespeed-cache'); ?></a></p>
30
+ <p>
31
+ <?php echo __('Please add a comment listing the plugins that you are using and how they are functioning on the support thread.', 'litespeed-cache'); ?>
32
+ <?php echo __('With your help, we can provide the best WordPress caching solution.', 'litespeed-cache'); ?>
33
+ </p>
34
+
35
+ <h4><?php echo __('This is a list of plugins that are confirmed to be compatible with LiteSpeed Cache Plugin:', 'litespeed-cache'); ?></h4>
36
+ <ul>
37
+ <?php
38
+ foreach ($known_compat as $plugin_name) {
39
+ echo '<li>' . $plugin_name . '</li>';
40
+ }
41
+ ?>
42
+ </ul>
43
+
44
+ <h4><?php echo __('This is a list of known UNSUPPORTED plugins:', 'litespeed-cache'); ?></h4>
45
+ <ul>
46
+ <?php
47
+ if($known_uncompat) {
48
+ foreach ($known_uncompat as $plugin_name) {
49
+ echo '<li>' . $plugin_name . '</li>';
50
+ }
51
+ }else{
52
+ echo "<li>Nil</li>";
53
+ }
54
+ ?>
55
+ </ul>
56
+
57
+
admin/tpl/info_config.php ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if (!defined('WPINC')) die;
3
+ ?>
4
+ <h3 class="litespeed-title"><?php echo __('LiteSpeed Cache Configuration', 'litespeed-cache'); ?></h3>
5
+
6
+
7
+ <h4><?php echo __('Instructions for LiteSpeed Web Server Enterprise', 'litespeed-cache'); ?></h4>
8
+ <p>
9
+ <?php echo __('Make sure that the server license has the LSCache module enabled.', 'litespeed-cache'); ?>
10
+ <?php echo sprintf(__('A <a %s>2-CPU trial license with LSCache module</a> is available for free for %d days.', 'litespeed-cache'),
11
+ 'href="https://www.litespeedtech.com/products/litespeed-web-server/download/get-a-trial-license" rel="noopener noreferrer" target="_blank"', 15); ?>
12
+ </p>
13
+ <p>
14
+ <?php echo __('The server must be configured to have caching enabled.', 'litespeed-cache'); ?>
15
+ <?php echo sprintf(__('If you are the server admin, <a %s>click here.</a>', 'litespeed-cache'),
16
+ 'href="https://www.litespeedtech.com/support/wiki/doku.php/litespeed_wiki:cache:common_installation#web_server_configuration" rel="noopener noreferrer" target="_blank"'); ?>
17
+ <?php echo __('Otherwise request that the server admin configure the cache root for the server.', 'litespeed-cache'); ?>
18
+ </p>
19
+ <p>
20
+ <?php echo __('In the .htaccess file for the WordPress installation, add the following:', 'litespeed-cache'); ?>
21
+ <textarea id="wpwrap" rows="3" readonly>&lt;IfModule LiteSpeed&gt;
22
+ CacheLookup public on
23
+ &lt;/IfModule&gt;</textarea>
24
+ </p>
25
+
26
+
27
+ <h4><?php echo __('Instructions for OpenLiteSpeed', 'litespeed-cache'); ?></h4>
28
+ <p><?php echo __('This integration utilizes OLS\'s cache module.', 'litespeed-cache'); ?></p>
29
+ <p>
30
+ <?php echo sprintf(__('If it is a fresh OLS installation, the easiest way to integrate is to use <a %s>ols1clk.</a>', 'litespeed-cache'),
31
+ 'href="http://open.litespeedtech.com/mediawiki/index.php/Help:1-Click_Install" rel="noopener noreferrer" target="_blank"'); ?>
32
+ <?php echo sprintf(__('If using an existing WordPress installation, use the %s parameter.', 'litespeed-cache'), '--wordpresspath'); ?>
33
+ <?php echo sprintf(__('Else if OLS and WordPress are already installed, please follow the instructions <a %s>here.</a>', 'litespeed-cache'),
34
+ 'href="http://open.litespeedtech.com/mediawiki/index.php/Help:How_To_Set_Up_LSCache_For_WordPress" rel="noopener noreferrer" target="_blank"'); ?>
35
+ </p>
36
+
37
+
38
+ <h3><?php echo __('How to test the plugin', 'litespeed-cache'); ?></h3>
39
+ <p><?php echo __('The LiteSpeed Cache Plugin utilizes LiteSpeed specific response headers.', 'litespeed-cache'); ?></p>
40
+ <p>
41
+ <?php echo sprintf(__('Visiting a page for the first time should result in a %s or %s response header for the page.', 'litespeed-cache'),
42
+ '<br><code>X-LiteSpeed-Cache-Control:miss</code><br>',
43
+ '<br><code>X-LiteSpeed-Cache-Control:no-cache</code><br>'); ?>
44
+ </p>
45
+ <p>
46
+ <?php echo sprintf(__('Subsequent requests should have the %s response header until the page is updated, expired, or purged.', 'litespeed-cache'), '<code>X-LiteSpeed-Cache-Control:hit</code><br>'); ?>
47
+ </p>
48
+ <p>
49
+ <?php echo sprintf(__('Please visit <a %s>this page</a> for more information.', 'litespeed-cache'),
50
+ 'href="https://www.litespeedtech.com/support/wiki/doku.php/litespeed_wiki:cache:lscwp:installation#testing" rel="noopener noreferrer" target="_blank"'); ?>
51
+ </p>
52
+
53
+ <h3><?php echo __( 'Cache tag prefix setting', 'litespeed-cache' ) ; ?></h3>
54
+ <p>
55
+ <?php echo sprintf(
56
+ __( 'The value of this wordpress cache tag prefix is %1$s. If you want to change the value to avoid conflicts with multiple sites, please add %2$s to %3$s.', 'litespeed-cache' ),
57
+ '<code>' . LSWCP_TAG_PREFIX . '</code>',
58
+ '<code>define( "LSWCP_TAG_PREFIX", "YourUniqueStringHere" ) ;</code>',
59
+ '<code>wp-config.php</code>'
60
+ ) ; ?>
61
+ </p>
62
+
63
+
64
+
65
+
66
+
67
+
68
+
admin/tpl/info_crawler.php ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if (!defined('WPINC')) die;
3
+
4
+ ?>
5
+
6
+ <h3 class="litespeed-title">
7
+ <?php echo __('Crawler Introduction', 'litespeed-cache'); ?>
8
+ <a href="javascript:;" class="litespeed-expend" data-litespeed-expend-all="crawler">+</a>
9
+ </h3>
10
+
11
+ <h4 class="litespeed-question litespeed-down"><?php echo __('How Does the Crawler Work?', 'litespeed-cache'); ?></h4>
12
+ <div class="litespeed-answer">
13
+ <p><?php echo __('Using a sitemap as a guide, LSCache’s crawler, travels its way throughout the backend, refreshing pages that have expired in the cache. The purpose is to keep the cache as fresh as possible while minimizing visitor exposure to uncached content.', 'litespeed-cache'); ?></p>
14
+
15
+ <p><?php echo __('The sitemap can be generated by the crawler, or you can provide your own custom map.', 'litespeed-cache'); ?></p>
16
+
17
+ <p><?php echo sprintf(__('To learn more about each of the crawler settings, see <a %s>our wiki - Crawler Settings</a>.', 'litespeed-cache'), 'href="https://www.litespeedtech.com/support/wiki/doku.php/litespeed_wiki:cache:lscwp:configuration#crawler_settings" target="_blank"'); ?></p>
18
+ </div>
19
+
20
+
21
+ <h4 class="litespeed-question litespeed-down"><?php echo __('Should I Enable the Crawler?', 'litespeed-cache'); ?></h4>
22
+ <div class="litespeed-answer">
23
+ <p><?php echo __('Not every site needs a crawler.', 'litespeed-cache'); ?></p>
24
+
25
+ <p><?php echo __('In WordPress, the first visitor to an uncached page waits for the page to be dynamically-generated and served, and the page is then cached for subsequent visitors.', 'litespeed-cache'); ?></p>
26
+
27
+ <p><?php echo __('The LSCache crawler makes the first visitor’s experience better by essentially becoming the first visitor. The crawler caches the page, and the visitor who would have been first is spared the wait. As such, the crawler realistically only benefits the first out of the many users who visit that page before it expires. If you have a small user base, then crawling impacts a greater percentage of your visitors than it would on a site that draws a large crowd.', 'litespeed-cache'); ?></p>
28
+
29
+ <p><?php echo __('You should weigh this benefit against your server’s resources. If resources are plentiful, then the crawler is a nice thing to have.', 'litespeed-cache'); ?></p>
30
+
31
+ <p><?php echo __('If your site is busy, you’ll find that commonly-visited pages are quickly re-cached by new visitors, without the aid of a crawler. An extra crawler task would compete for server resources while delivering minimal benefits.', 'litespeed-cache'); ?></p>
32
+
33
+ <p><?php echo __('The decision to use a crawler depends on the busy-ness of the site and the availability of server resources. Ultimately, it is the hosting provider who can best make this call.', 'litespeed-cache'); ?></p>
34
+ </div>
35
+
36
+
37
+
38
+ <h4 class="litespeed-question litespeed-down"><?php echo __('Enabling the Crawler', 'litespeed-cache'); ?></h4>
39
+ <div class="litespeed-answer">
40
+ <p><?php echo __('Due to the potential of the crawler to consume considerable resources, we have put the on/off switch in the hands of the server administrators. The crawler is disabled by default and can only be enabled by an admin.', 'litespeed-cache'); ?></p>
41
+
42
+ <p><?php echo sprintf(__('Instructions for enabling the crawler can be found in <a %s>our wiki - Enabling the Crawler</a>. If you do not have access to server configuration files or virtual host include files, you will need to ask your web host for assistance.', 'litespeed-cache'), 'href="https://www.litespeedtech.com/support/wiki/doku.php/litespeed_wiki:cache:lscwp:configuration:enabling_the_crawler" target="_blank"'); ?></p>
43
+ </div>
44
+
45
+
46
+
47
+ <h4 class="litespeed-question litespeed-down"><?php echo __('Testing the Crawler', 'litespeed-cache'); ?></h4>
48
+ <div class="litespeed-answer">
49
+ <p><?php echo __('To determine whether the crawler is working as expected, you can test it with a single URL.', 'litespeed-cache'); ?></p>
50
+
51
+ <ul>
52
+ <li>
53
+ <?php echo __('Pick a URL from your sitemap and purge it:', 'litespeed-cache'); ?><br />
54
+ <?php echo __('Navigate to <b>LiteSpeed Cache > Manage > Purge By… > URL</b> and enter the full URL in the text box.', 'litespeed-cache'); ?>
55
+ </li>
56
+ <li>
57
+ <?php echo __('Manually run the crawler:', 'litespeed-cache'); ?><br />
58
+ <?php echo __('Navigate to <b>LiteSpeed Cache > Crawler</b>, make sure <b>Activation</b> is set to Enable, and press the <b>Manually run</b> button. Wait for it to finish.', 'litespeed-cache'); ?>
59
+ </li>
60
+ <li>
61
+ <?php echo __('See if the purged URL was cached during the crawl:', 'litespeed-cache'); ?><br />
62
+ <?php echo __('Turn on your browser’s Developer Tool/Inspector. Visit the URL that should have been crawled. Select the <b>Network</b> tab in the inspector, select the page request (the URL we just visited - it should be the first entry in the list), and select the <b>Header</b> tab. If the URL was crawled correctly, you will see the response header X-LiteSpeed-Cache: hit.', 'litespeed-cache'); ?>
63
+ </li>
64
+ </ul>
65
+ </div>
66
+
67
+ <h5><?php echo sprintf(__('If you don’t see X-LiteSpeed-Cache: hit, and you can’t figure out why the crawler didn’t cache the purged URL, you can visit <a %s>our support forum</a> for help.', 'litespeed-cache'), 'href="https://wordpress.org/support/plugin/litespeed-cache" target="_blank"'); ?></h5>
admin/tpl/info_faqs.php ADDED
@@ -0,0 +1,110 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if (!defined('WPINC')) die;
3
+ ?>
4
+ <h3 class="litespeed-title">
5
+ <?php echo __('LiteSpeed Cache FAQs', 'litespeed-cache'); ?>
6
+ <a href="javascript:;" class="litespeed-expend" data-litespeed-expend-all="faqs">+</a>
7
+ </h3>
8
+
9
+ <h4 class="litespeed-question litespeed-down"><?php echo __('Is the LiteSpeed Cache Plugin for WordPress free?', 'litespeed-cache'); ?></h4>
10
+ <div class="litespeed-answer">
11
+ <p>
12
+ <?php echo __('Yes, the plugin itself will remain free and open source.', 'litespeed-cache'); ?>
13
+ <?php echo __('That said, a LiteSpeed server is required (see question 2)', 'litespeed-cache'); ?>
14
+ </p>
15
+ </div>
16
+
17
+ <h4 class="litespeed-question litespeed-down"><?php echo __('What server software is required for this plugin?', 'litespeed-cache'); ?></h4>
18
+ <div class="litespeed-answer">
19
+ <p><?php echo __('A LiteSpeed server is required in order to use this plugin.', 'litespeed-cache'); ?></p>
20
+ <ol>
21
+ <li>LiteSpeed Web Server Enterprise with LSCache Module (v5.0.10+)</li>
22
+ <li>OpenLiteSpeed (v1.4.17+)</li>
23
+ <li>LiteSpeed WebADC (v2.0+)</li>
24
+ </ol>
25
+ <p><?php echo __('Any single server or cluster including a LiteSpeed server will work.', 'litespeed-cache'); ?>
26
+ </div>
27
+
28
+ <h4 class="litespeed-question litespeed-down"><?php echo __('Does this plugin work in a clustered environment?', 'litespeed-cache'); ?></h4>
29
+ <div class="litespeed-answer">
30
+ <p>
31
+ <?php echo __('The cache entries are stored at the litespeed server level.', 'litespeed-cache'); ?>
32
+ <?php echo __('The simplest solution is to use LiteSpeed WebADC, as the cache entries will be cached at that level.', 'litespeed-cache'); ?>
33
+ </p>
34
+ <p>
35
+ <?php echo __('If using another load balancer, the cache entries will only be stored at the backend nodes, not at the load balancer.', 'litespeed-cache'); ?>
36
+ <?php echo __('The purges will also not be synchronized across the nodes, so this is not recommended.', 'litespeed-cache'); ?>
37
+ </p>
38
+ <p>
39
+ <?php echo sprintf(__('If a customized solution is required, please contact %s at %s', 'litespeed-cache'),
40
+ 'LiteSpeed Technologies', 'info@litespeedtech.com'); ?>
41
+ </p>
42
+ <p><?php echo __('NOTICE: The rewrite rules created by this plugin must be copied to the WebADC', 'litespeed-cache'); ?></p>
43
+ </div>
44
+
45
+ <h4 class="litespeed-question litespeed-down"><?php echo __('Where are the cache entries stored?', 'litespeed-cache'); ?></h4>
46
+ <div class="litespeed-answer">
47
+ <p><?php echo __('The actual cached pages are stored and managed by LiteSpeed Servers. Nothing is stored on the PHP side.', 'litespeed-cache'); ?></p>
48
+ </div>
49
+
50
+ <h4 class="litespeed-question litespeed-down"><?php echo __('Is WooCommerce supported?', 'litespeed-cache'); ?></h4>
51
+ <div class="litespeed-answer">
52
+ <p>
53
+ <?php echo __('In short, yes.', 'litespeed-cache'); ?>
54
+ <?php echo __('However, for some woocommerce themes, the cart may not be updated correctly.', 'litespeed-cache'); ?>
55
+ </p>
56
+ <p><b><?php echo __('To test the cart:', 'litespeed-cache'); ?></b></p>
57
+ <ul>
58
+ <li><?php echo __('On a non-logged-in browser, visit and cache a page, then visit and cache a product page.', 'litespeed-cache'); ?></li>
59
+ <li><?php echo __('The first page should be accessible from the product page (e.g. the shop).', 'litespeed-cache'); ?></li>
60
+ <li><?php echo __('Once both pages are confirmed cached, add the product to the cart.', 'litespeed-cache'); ?></li>
61
+ <li><?php echo __('After adding to the cart, visit the first page.', 'litespeed-cache'); ?></li>
62
+ <li><?php echo __('The page should still be cached, and the cart should be up to date.', 'litespeed-cache'); ?></li>
63
+ <li><?php echo __('If that is not the case, please add woocommerce_items_in_cart to the do not cache cookie list.', 'litespeed-cache'); ?></li>
64
+ </ul>
65
+ <p>
66
+ <?php echo __('Some themes like Storefront and Shop Isle are built such that the cart works without the rule.', 'litespeed-cache'); ?>
67
+ <?php echo __('However, other themes like the E-Commerce theme, do not, so please verify the theme used.', 'litespeed-cache'); ?>
68
+ </p>
69
+ </div>
70
+
71
+ <h4 class="litespeed-question litespeed-down"><?php echo __('Are my images optimized?', 'litespeed-cache'); ?></h4>
72
+ <div class="litespeed-answer">
73
+ <p>
74
+ <?php echo __('The cache plugin does not do anything with the images themselves.', 'litespeed-cache'); ?>
75
+ <?php echo sprintf(__('We recommend you trying an image optimization plugin like %s to optimize your images.', 'litespeed-cache'),
76
+ '<a href="https://shortpixel.com/h/af/CXNO4OI28044" rel="friend noopener noreferer" target="_blank">ShortPixel</a>'); ?>
77
+ <?php echo __("It can reduce your site's images up to 90%.", 'litespeed-cache'); ?>
78
+ </p>
79
+ </div>
80
+
81
+ <h4 class="litespeed-question litespeed-down"><?php echo __('How do I get WP-PostViews to display an updating view count?', 'litespeed-cache'); ?></h4>
82
+ <div class="litespeed-answer">
83
+ <ol>
84
+ <li><?php echo sprintf(__('Use %1$s to replace %2$s', 'litespeed-cache'),
85
+ '<code>&lt;div id="postviews_lscwp"&gt;&lt;/div&gt;</code>',
86
+ '<code>&lt;?php if(function_exists(\'the_views\')) { the_views(); } ?&gt;</code>'); ?>
87
+ <ul>
88
+ <li><?php echo __('NOTE: The id can be changed, but the div id and the ajax function must match.', 'litespeed-cache'); ?></li>
89
+ </ul>
90
+ </li>
91
+ <li><?php echo sprintf(__('Replace the ajax query in %1$s with %2$s', 'litespeed-cache'),
92
+ '<code>wp-content/plugins/wp-postviews/postviews-cache.js</code>',
93
+ '<textarea id="wpwrap" rows="11" readonly>jQuery.ajax({
94
+ type:"GET",
95
+ url:viewsCacheL10n.admin_ajax_url,
96
+ data:"postviews_id="+viewsCacheL10n.post_id+"&amp;action=postviews",
97
+ cache:!1,
98
+ success:function(data) {
99
+ if(data) {
100
+ jQuery(\'#postviews_lscwp\').html(data+\' views\');
101
+ }
102
+ }
103
+ });</textarea>'); ?>
104
+ </li>
105
+ <li>
106
+ <?php echo __('Purge the cache to use the updated pages.', 'litespeed-cache'); ?>
107
+ </li>
108
+ </ol>
109
+ </div>
110
+
admin/tpl/manage.php ADDED
@@ -0,0 +1,201 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if (!defined('WPINC')) die;
3
+
4
+ LiteSpeed_Cache_Admin_Display::get_instance()->check_license();
5
+
6
+ ?>
7
+
8
+ <div class="wrap">
9
+ <h2>
10
+ <?php echo __('LiteSpeed Cache Management', 'litespeed-cache'); ?>
11
+ <span class="litespeed-desc">
12
+ v<?php echo LiteSpeed_Cache::PLUGIN_VERSION ; ?>
13
+ </span>
14
+ </h2>
15
+ </div>
16
+ <div class="wrap">
17
+ <div class="litespeed-cache-welcome-panel">
18
+ <p><?php echo __('From this screen, one can inform the server to purge the selected cached pages or empty the entire cache.', 'litespeed-cache'); ?></p>
19
+
20
+
21
+ <table class="form-table"><tbody>
22
+ <tr>
23
+ <th><?php echo __('Purge the Front Page.', 'litespeed-cache'); ?></th>
24
+ <td>
25
+ <a href="<?php echo LiteSpeed_Cache_Admin_Display::build_url(LiteSpeed_Cache::ACTION_PURGE_FRONT); ?>" class="litespeed-btn litespeed-btn-success">
26
+ <?php echo __('Purge Front Page', 'litespeed-cache'); ?>
27
+ </a>
28
+ <div class="litespeed-desc">
29
+ <?php echo __('This will Purge Front Page only', 'litespeed-cache'); ?>
30
+ </div>
31
+ </td>
32
+ </tr>
33
+
34
+ <tr>
35
+ <th><?php echo __('Purge Pages.', 'litespeed-cache'); ?></th>
36
+ <td>
37
+ <a href="<?php echo LiteSpeed_Cache_Admin_Display::build_url(LiteSpeed_Cache::ACTION_PURGE_PAGES); ?>" class="litespeed-btn litespeed-btn-success">
38
+ <?php echo __('Purge Pages', 'litespeed-cache'); ?>
39
+ </a>
40
+ <div class="litespeed-desc">
41
+ <?php echo __('This will Purge Pages only', 'litespeed-cache'); ?>
42
+ </div>
43
+ </td>
44
+ </tr>
45
+
46
+ <tr>
47
+ <th><?php echo __('Purge the error pages.', 'litespeed-cache'); ?></th>
48
+ <td>
49
+ <form method="post" action="admin.php?page=lscache-dash">
50
+ <?php $this->form_action(LiteSpeed_Cache::ACTION_PURGE_ERRORS); ?>
51
+
52
+ <div class="litespeed-row">
53
+ <?php $this->build_checkbox('include_403', __('Include 403', 'litespeed-cache'), 'checked', 'is_mini'); ?>
54
+ <?php $this->build_checkbox('include_404', __('Include 404', 'litespeed-cache'), false, 'is_mini'); ?>
55
+ <?php $this->build_checkbox('include_500', __('Include 500s', 'litespeed-cache'), 'checked', 'is_mini'); ?>
56
+ </div>
57
+
58
+ <div class="litespeed-row">
59
+ <button type="submit" class="litespeed-btn litespeed-btn-success">
60
+ <?php echo __('Purge Error Pages', 'litespeed-cache'); ?>
61
+ </button>
62
+ </div>
63
+
64
+ <div class="litespeed-desc">
65
+ <?php echo __('Purges the error page cache entries created by this plugin.', 'litespeed-cache'); ?>
66
+ </div>
67
+ </form>
68
+ </td>
69
+ </tr>
70
+
71
+ <tr>
72
+ <th><?php echo __('Purge all WordPress pages.', 'litespeed-cache'); ?></th>
73
+ <td>
74
+ <a href="<?php echo LiteSpeed_Cache_Admin_Display::build_url(LiteSpeed_Cache::ACTION_PURGE_ALL); ?>" class="litespeed-btn litespeed-btn-warning"
75
+ <?php if (is_multisite() && is_network_admin()): ?>
76
+ data-litespeed-cfm="<?php echo esc_html(__('This will purge everything for all blogs.', 'litespeed-cache')); ?> <?php echo esc_html(__('Are you sure you want to purge all?', 'litespeed-cache')); ?>"
77
+ <?php else: ?>
78
+ data-litespeed-cfm="<?php echo esc_html(__('Are you sure you want to purge all?', 'litespeed-cache')); ?>"
79
+ <?php endif; ?>
80
+ >
81
+ <?php echo __('Purge All', 'litespeed-cache'); ?>
82
+ </a>
83
+ <div class="litespeed-desc">
84
+ <?php echo __('Purge the cache entries created by this plugin.', 'litespeed-cache'); ?>
85
+ </div>
86
+ </td>
87
+ </tr>
88
+
89
+ <?php if (!is_multisite() || is_network_admin()): ?>
90
+ <tr>
91
+ <th><?php echo __('Clear all cache entries.', 'litespeed-cache'); ?></th>
92
+ <td>
93
+ <a href="<?php echo LiteSpeed_Cache_Admin_Display::build_url(LiteSpeed_Cache::ACTION_PURGE_EMPTYCACHE); ?>" class="litespeed-btn litespeed-btn-danger" data-litespeed-cfm="
94
+ <?php echo esc_html(__('This will clear EVERYTHING inside the cache.', 'litespeed-cache')); ?>
95
+ <?php echo esc_html(__('This may cause heavy load on the server.', 'litespeed-cache')); ?>
96
+ <?php echo esc_html(__('If only the WordPress site should be purged, use purge all.', 'litespeed-cache')); ?>
97
+ ">
98
+ <?php echo __('Empty Entire Cache', 'litespeed-cache'); ?>
99
+ </a>
100
+ <div class="litespeed-desc">
101
+ <?php echo __('Clears all cache entries related to this site, <i>including other web applications</i>.', 'litespeed-cache'); ?>
102
+ <?php echo __('<b>This action should only be used if things are cached incorrectly.</b>', 'litespeed-cache'); ?>
103
+ </div>
104
+ </td>
105
+ </tr>
106
+ <?php endif; ?>
107
+ </tbody></table>
108
+
109
+ <?php if (!is_multisite() || !is_network_admin()): ?>
110
+
111
+ <h3><?php echo __('Purge By...', 'litespeed-cache'); ?></h3>
112
+ <hr/>
113
+ <p>
114
+ <?php echo __('Select below for "Purge by" options.', 'litespeed-cache'); ?>
115
+ <?php echo __('Please enter one per line.', 'litespeed-cache'); ?>
116
+ </p>
117
+
118
+ <?php
119
+ $purgeby_option = false;
120
+ $_option_field = LiteSpeed_Cache_Admin_Display::PURGEBYOPT_SELECT;
121
+ if(!empty($_REQUEST[$_option_field])){
122
+ $purgeby_option = $_REQUEST[$_option_field];
123
+ }
124
+ if( !in_array($purgeby_option, array(
125
+ LiteSpeed_Cache_Admin_Display::PURGEBY_CAT,
126
+ LiteSpeed_Cache_Admin_Display::PURGEBY_PID,
127
+ LiteSpeed_Cache_Admin_Display::PURGEBY_TAG,
128
+ LiteSpeed_Cache_Admin_Display::PURGEBY_URL,
129
+ )) ) {
130
+ $purgeby_option = LiteSpeed_Cache_Admin_Display::PURGEBY_CAT;
131
+ }
132
+ ?>
133
+
134
+ <form method="post" action="admin.php?page=lscache-dash">
135
+ <?php $this->form_action(LiteSpeed_Cache::ACTION_PURGE_BY); ?>
136
+ <div class="litespeed-row">
137
+ <div class="litespeed-switch litespeed-label-info litespeed-mini">
138
+ <?php $val = LiteSpeed_Cache_Admin_Display::PURGEBY_CAT;?>
139
+ <input type="radio" name="<?php echo $_option_field; ?>" id="purgeby_option_category"
140
+ value="<?php echo $val; ?>" <?php if( $purgeby_option == $val ) echo 'checked'; ?>
141
+ />
142
+ <label for="purgeby_option_category"><?php echo __('Category', 'litespeed-cache'); ?></label>
143
+
144
+ <?php $val = LiteSpeed_Cache_Admin_Display::PURGEBY_PID;?>
145
+ <input type="radio" name="<?php echo $_option_field; ?>" id="purgeby_option_postid"
146
+ value="<?php echo $val; ?>" <?php if( $purgeby_option == $val ) echo 'checked'; ?>
147
+ />
148
+ <label for="purgeby_option_postid"><?php echo __('Post ID', 'litespeed-cache'); ?></label>
149
+
150
+ <?php $val = LiteSpeed_Cache_Admin_Display::PURGEBY_TAG;?>
151
+ <input type="radio" name="<?php echo $_option_field; ?>" id="purgeby_option_tag"
152
+ value="<?php echo $val; ?>" <?php if( $purgeby_option == $val ) echo 'checked'; ?>
153
+ />
154
+ <label for="purgeby_option_tag"><?php echo __('Tag', 'litespeed-cache'); ?></label>
155
+
156
+ <?php $val = LiteSpeed_Cache_Admin_Display::PURGEBY_URL;?>
157
+ <input type="radio" name="<?php echo $_option_field; ?>" id="purgeby_option_url"
158
+ value="<?php echo $val; ?>" <?php if( $purgeby_option == $val ) echo 'checked'; ?>
159
+ />
160
+ <label for="purgeby_option_url"><?php echo __('URL', 'litespeed-cache'); ?></label>
161
+ </div>
162
+
163
+ <div class="litespeed-cache-purgeby-text">
164
+ <div class="<?php if($purgeby_option != LiteSpeed_Cache_Admin_Display::PURGEBY_CAT) echo 'litespeed-hide'; ?>"
165
+ data-purgeby="<?php echo LiteSpeed_Cache_Admin_Display::PURGEBY_CAT; ?>">
166
+ <?php echo sprintf(__('Purge pages by category name - e.g. %2$s should be used for the URL %1$s.', "litespeed-cache"),
167
+ 'http://example.com/category/category-name/', 'category-name'); ?>
168
+ </div>
169
+ <div class="<?php if($purgeby_option != LiteSpeed_Cache_Admin_Display::PURGEBY_PID) echo 'litespeed-hide'; ?>"
170
+ data-purgeby="<?php echo LiteSpeed_Cache_Admin_Display::PURGEBY_PID; ?>">
171
+ <?php echo __("Purge pages by post ID.", "litespeed-cache"); ?>
172
+ </div>
173
+ <div class="<?php if($purgeby_option != LiteSpeed_Cache_Admin_Display::PURGEBY_TAG) echo 'litespeed-hide'; ?>"
174
+ data-purgeby="<?php echo LiteSpeed_Cache_Admin_Display::PURGEBY_TAG; ?>">
175
+ <?php echo sprintf(__('Purge pages by tag name - e.g. %2$s should be used for the URL %1$s.', "litespeed-cache"),
176
+ 'http://example.com/tag/tag-name/', 'tag-name'); ?>
177
+ </div>
178
+ <div class="<?php if($purgeby_option != LiteSpeed_Cache_Admin_Display::PURGEBY_URL) echo 'litespeed-hide'; ?>"
179
+ data-purgeby="<?php echo LiteSpeed_Cache_Admin_Display::PURGEBY_URL; ?>">
180
+ <?php echo __('Purge pages by relative or full URL.', 'litespeed-cache'); ?>
181
+ <?php echo sprintf(__('e.g. Use %s or %s.', 'litespeed-cache'),
182
+ '<b><u>/2016/02/24/hello-world/</u></b>',
183
+ '<b><u>http://www.myexamplesite.com/2016/02/24/hello-world/</u></b>'); ?>
184
+ </div>
185
+ </div>
186
+
187
+ </div>
188
+
189
+ <p>
190
+ <textarea name="<?php echo LiteSpeed_Cache_Admin_Display::PURGEBYOPT_LIST; ?>" rows="5" class="code litespeed-cache-purgeby-textarea"></textarea>
191
+ </p>
192
+
193
+ <p>
194
+ <button type="submit" class="litespeed-btn litespeed-btn-success"><?php echo __('Purge List', 'litespeed-cache'); ?></button>
195
+ </p>
196
+ </form>
197
+ <?php endif; ?>
198
+
199
+ </div>
200
+ </div>
201
+
admin/tpl/network_settings.php ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if (!defined('WPINC')) die;
3
+
4
+ $menuArr = array(
5
+ 'general' => __('General', 'litespeed-cache'),
6
+ 'cache' => __('Cache', 'litespeed-cache'),
7
+ 'purge' => __('Purge', 'litespeed-cache'),
8
+ 'excludes' => __('Excludes', 'litespeed-cache'),
9
+ 'advanced' => __('Advanced', 'litespeed-cache'),
10
+ );
11
+
12
+ global $_options;
13
+ $_options = LiteSpeed_Cache_Config::get_instance()->get_site_options();
14
+
15
+ ?>
16
+
17
+ <div class="wrap">
18
+ <h2>
19
+ <?php echo __('LiteSpeed Cache Network Settings', 'litespeed-cache'); ?>
20
+ <span class="litespeed-desc">
21
+ v<?php echo LiteSpeed_Cache::PLUGIN_VERSION; ?>
22
+ </span>
23
+ </h2>
24
+ </div>
25
+ <div class="wrap">
26
+ <h2 class="nav-tab-wrapper">
27
+ <?php
28
+ foreach ($menuArr as $tab => $val){
29
+ echo "<a class='nav-tab litespeed-tab' href='#$tab' data-litespeed-tab='$tab'>$val</a>";
30
+ }
31
+ ?>
32
+ </h2>
33
+ <div class="litespeed-cache-welcome-panel">
34
+ <form method="post" action="admin.php?page=lscache-settings" id="ls_form_options">
35
+ <?php
36
+ $this->form_action(LiteSpeed_Cache::ACTION_SAVE_SETTINGS_NETWORK);
37
+
38
+ // include all tpl for faster UE
39
+ foreach ($menuArr as $tab => $val) {
40
+ echo "<div data-litespeed-layout='$tab'>";
41
+ if($tab == 'advanced') {
42
+ require LSWCP_DIR . 'admin/tpl/settings_advanced.php';
43
+ }else{
44
+ require LSWCP_DIR . "admin/tpl/network_settings_$tab.php";
45
+ }
46
+ echo "</div>";
47
+ }
48
+
49
+ echo "<div class='litespeed-top20'></div>";
50
+
51
+ submit_button();
52
+
53
+ ?>
54
+ </form>
55
+ </div>
56
+ </div>
admin/tpl/network_settings_cache.php ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( ! defined( 'WPINC' ) ) die ;
3
+ ?>
4
+ <h3 class="litespeed-title"><?php echo __( 'Cache Control Network Settings', 'litespeed-cache' ) ; ?></h3>
5
+
6
+ <p>
7
+ <?php echo __( 'Separate Mobile Views should be enabled if any of the network enabled themes require a different view for mobile devices.', 'litespeed-cache' ) ; ?>
8
+ <?php echo __( 'Responsive themes can handle this part automatically.', 'litespeed-cache' ) ; ?>
9
+ </p>
10
+
11
+ <table class="form-table"><tbody>
12
+
13
+ <?php require LSWCP_DIR . 'admin/tpl/settings_inc.cache_favicon.php' ; ?>
14
+ <?php require LSWCP_DIR . 'admin/tpl/settings_inc.cache_resources.php' ; ?>
15
+ <?php require LSWCP_DIR . 'admin/tpl/settings_inc.cache_mobile.php' ; ?>
16
+
17
+ </tbody></table>
18
+
admin/tpl/network_settings_excludes.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if (!defined('WPINC')) die;
3
+
4
+ ?>
5
+ <h3 class="litespeed-title"><?php echo __('Network Do Not Cache Rules', 'litespeed-cache'); ?></h3>
6
+
7
+ <!-- User Agent List -->
8
+ <?php require LSWCP_DIR . 'admin/tpl/settings_inc.exclude_useragent.php'; ?>
9
+
10
+ <!-- Cookie List -->
11
+ <?php require LSWCP_DIR . 'admin/tpl/settings_inc.exclude_cookies.php'; ?>
admin/tpl/network_settings_general.php ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if (!defined('WPINC')) die;
3
+
4
+ ?>
5
+ <h3 class="litespeed-title"><?php echo __('General Network Configuration', 'litespeed-cache'); ?></h3>
6
+
7
+ <p><?php echo __('These configuration are only available network wide.', 'litespeed-cache'); ?></p>
8
+
9
+ <table class="form-table"><tbody>
10
+ <tr>
11
+ <th><?php echo __('Network Enable Cache', 'litespeed-cache'); ?></th>
12
+ <td>
13
+ <?php $this->build_switch(LiteSpeed_Cache_Config::NETWORK_OPID_ENABLED); ?>
14
+ <div class="litespeed-desc">
15
+ <?php echo __('Enabling LiteSpeed Cache for WordPress here enables the cache for the network.', 'litespeed-cache'); ?><br />
16
+ <?php echo __('It is <b>STRONGLY</b> recommend that the compatibility with other plugins on a single/few sites is tested first.', 'litespeed-cache'); ?>
17
+ <?php echo __('This is to ensure compatibility prior to enabling the cache for all sites.', 'litespeed-cache'); ?>
18
+ </div>
19
+ </td>
20
+ </tr>
21
+
22
+ <tr>
23
+ <th><?php echo __('Use Primary Site Configuration', 'litespeed-cache'); ?></th>
24
+ <td>
25
+ <?php $this->build_switch(LiteSpeed_Cache_Config::NETWORK_OPID_USE_PRIMARY); ?>
26
+ <div class="litespeed-desc">
27
+ <?php echo __("Check this option to use the primary site's configuration for all subsites.", 'litespeed-cache'); ?>
28
+ <?php echo __('This will disable the settings page on all subsites.', 'litespeed-cache'); ?>
29
+ </div>
30
+ </td>
31
+ </tr>
32
+
33
+ </tbody></table>
34
+
admin/tpl/network_settings_purge.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( ! defined( 'WPINC' ) ) die ;
3
+ ?>
4
+ <h3 class="litespeed-title"><?php echo __( 'Purge Network Settings', 'litespeed-cache' ) ; ?></h3>
5
+
6
+ <table class="form-table"><tbody>
7
+
8
+ <?php require LSWCP_DIR . 'admin/tpl/settings_inc.purge_on_upgrade.php' ; ?>
9
+
10
+ </tbody></table>
admin/tpl/report.php ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if (!defined('WPINC')) die;
3
+
4
+ $report = LiteSpeed_Cache_Admin_Report::get_instance()->generate_environment_report();
5
+ ?>
6
+
7
+ <div class="wrap">
8
+ <h2>
9
+ <?php echo __('LiteSpeed Cache Report', 'litespeed-cache'); ?>
10
+ <span class="litespeed-desc">
11
+ v<?php echo LiteSpeed_Cache::PLUGIN_VERSION; ?>
12
+ </span>
13
+ </h2>
14
+ </div>
15
+ <div class="wrap">
16
+ <div class="litespeed-cache-welcome-panel">
17
+ <ul>
18
+ <li><?php echo __('The environment report contains detailed information about the WordPress configuration.', 'litespeed-cache'); ?></li>
19
+ <li><?php echo __('If you run into any issues, please include the contents of this text area in your support message.', 'litespeed-cache'); ?></li>
20
+ <li><?php echo __('To easily grab the content, click the <b>Select All and Copy to Clipboard</b> button, to select and copy to clipboard.', 'litespeed-cache'); ?></li>
21
+ <?php if ( is_writable(LSWCP_DIR) ): ?>
22
+ <li><?php echo sprintf(__('Alternatively, this information is also saved in %s.', 'litespeed-cache'),
23
+ 'wp-content/plugins/litespeed-cache/environment_report.php'); ?></li>
24
+ <?php endif; ?>
25
+ </ul>
26
+ <p>
27
+ <b><?php echo __('The text area below contains the following content:', 'litespeed-cache'); ?></b>
28
+ </p>
29
+ <p>
30
+ <span style="font-size:11px; font-style:italic">
31
+ <?php echo __('Server Variables, Plugin Options, WordPress information (version, locale, active plugins, etc.), and .htaccess file content.', 'litespeed-cache'); ?>
32
+ </span>
33
+ </p>
34
+ <p>
35
+ <button class="litespeed-btn litespeed-btn-primary" id='litespeed_cache_report_copy'>
36
+ <?php echo __("Select All and Copy to Clipboard", "litespeed-cache"); ?>
37
+ </button>
38
+ <span class="litespeed-hide litespeed-notice" id="copy_select_all_span">
39
+ <?php echo __("Environment Report copied to Clipboard!", "litespeed-cache"); ?>
40
+ </span>
41
+ </p>
42
+ <textarea id="litespeed-report" rows="20" cols="80" readonly><?php echo $report; ?></textarea>
43
+ </div>
44
+ </div>
45
+
admin/tpl/settings.php ADDED
@@ -0,0 +1,141 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if (!defined('WPINC')) die ;
3
+
4
+ $this->check_license() ;
5
+
6
+ $menu_list = array(
7
+ 'general' => __('General', 'litespeed-cache'),
8
+ 'cache' => __('Cache', 'litespeed-cache'),
9
+ 'purge' => __('Purge', 'litespeed-cache'),
10
+ 'excludes' => __('Excludes', 'litespeed-cache'),
11
+ ) ;
12
+
13
+ if ( LSWCP_ESI_SUPPORT ) {
14
+ $menu_list['esi'] = __('ESI', 'litespeed-cache') ;
15
+ }
16
+
17
+ if (!is_multisite()) {
18
+ $menu_list['advanced'] = __('Advanced', 'litespeed-cache') ;
19
+ }
20
+
21
+ $menu_list['debug'] = __('Debug', 'litespeed-cache') ;
22
+
23
+ if ($this->show_compatibility_tab()){
24
+ $menu_list['compatibilities'] = __('Compatibilities', 'litespeed-cache') ;
25
+ }
26
+
27
+ $menu_list['crawler'] = __('Crawler', 'litespeed-cache') ;
28
+
29
+
30
+ global $_options ;
31
+ $_options = LiteSpeed_Cache_Config::get_instance()->get_options() ;
32
+
33
+
34
+ /**
35
+ * This hook allows third party plugins to create litespeed cache
36
+ * specific configuration.
37
+ *
38
+ * Each config should append an array containing the following:
39
+ * 'title' (required) - The tab's title.
40
+ * 'slug' (required) - The slug used for the tab. [a-z][A-Z], [0-9], -, _ permitted.
41
+ * 'content' (required) - The tab's content.
42
+ *
43
+ * Upon saving, only the options with the option group in the input's
44
+ * name will be retrieved.
45
+ * For example, name="litespeed-cache-conf[my-opt]".
46
+ *
47
+ * @see TODO: add option save filter.
48
+ * @since 1.0.9
49
+ * @param array $tabs An array of third party configuration.
50
+ * @param array $options The current configuration options.
51
+ * @param string $option_group The option group to use for options.
52
+ * @param boolean $disableall Whether to disable the settings or not.
53
+ * @return mixed An array of third party configs else false on failure.
54
+ */
55
+ $tp_tabs = apply_filters('litespeed_cache_add_config_tab',
56
+ array(),
57
+ $_options,
58
+ LiteSpeed_Cache_Config::OPTION_NAME,
59
+ $this->get_disable_all()
60
+ ) ;
61
+ if ( !empty($tp_tabs) && is_array($tp_tabs) ) {
62
+ foreach ($tp_tabs as $key => $tab) {
63
+ if ( !is_array($tab) || !isset($tab['title']) || !isset($tab['slug']) || !isset($tab['content']) ) {
64
+ if (LiteSpeed_Cache_Log::get_enabled()) {
65
+ LiteSpeed_Cache_Log::push(__('WARNING: Third party tab input invalid.', 'litespeed-cache')) ;
66
+ }
67
+ unset($tp_tabs[$key]) ;
68
+ continue ;
69
+ }
70
+ if ( preg_match('/[^-\w]/', $tab['slug']) ) {
71
+ if (LiteSpeed_Cache_Log::get_enabled()) {
72
+ LiteSpeed_Cache_Log::push(__('WARNING: Third party config slug contains invalid characters.', 'litespeed-cache')) ;
73
+ }
74
+ unset($tp_tabs[$key]) ;
75
+ continue ;
76
+ }
77
+ }
78
+ }
79
+ else {
80
+ $tp_tabs = array() ;
81
+ }
82
+
83
+
84
+ ?>
85
+ <div class="wrap">
86
+ <h2>
87
+ <?php echo __('LiteSpeed Cache Settings', 'litespeed-cache') ; ?>
88
+ <span class="litespeed-desc">
89
+ v<?php echo LiteSpeed_Cache::PLUGIN_VERSION ; ?>
90
+ </span>
91
+ </h2>
92
+ </div>
93
+ <div class="wrap">
94
+ <h2 class="nav-tab-wrapper">
95
+ <?php
96
+ foreach ($menu_list as $tab => $val){
97
+ echo "<a class='nav-tab litespeed-tab' href='#$tab' data-litespeed-tab='$tab'>$val</a>" ;
98
+ }
99
+ foreach ($tp_tabs as $val){
100
+ echo "<a class='nav-tab litespeed-tab' href='#$val[slug]' data-litespeed-tab='$val[slug]'>$val[title]</a>" ;
101
+ }
102
+ ?>
103
+ </h2>
104
+ <div class="litespeed-cache-welcome-panel">
105
+ <form method="post" action="options.php" id="litespeed_form_options">
106
+ <!--input type="hidden" name="<?php echo LiteSpeed_Cache::ACTION_KEY ; ?>" value="<?php echo LiteSpeed_Cache::ACTION_SAVE_SETTINGS ; ?>" /-->
107
+
108
+ <?php if ($this->get_disable_all()): ?>
109
+ <p>
110
+ <?php echo __('The network admin selected use primary site configs for all subsites.', 'litespeed-cache') ; ?>
111
+ <?php echo __('The following options are selected, but are not editable in this settings page.', 'litespeed-cache') ; ?>
112
+ </p>
113
+ <?php endif ; ?>
114
+
115
+ <?php
116
+ settings_fields(LiteSpeed_Cache_Config::OPTION_NAME) ;
117
+
118
+ // include all tpl for faster UE
119
+ foreach ($menu_list as $tab => $val) {
120
+ echo "<div data-litespeed-layout='$tab'>" ;
121
+ require LSWCP_DIR . "admin/tpl/settings_$tab.php" ;
122
+ echo "</div>" ;
123
+ }
124
+
125
+ foreach ($tp_tabs as $val) {
126
+ echo "<div data-litespeed-layout='$val[slug]'>$val[content]</div>" ;
127
+ }
128
+
129
+ echo "<div class='litespeed-top20'></div>" ;
130
+
131
+ if ($this->get_disable_all()) {
132
+ submit_button(__('Save Changes', 'litespeed-cache'), 'primary', 'litespeed-submit', true, array('disabled' => true)) ;
133
+ }
134
+ else {
135
+ submit_button(__('Save Changes', 'litespeed-cache'), 'primary', 'litespeed-submit') ;
136
+ }
137
+
138
+ ?>
139
+ </form>
140
+ </div>
141
+ </div>
admin/tpl/settings_advanced.php ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if (!defined('WPINC')) die;
3
+
4
+ ?>
5
+ <div class="litespeed-callout litespeed-callout-danger">
6
+ <h4><?php echo __('NOTICE:', 'litespeed-cache'); ?></h4>
7
+ <ol>
8
+ <li><?php echo __('These settings are meant for ADVANCED USERS ONLY.', 'litespeed-cache'); ?></li>
9
+ <li><?php echo __('Please take great care when changing any of these settings.', 'litespeed-cache'); ?></li>
10
+ <li><?php echo __('If there are any questions, do not hesitate to submit a support thread.', 'litespeed-cache'); ?></li>
11
+ </ol>
12
+ </div>
13
+
14
+ <h3 class="litespeed-title"><?php echo __('Check Advanced Cache', 'litespeed-cache'); ?></h3>
15
+ <?php
16
+ $id = LiteSpeed_Cache_Config::OPID_CHECK_ADVANCEDCACHE;
17
+ $this->build_checkbox($id, __('Include advanced-cache.php', 'litespeed-cache'), $_options[$id]);
18
+ ?>
19
+ <div class="litespeed-row litespeed-top10">
20
+ <?php echo __('The advanced-cache.php file is used by many caching plugins to signal that a cache is active.', 'litespeed-cache'); ?>
21
+ <?php echo __('When this option is checked and this file is detected as belonging to another plugin, LiteSpeed Cache will not cache.', 'litespeed-cache'); ?>
22
+ </div>
23
+ <div class="litespeed-row litespeed-top10">
24
+ <i><?php echo __('Uncheck this option only if the other plugin is used for non-caching purposes, such as minifying css/js files.', 'litespeed-cache'); ?></i>
25
+ </div>
26
+
27
+ <h3 class="litespeed-title"><?php echo __('Login Cookie', 'litespeed-cache'); ?></h3>
28
+ <?php
29
+
30
+ echo __('SYNTAX: alphanumeric and "_".', 'litespeed-cache')
31
+ . ' ' . __('No spaces and case sensitive.', 'litespeed-cache')
32
+ . ' ' . __('MUST BE UNIQUE FROM OTHER WEB APPLICATIONS.', 'litespeed-cache')
33
+ . '<p>'
34
+ . sprintf(__('The default login cookie is %s.', 'litespeed-cache'), '_lscache_vary')
35
+ . ' ' . __('The server will determine if the user is logged in based on the existance of this cookie.', 'litespeed-cache')
36
+ . ' ' . __('This setting is useful for those that have multiple web applications for the same domain.', 'litespeed-cache')
37
+ . ' ' . __('If every web application uses the same cookie, the server may confuse whether a user is logged in or not.', 'litespeed-cache')
38
+ . ' ' . __('The cookie set here will be used for this WordPress installation.', 'litespeed-cache')
39
+ . '</p>'
40
+ . '<p>'
41
+ . __('Example use case:', 'litespeed-cache')
42
+ . '<br />'
43
+ . sprintf(__('There is a WordPress installed for %s.', 'litespeed-cache'), '<u>www.example.com</u>')
44
+ . '<br />'
45
+ . sprintf(__('Then another WordPress is installed (NOT MULTISITE) at %s', 'litespeed-cache'), '<u>www.example.com/blog/</u>')
46
+ . ' ' . __('The cache needs to distinguish who is logged into which WordPress site in order to cache correctly.', 'litespeed-cache')
47
+ . '</p>';
48
+
49
+ $cookie_rule = LiteSpeed_Cache_Admin_Rules::get_instance()->get_rewrite_rule_login_cookie();
50
+ if ( $cookie_rule && substr($cookie_rule, 0, 11) !== 'Cache-Vary:' ){
51
+ echo '<p class="attention">'
52
+ . sprintf(__('Error: invalid login cookie. Please check the %s file', 'litespeed-cache'), '.htaccess')
53
+ . '</p>';
54
+ }
55
+
56
+ $id = LiteSpeed_Cache_Config::OPID_LOGIN_COOKIE;
57
+ if ( $_options[LiteSpeed_Cache_Config::OPID_ENABLED] && $_options[$id] ){
58
+
59
+ if (!$cookie_rule){
60
+ echo '<p class="attention">'
61
+ . sprintf(__('Error getting current rules from %s: %s', 'litespeed-cache'), '.htaccess', LiteSpeed_Cache_Admin_Rules::MARKER_LOGIN_COOKIE)
62
+ . '</p>';
63
+ }
64
+ else{
65
+ $cookie_rule = substr($cookie_rule, 11);
66
+ $cookie_arr = explode(',', $cookie_rule);
67
+ if(!in_array($_options[$id], $cookie_arr)) {
68
+ echo '<div class="litespeed-callout litespeed-callout-warning">'.
69
+ __('WARNING: The .htaccess login cookie and Database login cookie do not match.', 'litespeed-cache').
70
+ '</div>';
71
+ }
72
+ }
73
+
74
+ }
75
+
76
+ $file_writable = LiteSpeed_Cache_Admin_Rules::writable();
77
+ $this->build_input($id, 'litespeed-input-long');// , !$file_writable
78
+
79
+
admin/tpl/settings_cache.php ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( ! defined( 'WPINC' ) ) die ;
3
+ ?>
4
+ <h3 class="litespeed-title"><?php echo __( 'Cache Control Settings', 'litespeed-cache' ) ; ?></h3>
5
+
6
+ <table class="form-table"><tbody>
7
+ <tr>
8
+ <th><?php echo __( 'Cache Logged-in Users', 'litespeed-cache' ) ; ?></th>
9
+ <td>
10
+ <?php $this->build_switch( LiteSpeed_Cache_Config::OPID_CACHE_PRIV ) ; ?>
11
+ <div class="litespeed-desc">
12
+ <?php echo sprintf( __( 'Privately cache frontend pages for logged-in users. (LSWS %s required)', 'litespeed-cache' ), 'v5.2.1+' ) ; ?>
13
+ </div>
14
+ </td>
15
+ </tr>
16
+
17
+ <tr>
18
+ <th><?php echo __( 'Cache Commenters', 'litespeed-cache' ) ; ?></th>
19
+ <td>
20
+ <?php $this->build_switch( LiteSpeed_Cache_Config::OPID_CACHE_COMMENTER ) ; ?>
21
+ <div class="litespeed-desc">
22
+ <?php echo sprintf( __( 'Privately cache commenters that have pending comments. Disabling this option will serve non-cacheable pages to commenters. (LSWS %s required)', 'litespeed-cache' ), 'v5.2.1+' ) ; ?>
23
+ </div>
24
+ </td>
25
+ </tr>
26
+
27
+ <tr>
28
+ <th><?php echo __( 'Cache REST API', 'litespeed-cache' ) ; ?></th>
29
+ <td>
30
+ <?php $this->build_switch( LiteSpeed_Cache_Config::OPID_CACHE_REST ) ; ?>
31
+ <div class="litespeed-desc">
32
+ <?php echo __( 'Cache requests made by WordPress REST API calls.', 'litespeed-cache' ) ; ?>
33
+ </div>
34
+ </td>
35
+ </tr>
36
+
37
+ <tr>
38
+ <th><?php echo __( 'Cache Login Page', 'litespeed-cache' ) ; ?></th>
39
+ <td>
40
+ <?php $this->build_switch( LiteSpeed_Cache_Config::OPID_CACHE_PAGE_LOGIN ) ; ?>
41
+ <div class="litespeed-desc">
42
+ <?php echo __( 'Disabling this option may negatively affect performance.', 'litespeed-cache' ) ; ?>
43
+ </div>
44
+ </td>
45
+ </tr>
46
+
47
+ <?php
48
+ if ( ! is_multisite() ) :
49
+ require LSWCP_DIR . 'admin/tpl/settings_inc.cache_favicon.php' ;
50
+ require LSWCP_DIR . 'admin/tpl/settings_inc.cache_resources.php' ;
51
+ require LSWCP_DIR . 'admin/tpl/settings_inc.cache_mobile.php' ;
52
+ endif ;
53
+ ?>
54
+
55
+ </tbody></table>
56
+
admin/tpl/settings_compatibilities.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if (!defined('WPINC')) die;
3
+
4
+ if (!LiteSpeed_Cache_Admin_Display::get_instance()->show_compatibility_tab()) return;
5
+ ?>
6
+
7
+ <h3 class="litespeed-title"><?php echo __('Compatibility with WP-PostViews', 'litespeed-cache'); ?></h3>
8
+
9
+ <p><?php echo __('To make LiteSpeed Cache compatible with WP-PostViews:', 'litespeed-cache'); ?></p>
10
+
11
+ <ol>
12
+ <li>
13
+ <p><?php echo __('Replace the following calls in the active theme\'s template files with a div or span with a unique ID.', 'litespeed-cache'); ?></p>
14
+ <p><?php echo sprintf(__('e.g. Replace <br> <pre>%1$s</pre> with<br> <pre>%2$s</pre>', 'litespeed-cache'),
15
+ htmlspecialchars('<?php if(function_exists(\'the_views\' )) { the_views(); } ?>'),
16
+ htmlspecialchars('<div id="postviews_lscwp" > </div>')
17
+ ); ?>
18
+ </p>
19
+ </li>
20
+ <li>
21
+ <p><?php echo __('Update the ajax request to output the results to that div.', 'litespeed-cache'); ?></p>
22
+ <p><?php echo __('Example:', 'litespeed-cache'); ?></p>
23
+ <pre>jQuery.ajax({
24
+ type:"GET",
25
+ url:viewsCacheL10n.admin_ajax_url,
26
+ data:"postviews_id="+viewsCacheL10n.post_id+"&action=postviews",
27
+ cache:!1,
28
+ success:function(data) {
29
+ if(data) {
30
+ jQuery(\'#postviews_lscwp\').html(data+\' views\');
31
+ }
32
+ }
33
+ });</pre>
34
+ <p><?php echo __('The ajax code can be found at', 'litespeed-cache'); ?></p>
35
+ <pre>/wp-content/plugins/wp-postviews/postviews-cache.js</pre>
36
+ </li>
37
+ <li><?php echo __('After purging the cache, the view count should be updating.', 'litespeed-cache'); ?></li>
38
+ </ol>
admin/tpl/settings_crawler.php ADDED
@@ -0,0 +1,196 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( !defined('WPINC') ) die;
3
+
4
+ ?>
5
+
6
+ <h3 class="litespeed-title"><?php echo __('Crawler Settings', 'litespeed-cache'); ?></h3>
7
+
8
+ <table class="form-table"><tbody>
9
+ <tr>
10
+ <th><?php echo __('Delay', 'litespeed-cache'); ?></th>
11
+ <td>
12
+ <?php $id = LiteSpeed_Cache_Config::CRWL_USLEEP ; ?>
13
+ <?php $this->build_input($id); ?> <?php echo __('microseconds', 'litespeed-cache'); ?>
14
+ <div class="litespeed-desc">
15
+ <?php echo __('Specify time in microseconds for the delay between requests during a crawl.', 'litespeed-cache'); ?>
16
+ <?php $this->recommended($id) ; ?>
17
+ </div>
18
+ </td>
19
+ </tr>
20
+
21
+ <tr>
22
+ <th><?php echo __('Run Duration', 'litespeed-cache'); ?></th>
23
+ <td>
24
+ <?php $id = LiteSpeed_Cache_Config::CRWL_RUN_DURATION ; ?>
25
+ <?php $this->build_input($id); ?> <?php echo __('seconds', 'litespeed-cache'); ?>
26
+ <div class="litespeed-desc">
27
+ <?php echo __('Specify time in seconds for the duration of the crawl interval.', 'litespeed-cache'); ?>
28
+ <?php $this->recommended($id) ; ?>
29
+ </div>
30
+ </td>
31
+ </tr>
32
+
33
+ <tr>
34
+ <th><?php echo __('Interval Between Runs', 'litespeed-cache'); ?></th>
35
+ <td>
36
+ <?php $id = LiteSpeed_Cache_Config::CRWL_RUN_INTERVAL ; ?>
37
+ <?php $this->build_input($id); ?> <?php echo __('seconds', 'litespeed-cache'); ?>
38
+ <div class="litespeed-desc">
39
+ <?php echo __('Specify time in seconds for the time between each run interval. Must be greater than 60.', 'litespeed-cache'); ?>
40
+ <?php $this->recommended($id) ; ?>
41
+ </div>
42
+ </td>
43
+ </tr>
44
+
45
+ <tr>
46
+ <th><?php echo __('Crawl Interval', 'litespeed-cache'); ?></th>
47
+ <td>
48
+ <?php $id = LiteSpeed_Cache_Config::CRWL_CRAWL_INTERVAL ; ?>
49
+ <?php $this->build_input($id); ?> <?php echo __('seconds', 'litespeed-cache'); ?>
50
+ <div class="litespeed-desc">
51
+ <?php echo __('Specify how long in seconds before the crawler should initiate crawling the entire sitemap again.', 'litespeed-cache'); ?>
52
+ <?php $this->recommended($id) ; ?>
53
+ </div>
54
+ </td>
55
+ </tr>
56
+
57
+ <tr>
58
+ <th><?php echo __('Threads', 'litespeed-cache'); ?></th>
59
+ <td>
60
+ <?php $id = LiteSpeed_Cache_Config::CRWL_THREADS ; ?>
61
+ <?php $this->build_input($id); ?>
62
+ <div class="litespeed-desc">
63
+ <?php echo __('Specify Number of Threads to use while crawling.', 'litespeed-cache'); ?>
64
+ <?php $this->recommended($id) ; ?>
65
+ </div>
66
+ </td>
67
+ </tr>
68
+
69
+ <tr>
70
+ <th><?php echo __('Server Load Limit', 'litespeed-cache'); ?></th>
71
+ <td>
72
+ <?php $id = LiteSpeed_Cache_Config::CRWL_LOAD_LIMIT ; ?>
73
+ <?php $this->build_input($id); ?>
74
+ <div class="litespeed-desc">
75
+ <?php echo __( 'The maximum average server load allowed while crawling. The number of crawler threads in use will be actively reduced until average server load falls under this limit. If this cannot be achieved with a single thread, the current crawler run will be terminated.', 'litespeed-cache' ) ;
76
+ ?>
77
+ <?php $this->recommended($id) ; ?>
78
+ </div>
79
+ </td>
80
+ </tr>
81
+
82
+ <tr>
83
+ <th><?php echo __('Site IP', 'litespeed-cache'); ?></th>
84
+ <td>
85
+ <?php $id = LiteSpeed_Cache_Config::CRWL_DOMAIN_IP ; ?>
86
+ <?php $this->build_input($id); ?>
87
+ <div class="litespeed-desc">
88
+ <?php echo __('Enter this site\'s IP address to crawl by IP instead of domain name. This eliminates the overhead of DNS and CDN lookups. (optional)', 'litespeed-cache'); ?>
89
+ </div>
90
+ </td>
91
+ </tr>
92
+
93
+ <tr>
94
+ <th><?php echo __('Custom Sitemap', 'litespeed-cache'); ?></th>
95
+ <td>
96
+ <?php $id = LiteSpeed_Cache_Config::CRWL_CUSTOM_SITEMAP ; ?>
97
+ <?php $this->build_input($id, false, false, false, 'litespeed_custom_sitemap'); ?>
98
+ <div class="litespeed-desc">
99
+ <?php echo __('The crawler can use your Google XML Sitemap instead of its own. Enter the full URL to your sitemap here.', 'litespeed-cache'); ?>
100
+ </div>
101
+ </td>
102
+ </tr>
103
+
104
+ <tr data-litespeed-selfsitemap="1">
105
+ <th><?php echo __('Include Posts', 'litespeed-cache'); ?></th>
106
+ <td>
107
+ <?php $this->build_switch(LiteSpeed_Cache_Config::CRWL_POSTS); ?>
108
+ <div class="litespeed-desc">
109
+ <?php echo __('Include Posts in crawler sitemap generation.', 'litespeed-cache'); ?>
110
+ </div>
111
+ </td>
112
+ </tr>
113
+
114
+ <tr data-litespeed-selfsitemap="1">
115
+ <th><?php echo __('Include Pages', 'litespeed-cache'); ?></th>
116
+ <td>
117
+ <?php $this->build_switch(LiteSpeed_Cache_Config::CRWL_PAGES); ?>
118
+ <div class="litespeed-desc">
119
+ <?php echo __('Include Pages in crawler sitemap generation.', 'litespeed-cache'); ?>
120
+ </div>
121
+ </td>
122
+ </tr>
123
+
124
+ <tr data-litespeed-selfsitemap="1">
125
+ <th><?php echo __('Include Categories', 'litespeed-cache'); ?></th>
126
+ <td>
127
+ <?php $this->build_switch(LiteSpeed_Cache_Config::CRWL_CATS); ?>
128
+ <div class="litespeed-desc">
129
+ <?php echo __('Include Categories pages in crawler sitemap generation.', 'litespeed-cache'); ?>
130
+ </div>
131
+ </td>
132
+ </tr>
133
+
134
+ <tr data-litespeed-selfsitemap="1">
135
+ <th><?php echo __('Include Tags', 'litespeed-cache'); ?></th>
136
+ <td>
137
+ <?php $this->build_switch(LiteSpeed_Cache_Config::CRWL_TAGS); ?>
138
+ <div class="litespeed-desc">
139
+ <?php echo __('Include Tags pages in crawler sitemap generation.', 'litespeed-cache'); ?>
140
+ </div>
141
+ </td>
142
+ </tr>
143
+
144
+ <tr data-litespeed-selfsitemap="1">
145
+ <th><?php echo __('Exclude Custom Post Types', 'litespeed-cache'); ?></th>
146
+ <td>
147
+ <?php $this->build_textarea(LiteSpeed_Cache_Config::CRWL_EXCLUDES_CPT); ?>
148
+
149
+ <div class="litespeed-desc">
150
+ <?php echo __('If you want to exclude certain Custom Post Types in sitemap, add the Custom Post Types in the box, one per line.', 'litespeed-cache'); ?>
151
+ </div>
152
+
153
+ <div class="litespeed-callout litespeed-callout-warning">
154
+ <h4><?php echo __('Available Custom Post Type','litespeed-cache'); ?></h4>
155
+ <?php echo implode('<br />', array_diff(get_post_types( '', 'names' ), array('post', 'page'))); ?>
156
+ </div>
157
+ </td>
158
+ </tr>
159
+
160
+ <tr data-litespeed-selfsitemap="1">
161
+ <th><?php echo __('Order links by', 'litespeed-cache'); ?></th>
162
+ <td>
163
+ <div class="litespeed-row">
164
+ <div class="litespeed-switch litespeed-label-info">
165
+ <?php echo $this->build_radio(
166
+ LiteSpeed_Cache_Config::CRWL_ORDER_LINKS,
167
+ LiteSpeed_Cache_Config::CRWL_DATE_DESC,
168
+ __('Date, descending (Default)', 'litespeed-cache')
169
+ ); ?>
170
+
171
+ <?php echo $this->build_radio(
172
+ LiteSpeed_Cache_Config::CRWL_ORDER_LINKS,
173
+ LiteSpeed_Cache_Config::CRWL_DATE_ASC,
174
+ __('Date, ascending', 'litespeed-cache')
175
+ ); ?>
176
+
177
+ <?php echo $this->build_radio(
178
+ LiteSpeed_Cache_Config::CRWL_ORDER_LINKS,
179
+ LiteSpeed_Cache_Config::CRWL_ALPHA_DESC,
180
+ __('Alphabetical, descending', 'litespeed-cache')
181
+ ); ?>
182
+
183
+ <?php echo $this->build_radio(
184
+ LiteSpeed_Cache_Config::CRWL_ORDER_LINKS,
185
+ LiteSpeed_Cache_Config::CRWL_ALPHA_ASC,
186
+ __('Alphabetical, ascending', 'litespeed-cache')
187
+ ); ?>
188
+ </div>
189
+ </div>
190
+ <div class="litespeed-desc">
191
+ <?php echo __('Please choose one of the above options to set the order in which the sitemap will be parsed.', 'litespeed-cache'); ?>
192
+ </div>
193
+ </td>
194
+ </tr>
195
+
196
+ </tbody></table>
admin/tpl/settings_debug.php ADDED
@@ -0,0 +1,161 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( ! defined( 'WPINC' ) ) die ;
3
+
4
+ ?>
5
+
6
+ <h3 class="litespeed-title"><?php echo __( 'Developer Testing', 'litespeed-cache' ) ; ?></h3>
7
+
8
+ <table class="form-table"><tbody>
9
+ <tr>
10
+ <th><?php echo __( 'Debug Log', 'litespeed-cache' ) ; ?></th>
11
+ <td>
12
+ <div class="litespeed-row">
13
+ <div class="litespeed-switch litespeed-label-info">
14
+ <?php echo $this->build_radio(
15
+ LiteSpeed_Cache_Config::OPID_DEBUG,
16
+ LiteSpeed_Cache_Config::VAL_OFF,
17
+ __( 'Off', 'litespeed-cache' )
18
+ ) ; ?>
19
+
20
+ <?php echo $this->build_radio(
21
+ LiteSpeed_Cache_Config::OPID_DEBUG,
22
+ LiteSpeed_Cache_Config::VAL_ON,
23
+ __( 'On', 'litespeed-cache' )
24
+ ) ; ?>
25
+
26
+ <?php echo $this->build_radio(
27
+ LiteSpeed_Cache_Config::OPID_DEBUG,
28
+ LiteSpeed_Cache_Config::VAL_NOTSET,
29
+ __( 'Admin IP only', 'litespeed-cache' )
30
+ ) ; ?>
31
+ </div>
32
+ </div>
33
+ <div class="litespeed-desc">
34
+ <?php echo __( 'Outputs to WordPress debug log.', 'litespeed-cache' ) ; ?>
35
+ <?php echo __( 'This should be set to off once everything is working to prevent filling the disk.', 'litespeed-cache' ) ; ?>
36
+ <?php echo __( 'The Admin IP option will only output log messages on requests from admin IPs.', 'litespeed-cache' ) ; ?>
37
+ <?php echo __( 'The logs will be outputted to the debug.log in the wp-content directory.', 'litespeed-cache' ) ; ?>
38
+ </div>
39
+ </td>
40
+ </tr>
41
+
42
+ <tr>
43
+ <th><?php echo __( 'Admin IPs', 'litespeed-cache' ) ; ?></th>
44
+ <td>
45
+ <?php $this->build_textarea( LiteSpeed_Cache_Config::OPID_ADMIN_IPS, null, false, 30 ) ; ?>
46
+ <div class="litespeed-desc">
47
+ <?php echo __( 'Allows listed IPs (one per line) to perform certain actions from their browsers.', 'litespeed-cache' ) ; ?><br />
48
+ <?php echo sprintf( __( 'More information about the available commands can be found <a href="%s">here</a>.', 'litespeed-cache' ),
49
+ get_admin_url() . 'admin.php?page=lscache-info#admin_ip' ) ; ?>
50
+ </div>
51
+ </td>
52
+ </tr>
53
+
54
+ <tr>
55
+ <th><?php echo __( 'Debug Level', 'litespeed-cache' ) ; ?></th>
56
+ <td>
57
+ <div class="litespeed-row">
58
+ <div class="litespeed-switch litespeed-label-info">
59
+ <?php echo $this->build_radio(
60
+ LiteSpeed_Cache_Config::OPID_DEBUG_LEVEL,
61
+ LiteSpeed_Cache_Config::VAL_OFF,
62
+ __( 'Basic', 'litespeed-cache' )
63
+ ) ; ?>
64
+
65
+ <?php echo $this->build_radio(
66
+ LiteSpeed_Cache_Config::OPID_DEBUG_LEVEL,
67
+ LiteSpeed_Cache_Config::VAL_ON,
68
+ __( 'Advanced', 'litespeed-cache' )
69
+ ) ; ?>
70
+ </div>
71
+ </div>
72
+ <div class="litespeed-desc">
73
+ <?php echo __( 'Advanced level will log more details.', 'litespeed-cache' ) ; ?>
74
+ </div>
75
+ </td>
76
+ </tr>
77
+
78
+ <tr>
79
+ <th><?php echo __( 'Log File Size Limit', 'litespeed-cache' ) ; ?></th>
80
+ <td>
81
+ <?php $id = LiteSpeed_Cache_Config::OPID_LOG_FILE_SIZE ; ?>
82
+ <?php $this->build_input( $id, 'small-text' ) ; ?> <?php echo __( 'MB', 'litespeed-cache' ) ; ?>
83
+ <div class="litespeed-desc">
84
+ <?php echo __( 'Specify the maximum size of the log file. Minimum is 3MB. Maximum is 3000MB.', 'litespeed-cache' ) ; ?>
85
+ <?php $this->recommended( $id ) ; ?>
86
+ </div>
87
+ </td>
88
+ </tr>
89
+
90
+ <tr>
91
+ <th><?php echo __( 'Heartbeat', 'litespeed-cache' ) ; ?></th>
92
+ <td>
93
+ <?php $this->build_switch( LiteSpeed_Cache_Config::OPID_HEARTBEAT ) ; ?>
94
+ <div class="litespeed-desc">
95
+ <?php echo __( 'Disable WordPress heartbeat to prevent AJAX calls from breaking debug logging. WARNING: Disabling this may cause WordPress tasks triggered by AJAX to stop working.', 'litespeed-cache' ) ; ?>
96
+ </div>
97
+ </td>
98
+ </tr>
99
+
100
+ <tr>
101
+ <th><?php echo __( 'Log Cookies', 'litespeed-cache' ) ; ?></th>
102
+ <td>
103
+ <?php $this->build_switch( LiteSpeed_Cache_Config::OPID_DEBUG_COOKIE ) ; ?>
104
+ <div class="litespeed-desc">
105
+ <?php echo __( 'Log request cookie values.', 'litespeed-cache' ) ; ?>
106
+ </div>
107
+ </td>
108
+ </tr>
109
+
110
+ <tr>
111
+ <th><?php echo __( 'Collapse Query Strings', 'litespeed-cache' ) ; ?></th>
112
+ <td>
113
+ <?php $this->build_switch( LiteSpeed_Cache_Config::OPID_COLLAPS_QS ) ; ?>
114
+ <div class="litespeed-desc">
115
+ <?php echo __( 'Shorten query strings in the debug log to improve readability.', 'litespeed-cache' ) ; ?>
116
+ </div>
117
+ </td>
118
+ </tr>
119
+
120
+ <tr>
121
+ <th><?php echo __( 'Log Filters', 'litespeed-cache' ) ; ?></th>
122
+ <td>
123
+ <?php $this->build_switch( LiteSpeed_Cache_Config::OPID_LOG_FILTERS ) ; ?>
124
+ <div class="litespeed-desc">
125
+ <?php echo __( 'Log all WordPress filter hooks. WARNING: Enabling this option will cause log file size to grow quickly.', 'litespeed-cache' ) ; ?>
126
+ </div>
127
+ </td>
128
+ </tr>
129
+
130
+ <tr>
131
+ <th><?php echo __( 'Exclude Filters', 'litespeed-cache' ) ; ?></th>
132
+ <td>
133
+ <?php $this->build_textarea( LiteSpeed_Cache_Config::OPID_LOG_IGNORE_FILTERS, null, false, 30 ) ; ?>
134
+ <div class="litespeed-desc">
135
+ <?php echo __( 'Listed filters (one per line) will not be logged.', 'litespeed-cache' ) ; ?><br />
136
+ </div>
137
+ </td>
138
+ </tr>
139
+
140
+ <tr>
141
+ <th><?php echo __( 'Exclude Part Filters', 'litespeed-cache' ) ; ?></th>
142
+ <td>
143
+ <?php $this->build_textarea( LiteSpeed_Cache_Config::OPID_LOG_IGNORE_PART_FILTERS, null, false, 30 ) ; ?>
144
+ <div class="litespeed-desc">
145
+ <?php echo __( 'Filters containing these strings (one per line) will not be logged.', 'litespeed-cache' ) ; ?><br />
146
+ </div>
147
+ </td>
148
+ </tr>
149
+
150
+ </tbody></table>
151
+
152
+ <?php
153
+
154
+ /* Maybe add this feature later
155
+ $id = LiteSpeed_Cache_Config::OPID_TEST_IPS;
156
+ $input_test_ips = $this->input_field_text($id, $options[$id], '', 'regular-text');
157
+ $buf .= $this->display_config_row('Test IPs', $input_test_ips,
158
+ 'Enable LiteSpeed Cache only for specified IPs. (Space or comma separated.)
159
+ * Allows testing on a live site. If empty, cache will be served to everyone.');
160
+ *
161
+ */
admin/tpl/settings_esi.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( !defined('WPINC') ) die;
3
+ // comments
4
+ // comment form
5
+ // admin bar
6
+
7
+ ?>
8
+
9
+ <h3 class="litespeed-title"><?php echo __('ESI Settings', 'litespeed-cache'); ?></h3>
10
+
11
+ <p><?php echo __('ESI enables the capability to cache pages for logged in users/commenters.', 'litespeed-cache'); ?></p>
12
+ <p><?php echo __('ESI functions by replacing the private information blocks with an ESI include.', 'litespeed-cache'); ?></p>
13
+ <p><?php echo __('When the server sees an ESI include, a sub request is created, containing the private information.', 'litespeed-cache'); ?></p>
14
+
15
+ <table class="form-table"><tbody>
16
+ <tr>
17
+ <th><?php echo __('Enable ESI', 'litespeed-cache'); ?></th>
18
+ <td>
19
+ <?php $this->build_switch(LiteSpeed_Cache_Config::OPID_ESI_ENABLE); ?>
20
+ <div class="litespeed-desc">
21
+ <?php echo __('Enabling ESI will cache the public page for logged in users.', 'litespeed-cache'); ?>
22
+ <?php echo __('The Admin Bar, comments, and comment form will be served via ESI blocks.', 'litespeed-cache'); ?>
23
+ <?php echo __('The ESI blocks will not be cached until Cache ESI is checked.', 'litespeed-cache'); ?>
24
+ </div>
25
+ </td>
26
+ </tr>
27
+
28
+ <tr>
29
+ <th><?php echo __('Cache ESI', 'litespeed-cache'); ?></th>
30
+ <td>
31
+ <?php $this->build_switch(LiteSpeed_Cache_Config::OPID_ESI_CACHE); ?>
32
+ <div class="litespeed-desc">
33
+ <?php echo __('Cache the ESI blocks.', 'litespeed-cache'); ?>
34
+ </div>
35
+ </td>
36
+ </tr>
37
+
38
+ </tbody></table>
admin/tpl/settings_excludes.php ADDED
@@ -0,0 +1,111 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if (!defined('WPINC')) die;
3
+
4
+ ?>
5
+
6
+ <!-- URI List -->
7
+ <h3 class="litespeed-title"><?php echo __('URI List', 'litespeed-cache'); ?></h3>
8
+ <ol>
9
+ <li><?php echo __('Enter a list of urls that should not be cached.', 'litespeed-cache'); ?></li>
10
+ <li><?php echo __('The urls will be compared to the REQUEST_URI server variable.', 'litespeed-cache'); ?></li>
11
+ <li><?php echo __('There should only be one url per line.', 'litespeed-cache'); ?></li>
12
+ </ol>
13
+ <div class="litespeed-callout litespeed-callout-warning">
14
+ <h4><?php echo __('NOTE:', 'litespeed-cache'); ?></h4>
15
+ <ol>
16
+ <li><?php echo __('URLs must start with a \'/\' to be correctly matched.', 'litespeed-cache'); ?></li>
17
+ <li><?php echo __('To do an exact match, add \'$\' to the end of the URL.', 'litespeed-cache'); ?></li>
18
+ <li><?php echo __('Any surrounding whitespaces will be trimmed.', 'litespeed-cache'); ?></li>
19
+ <li><?php echo sprintf(__('e.g. to exclude %1$s, insert %2$s', 'litespeed-cache'),
20
+ 'http://www.example.com/excludethis.php', '/excludethis.php'); ?></li>
21
+ <li><?php echo sprintf(__('Similarly, to exclude %1$s(accessed with the /blog), insert %2$s', 'litespeed-cache'),
22
+ 'http://www.example.com/blog/excludethis.php', '/blog/excludethis.php'); ?></li>
23
+ </ol>
24
+ </div>
25
+ <div class="litespeed-desc">
26
+ <i>
27
+ <?php echo __('SYNTAX: URLs must start with a \'/\' to be correctly matched.', 'litespeed-cache'); ?><br />
28
+ <?php echo __('To do an exact match, add \'$\' to the end of the URL. One URL per line.', 'litespeed-cache'); ?>
29
+ </i>
30
+ </div>
31
+ <?php $this->build_textarea(LiteSpeed_Cache_Config::OPID_EXCLUDES_URI); ?>
32
+
33
+ <!-- Category List -->
34
+ <h3 class="litespeed-title"><?php echo __('Category List', 'litespeed-cache'); ?></h3>
35
+ <ol>
36
+ <li><b><?php echo __('All categories are cached by default.', 'litespeed-cache'); ?></b></li>
37
+ <li><?php echo __('To prevent a category from being cached, enter it in the text area below, one per line.', 'litespeed-cache'); ?></li>
38
+ </ol>
39
+ <div class="litespeed-callout litespeed-callout-warning">
40
+ <h4><?php echo __('NOTE:', 'litespeed-cache'); ?></h4>
41
+ <ol>
42
+ <li><?php echo __('If the Category ID is not found, the name will be removed on save.', 'litespeed-cache'); ?></li>
43
+ <li><?php echo sprintf(__('e.g. to exclude %1$s, insert %2$s', 'litespeed-cache'),
44
+ '<code style="font-size: 11px;">http://www.example.com/category/category-id/</code>', 'category-id'); ?></li>
45
+ </ol>
46
+ </div>
47
+ <div class="litespeed-desc">
48
+ <i>
49
+ <?php echo __('SYNTAX: One category id per line.', 'litespeed-cache'); ?>
50
+ </i>
51
+ </div>
52
+ <?php
53
+ $id = LiteSpeed_Cache_Config::OPID_EXCLUDES_CAT;
54
+ $excludes_buf = '';
55
+ $cat_ids = $_options[$id];
56
+ if ($cat_ids != '') {
57
+ $id_list = explode(',', $cat_ids);
58
+ $excludes_buf = implode("\n", array_map('get_cat_name', $id_list));
59
+ }
60
+ $this->build_textarea($id, $excludes_buf);
61
+ ?>
62
+
63
+ <!-- Tag List -->
64
+ <h3 class="litespeed-title"><?php echo __('Tag List', 'litespeed-cache'); ?></h3>
65
+ <ol>
66
+ <li><b><?php echo __('All tags are cached by default.', 'litespeed-cache'); ?></b></li>
67
+ <li><?php echo __('To prevent tags from being cached, enter the tag in the text area below, one per line.', 'litespeed-cache'); ?></li>
68
+ </ol>
69
+ <div class="litespeed-callout litespeed-callout-warning">
70
+ <h4><?php echo __('NOTE:', 'litespeed-cache'); ?></h4>
71
+ <ol>
72
+ <li><?php echo __('If the Tag ID is not found, the name will be removed on save.', 'litespeed-cache'); ?></li>
73
+ <li><?php echo sprintf(__('e.g. to exclude %1$s, insert %2$s', 'litespeed-cache'),
74
+ 'http://www.example.com/tag/category/tag-id/', 'tag-id'); ?></li>
75
+ </ol>
76
+ </div>
77
+ <div class="litespeed-desc">
78
+ <i>
79
+ <?php echo __('SYNTAX: One tag id per line.', 'litespeed-cache'); ?>
80
+ </i>
81
+ </div>
82
+ <?php
83
+ $id = LiteSpeed_Cache_Config::OPID_EXCLUDES_TAG;
84
+ $excludes_buf = '';
85
+ $ids = $_options[$id];
86
+ if ($ids != '') {
87
+ $id_list = explode(',', $ids);
88
+ $tags_list = array_map('get_tag', $id_list);
89
+ $tag_names = array();
90
+ foreach ($tags_list as $tag) {
91
+ $tag_names[] = $tag->name;
92
+ }
93
+ if (!empty($tag_names)) {
94
+ $excludes_buf = implode("\n", $tag_names);
95
+ }
96
+ }
97
+ $this->build_textarea($id, $excludes_buf);
98
+ ?>
99
+
100
+ <?php
101
+ if (is_multisite()) {
102
+ return;
103
+ }
104
+ ?>
105
+
106
+ <!-- Cookie List -->
107
+ <?php require LSWCP_DIR . 'admin/tpl/settings_inc.exclude_cookies.php'; ?>
108
+
109
+ <!-- User Agent List -->
110
+ <?php require LSWCP_DIR . 'admin/tpl/settings_inc.exclude_useragent.php'; ?>
111
+
admin/tpl/settings_general.php ADDED
@@ -0,0 +1,134 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if (!defined('WPINC')) die;
3
+
4
+ ?>
5
+ <h3 class="litespeed-title"><?php echo __('General', 'litespeed-cache'); ?></h3>
6
+
7
+ <table class="form-table"><tbody>
8
+ <tr>
9
+ <th><?php echo __('Enable LiteSpeed Cache', 'litespeed-cache'); ?></th>
10
+ <td>
11
+ <?php
12
+ $id = LiteSpeed_Cache_Config::OPID_ENABLED_RADIO;
13
+ //IF multisite: Add 'Use Network Admin' option,
14
+ //ELSE: Change 'Enable LiteSpeed Cache' selection to 'Enabled' if the 'Use Network Admin' option was previously selected.
15
+ // Selection will not actually be changed unless settings are saved.
16
+ if(!is_multisite() && intval($_options[$id]) === 2){
17
+ $_options[$id] = 1;
18
+ }
19
+ ?>
20
+ <div class="litespeed-row">
21
+ <div class="litespeed-switch litespeed-label-info">
22
+ <?php echo $this->build_radio(
23
+ $id,
24
+ LiteSpeed_Cache_Config::VAL_ON,
25
+ __('Enable', 'litespeed-cache')
26
+ ); ?>
27
+
28
+ <?php echo $this->build_radio(
29
+ $id,
30
+ LiteSpeed_Cache_Config::VAL_OFF,
31
+ __('Disable', 'litespeed-cache')
32
+ ); ?>
33
+
34
+ <?php
35
+ if ( is_multisite() ){
36
+ echo $this->build_radio(
37
+ $id,
38
+ LiteSpeed_Cache_Config::VAL_NOTSET,
39
+ __('Use Network Admin Setting', 'litespeed-cache')
40
+ );
41
+ }
42
+ ?>
43
+ </div>
44
+ </div>
45
+ <div class="litespeed-desc">
46
+ <?php echo sprintf(__('Please visit the <a %s>Information</a> page on how to test the cache.', 'litespeed-cache'),
47
+ 'href="'.get_admin_url().'admin.php?page=lscache-info"'); ?>
48
+
49
+ <strong><?php echo __('NOTICE', 'litespeed-cache'); ?>: </strong><?php echo __('When disabling the cache, all cached entries for this blog will be purged.', 'litespeed-cache'); ?>
50
+ <?php if ( is_multisite() ): ?>
51
+ <br><?php echo __('The network admin setting can be overridden here.', 'litespeed-cache'); ?>
52
+ <?php endif; ?>
53
+ </div>
54
+ </td>
55
+ </tr>
56
+
57
+ <tr>
58
+ <th><?php echo __('Default Public Cache TTL', 'litespeed-cache'); ?></th>
59
+ <td>
60
+ <?php $id = LiteSpeed_Cache_Config::OPID_PUBLIC_TTL ; ?>
61
+ <?php $this->build_input($id); ?> <?php echo __('seconds', 'litespeed-cache'); ?>
62
+ <div class="litespeed-desc">
63
+ <?php echo __('Specify how long, in seconds, public pages are cached. Minimum is 30 seconds.', 'litespeed-cache'); ?>
64
+ <?php $this->recommended($id) ; ?>
65
+ </div>
66
+ </td>
67
+ </tr>
68
+
69
+ <tr>
70
+ <th><?php echo __('Default Front Page TTL', 'litespeed-cache'); ?></th>
71
+ <td>
72
+ <?php $id = LiteSpeed_Cache_Config::OPID_FRONT_PAGE_TTL ; ?>
73
+ <?php $this->build_input($id); ?> <?php echo __('seconds', 'litespeed-cache'); ?>
74
+ <div class="litespeed-desc">
75
+ <?php echo __('Specify how long, in seconds, the front page is cached. Minimum is 30 seconds.', 'litespeed-cache'); ?>
76
+ <?php $this->recommended($id) ; ?>
77
+ </div>
78
+ </td>
79
+ </tr>
80
+
81
+ <tr>
82
+ <th><?php echo __('Default Feed TTL', 'litespeed-cache'); ?></th>
83
+ <td>
84
+ <?php $id = LiteSpeed_Cache_Config::OPID_FEED_TTL ; ?>
85
+ <?php $this->build_input($id); ?> <?php echo __('seconds', 'litespeed-cache'); ?>
86
+ <div class="litespeed-desc">
87
+ <?php echo __('Specify how long, in seconds, feeds are cached.', 'litespeed-cache'); ?>
88
+ <?php echo __('If this is set to a number less than 30, feeds will not be cached.', 'litespeed-cache'); ?>
89
+ <?php $this->recommended($id) ; ?>
90
+ </div>
91
+ </td>
92
+ </tr>
93
+
94
+ <tr>
95
+ <th><?php echo __('Default 404 Page TTL', 'litespeed-cache'); ?></th>
96
+ <td>
97
+ <?php $id = LiteSpeed_Cache_Config::OPID_404_TTL ; ?>
98
+ <?php $this->build_input($id); ?> <?php echo __('seconds', 'litespeed-cache'); ?>
99
+ <div class="litespeed-desc">
100
+ <?php echo __('Specify how long, in seconds, 404 pages are cached.', 'litespeed-cache'); ?>
101
+ <?php echo __('If this is set to a number less than 30, 404 pages will not be cached.', 'litespeed-cache'); ?>
102
+ <?php $this->recommended($id) ; ?>
103
+ </div>
104
+ </td>
105
+ </tr>
106
+
107
+ <tr>
108
+ <th><?php echo __('Default 403 Page TTL', 'litespeed-cache'); ?></th>
109
+ <td>
110
+ <?php $id = LiteSpeed_Cache_Config::OPID_403_TTL ; ?>
111
+ <?php $this->build_input($id); ?> <?php echo __('seconds', 'litespeed-cache'); ?>
112
+ <div class="litespeed-desc">
113
+ <?php echo __('Specify how long, in seconds, 403 pages are cached.', 'litespeed-cache'); ?>
114
+ <?php echo __('If this is set to a number less than 30, 403 pages will not be cached.', 'litespeed-cache'); ?>
115
+ <?php $this->recommended($id) ; ?>
116
+ </div>
117
+ </td>
118
+ </tr>
119
+
120
+ <tr>
121
+ <th><?php echo __('Default 500 Page TTL', 'litespeed-cache'); ?></th>
122
+ <td>
123
+ <?php $id = LiteSpeed_Cache_Config::OPID_500_TTL ; ?>
124
+ <?php $this->build_input($id); ?> <?php echo __('seconds', 'litespeed-cache'); ?>
125
+ <div class="litespeed-desc">
126
+ <?php echo __('Specify how long, in seconds, 500 pages are cached.', 'litespeed-cache'); ?>
127
+ <?php echo __('If this is set to a number less than 30, 500 pages will not be cached.', 'litespeed-cache'); ?>
128
+ <?php $this->recommended($id) ; ?>
129
+ </div>
130
+ </td>
131
+ </tr>
132
+
133
+ </tbody></table>
134
+
admin/tpl/settings_inc.cache_favicon.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if (!defined('WPINC')) die;
3
+
4
+ $file_writable = LiteSpeed_Cache_Admin_Rules::writable();
5
+ ?>
6
+ <tr>
7
+ <th><?php echo __('Cache favicon.ico', 'litespeed-cache'); ?></th>
8
+ <td>
9
+ <?php $this->build_switch(LiteSpeed_Cache_Config::OPID_CACHE_FAVICON);/*, !$file_writable*/ ?>
10
+ <div class="litespeed-desc">
11
+ <?php echo __('favicon.ico is requested on most pages.', 'litespeed-cache'); ?>
12
+ <?php echo __('Caching this recource may improve server performance by avoiding unnecessary PHP calls.', 'litespeed-cache'); ?>
13
+ </div>
14
+ </td>
15
+ </tr>
admin/tpl/settings_inc.cache_mobile.php ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if (!defined('WPINC')) die;
3
+
4
+ ?>
5
+
6
+ <!-- build_setting_mobile_view start -->
7
+ <tr>
8
+ <th><?php echo __('Cache Mobile', 'litespeed-cache'); ?></th>
9
+ <td>
10
+ <?php
11
+ $file_writable = LiteSpeed_Cache_Admin_Rules::writable();
12
+ $this->build_switch(LiteSpeed_Cache_Config::OPID_CACHE_MOBILE); //, !$file_writable
13
+ ?>
14
+ <div class="litespeed-desc">
15
+ <?php echo __('When enabled, mobile views will be cached separately.', 'litespeed-cache'); ?>
16
+ <?php echo __('A site built with responsive design does not need to check this.', 'litespeed-cache'); ?>
17
+ </div>
18
+ </td>
19
+ </tr>
20
+
21
+ <tr>
22
+ <th><?php echo __('List of Mobile User Agents', 'litespeed-cache'); ?></th>
23
+ <td>
24
+ <?php
25
+ $id = LiteSpeed_Cache_Config::ID_MOBILEVIEW_LIST;
26
+ $wp_default_mobile = 'Mobile|Android|Silk/|Kindle|BlackBerry|Opera\ Mini|Opera\ Mobi';
27
+ $cache_enable_id = is_network_admin() ? LiteSpeed_Cache_Config::NETWORK_OPID_ENABLED : LiteSpeed_Cache_Config::OPID_ENABLED;
28
+ $mobile_agents = '';
29
+ $input_value = $wp_default_mobile;
30
+
31
+ // if set, use value as input value
32
+ if ( $_options[$id] ){
33
+
34
+ $input_value = $_options[$id];
35
+
36
+ // if enabled, check the setting in file
37
+ if ( $_options[$cache_enable_id]){
38
+
39
+ $mobile_agents = LiteSpeed_Cache_Admin_Rules::get_instance()->get_rewrite_rule_mobile_agents();
40
+ $this->display_messages();
41
+ if ( $mobile_agents ){
42
+ $input_value = $mobile_agents;
43
+ }
44
+
45
+ if ( $mobile_agents !== $_options[$id] ){
46
+ echo '<p class="attention">'
47
+ . __('Htaccess did not match configuration option.', 'litespeed-cache')
48
+ . ' ' . __('Please re-enter the mobile view setting.', 'litespeed-cache')
49
+ . ' ' . sprintf(__('List in WordPress database is: %s', 'litespeed-cache'), '<b>' . $_options[$id] . '</b>')
50
+ . '</p>';
51
+ }
52
+ }
53
+ }
54
+
55
+ $this->build_input($id, 'large-text widget ui-draggable-dragging code', false, !$_options[$id], 'litespeed-mobileview-rules', $input_value);
56
+ ?>
57
+
58
+ <input type="hidden" name="<?php echo LiteSpeed_Cache_Config::OPTION_NAME; ?>[<?php echo $id; ?>__default]"
59
+ id="litespeed-mobileview-rules-default"
60
+ value="<?php echo esc_textarea($_options[$id] ?: $wp_default_mobile); ?>"
61
+ />
62
+
63
+ <div class="litespeed-desc">
64
+ <strong><?php echo __('NOTICE:', 'litespeed-cache'); ?></strong>
65
+ <?php echo __('This setting will edit the .htaccess file.', 'litespeed-cache'); ?><br />
66
+
67
+ <i>
68
+ <?php
69
+ echo sprintf(__('SYNTAX: Each entry should be separated with a bar, %s', 'litespeed-cache'), "'|'.")
70
+ . ' ' . sprintf(__('Any spaces should be escaped with a backslash before the space, %s', 'litespeed-cache'), "'\\ '.")
71
+ . '<br />'
72
+ . sprintf(__('The default list WordPress uses is %s', 'litespeed-cache'), "<b>$wp_default_mobile</b>");
73
+ ?>
74
+ </i>
75
+ </div>
76
+ </td>
77
+ </tr>
78
+ <!-- build_setting_mobile_view end -->
admin/tpl/settings_inc.cache_resources.php ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if (!defined('WPINC')) die;
3
+
4
+ $file_writable = LiteSpeed_Cache_Admin_Rules::writable();
5
+ ?>
6
+ <!-- build_setting_cache_resources -->
7
+ <tr>
8
+ <th><?php echo __('Cache PHP Resources', 'litespeed-cache'); ?></th>
9
+ <td>
10
+ <?php $this->build_switch(LiteSpeed_Cache_Config::OPID_CACHE_RES);/*, !$file_writable*/ ?>
11
+ <div class="litespeed-desc">
12
+ <?php echo __('Some themes and plugins add resources via a PHP request.', 'litespeed-cache'); ?>
13
+ <?php echo __('Caching these pages may improve server performance by avoiding unnecessary PHP calls.', 'litespeed-cache'); ?>
14
+ </div>
15
+ </td>
16
+ </tr>
admin/tpl/settings_inc.exclude_cookies.php ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!-- build_setting_exclude_cookies -->
2
+ <h3 class="litespeed-title"><?php echo __('Cookie List', 'litespeed-cache'); ?></h3>
3
+ <p><?php echo __('To prevent cookies from being cached, enter it in the text area below.', 'litespeed-cache'); ?></p>
4
+ <div class="litespeed-callout litespeed-callout-warning">
5
+ <h4><?php echo __('NOTE:', 'litespeed-cache'); ?></h4>
6
+ <ol>
7
+ <li><?php echo __('This setting will edit the .htaccess file.', 'litespeed-cache'); ?></li>
8
+ </ol>
9
+ </div>
10
+ <div class="litespeed-desc">
11
+ <i>
12
+ <?php echo __('SYNTAX: Cookies should be listed one per line.', 'litespeed-cache'); ?>
13
+ <?php echo sprintf(__('Spaces should have a backslash in front of them, %s', 'litespeed-cache'), "'\ '."); ?>
14
+ </i>
15
+ </div>
16
+
17
+ <?php
18
+
19
+ $id = LiteSpeed_Cache_Config::ID_NOCACHE_COOKIES;
20
+
21
+ $file_writable = LiteSpeed_Cache_Admin_Rules::writable();
22
+
23
+ $this->build_textarea($id, str_replace('|', "\n", $_options[$id]));//, !$file_writable
admin/tpl/settings_inc.exclude_useragent.php ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if (!defined('WPINC')) die;
3
+
4
+ ?>
5
+
6
+ <!-- build_setting_exclude_useragent -->
7
+ <h3 class="litespeed-title"><?php echo __('User Agent List', 'litespeed-cache'); ?></h3>
8
+ <p><?php echo __('To prevent user agents from being cached, enter it in the text field below.', 'litespeed-cache'); ?></p>
9
+ <div class="litespeed-callout litespeed-callout-warning">
10
+ <h4><?php echo __('NOTE:', 'litespeed-cache'); ?></h4>
11
+ <ol>
12
+ <li><?php echo __('This setting will edit the .htaccess file.', 'litespeed-cache'); ?></li>
13
+ </ol>
14
+ </div>
15
+ <div class="litespeed-desc">
16
+ <i>
17
+ <?php echo sprintf(__('SYNTAX: Separate each user agent with a bar, <font style="font-style:normal">%s</font>.', 'litespeed-cache'), "'|'"); ?>
18
+ <?php echo sprintf(__('Spaces should have a backslash in front of them, %s.', 'litespeed-cache'), "'\'"); ?>
19
+ </i>
20
+ </div>
21
+
22
+ <?php
23
+
24
+ $file_writable = LiteSpeed_Cache_Admin_Rules::writable();
25
+
26
+ $this->build_input(LiteSpeed_Cache_Config::ID_NOCACHE_USERAGENTS, 'litespeed-input-long');//, !$file_writable
admin/tpl/settings_inc.purge_on_upgrade.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if (!defined('WPINC')) die;
3
+
4
+ ?>
5
+ <!-- build_setting_purge_on_upgrade -->
6
+ <tr>
7
+ <th><?php echo __('Purge All on upgrade', 'litespeed-cache'); ?></th>
8
+ <td>
9
+ <?php $this->build_switch(LiteSpeed_Cache_Config::OPID_PURGE_ON_UPGRADE); ?>
10
+ <div class="litespeed-desc">
11
+ <?php echo __('When enabled, the cache will automatically purge when any plugins, themes, or WordPress core is upgraded.', 'litespeed-cache'); ?>
12
+ </div>
13
+ </td>
14
+ </tr>
admin/tpl/settings_purge.php ADDED
@@ -0,0 +1,97 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if (!defined('WPINC')) die;
3
+
4
+ ?>
5
+ <h3 class="litespeed-title"><?php echo __('Purge Settings', 'litespeed-cache'); ?></h3>
6
+
7
+ <?php
8
+ $purge_options = LiteSpeed_Cache_Config::get_instance()->get_purge_options();
9
+ $optionArr = array(
10
+ LiteSpeed_Cache_Config::PURGE_ALL_PAGES => __('All pages', 'litespeed-cache'),
11
+ LiteSpeed_Cache_Config::PURGE_FRONT_PAGE => __('Front page', 'litespeed-cache'),
12
+ LiteSpeed_Cache_Config::PURGE_HOME_PAGE => __('Home page', 'litespeed-cache'),
13
+ LiteSpeed_Cache_Config::PURGE_PAGES => __('Pages', 'litespeed-cache'),
14
+
15
+ LiteSpeed_Cache_Config::PURGE_PAGES_WITH_RECENT_POSTS => __('All pages with Recent Posts Widget', 'litespeed-cache'),
16
+
17
+ LiteSpeed_Cache_Config::PURGE_AUTHOR => __('Author archive', 'litespeed-cache'),
18
+ LiteSpeed_Cache_Config::PURGE_POST_TYPE => __('Post type archive', 'litespeed-cache'),
19
+
20
+ LiteSpeed_Cache_Config::PURGE_YEAR => __('Yearly archive', 'litespeed-cache'),
21
+ LiteSpeed_Cache_Config::PURGE_MONTH => __('Monthly archive', 'litespeed-cache'),
22
+ LiteSpeed_Cache_Config::PURGE_DATE => __('Daily archive', 'litespeed-cache'),
23
+
24
+ LiteSpeed_Cache_Config::PURGE_TERM => __('Term archive (include category, tag, and tax)', 'litespeed-cache'),
25
+ );
26
+
27
+ // break line at these ids
28
+ $breakArr = array(
29
+ LiteSpeed_Cache_Config::PURGE_PAGES,
30
+ LiteSpeed_Cache_Config::PURGE_PAGES_WITH_RECENT_POSTS,
31
+ LiteSpeed_Cache_Config::PURGE_POST_TYPE,
32
+ LiteSpeed_Cache_Config::PURGE_DATE,
33
+ );
34
+
35
+ ?>
36
+
37
+ <table class="form-table"><tbody>
38
+
39
+ <?php if (!is_multisite()): ?>
40
+ <?php require LSWCP_DIR . 'admin/tpl/settings_inc.purge_on_upgrade.php'; ?>
41
+ <?php endif; ?>
42
+
43
+ <tr>
44
+ <th><?php echo __('Auto Purge Rules For Publish/Update', 'litespeed-cache'); ?></th>
45
+ <td>
46
+ <div class="litespeed-desc">
47
+ <div class="litespeed-callout litespeed-callout-warning">
48
+ <h4><?php echo __('Note:', 'litespeed-cache'); ?></h4>
49
+ <i>
50
+ <?php echo __('Select "All" if there are dynamic widgets linked to posts on pages other than the front or home pages.', 'litespeed-cache'); ?><br />
51
+ <?php echo __('Other checkboxes will be ignored.', 'litespeed-cache'); ?><br />
52
+ <?php echo __('Select only the archive types that are currently used, the others can be left unchecked.', 'litespeed-cache'); ?>
53
+ </i>
54
+ </div>
55
+ </div>
56
+ <div class="litespeed-row litespeed-top20">
57
+ <?php
58
+ foreach ($optionArr as $id => $title){
59
+
60
+ $this->build_checkbox("purge_$id", $title, in_array($id, $purge_options));
61
+
62
+ if ( in_array($id, $breakArr) ){
63
+ echo '</div><div class="litespeed-row litespeed-top20">';
64
+ }
65
+ }
66
+ ?>
67
+ </div>
68
+ <div class="litespeed-desc">
69
+ <?php echo __('Select which pages will be automatically purged when posts are published/updated.', 'litespeed-cache'); ?>
70
+ </div>
71
+ </td>
72
+ </tr>
73
+
74
+ <tr>
75
+ <th><?php echo __( 'Scheduled Purge URLs', 'litespeed-cache' ) ; ?></th>
76
+ <td>
77
+ <?php $this->build_textarea( LiteSpeed_Cache_Config::OPID_TIMED_URLS, null, false, 80 ) ; ?>
78
+ <div class="litespeed-desc">
79
+ <?php echo sprintf( __( 'The URLs here (one per line) will be purged automatically at the time set in the option "%s".', 'litespeed-cache' ), __( 'Scheduled Purge Time', 'litespeed-cache' ) ) ; ?><br />
80
+ <?php echo sprintf( __( 'Both %1$s and %2$s are acceptable.', 'litespeed-cache' ), '<i>http://www.example.com/path/url.php</i>', '<i>/path/url.php</i>' ) ; ?>
81
+ </div>
82
+ </td>
83
+ </tr>
84
+
85
+ <tr>
86
+ <th><?php echo __( 'Scheduled Purge Time', 'litespeed-cache' ) ; ?></th>
87
+ <td>
88
+ <?php $id = LiteSpeed_Cache_Config::OPID_TIMED_URLS_TIME ; ?>
89
+ <?php $this->build_input( $id, '', false, false, null, null, '', 'time' ) ; ?>
90
+ <div class="litespeed-desc">
91
+ <?php echo sprintf( __( 'Specify the time to purge the "%s" list.', 'litespeed-cache' ), __( 'Scheduled Purge URLs', 'litespeed-cache' ) ) ; ?>
92
+ <?php echo sprintf( __( 'Current server time is %s.', 'litespeed-cache' ), '<i>' . date( 'H:i:s' ) . '</i>' ) ; ?>
93
+ </div>
94
+ </td>
95
+ </tr>
96
+ </tbody></table>
97
+
admin/tpl/show_display_installed.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if (!defined('WPINC')) die;
3
+
4
+
5
+ $buf = '<h3>'. __('LiteSpeed Cache plugin is installed!', 'litespeed-cache'). '</h3>' . ' '
6
+ . __('This message indicates that the plugin was installed by the server admin.', 'litespeed-cache') . ' '
7
+ . __('The LiteSpeed Cache plugin is used to cache pages - a simple way to improve the performance of the site.', 'litespeed-cache') . ' '
8
+ . __('However, there is no way of knowing all the possible customizations that were implemented.', 'litespeed-cache') . ' '
9
+ . __('For that reason, please test the site to make sure everything still functions properly.', 'litespeed-cache')
10
+ . '<br /><br />'
11
+ . __('Examples of test cases include:', 'litespeed-cache')
12
+ . '<ul>'
13
+ . '<li>' . __('Visit the site while logged out.', 'litespeed-cache') . '</li>'
14
+ . '<li>' . __('Create a post, make sure the front page is accurate.', 'litespeed-cache') . '</li>'
15
+ . '</ul>'
16
+ . sprintf(__('If there are any questions, the team is always happy to answer any questions on the <a %s>support forum</a>.', 'litespeed-cache'),
17
+ 'href="https://wordpress.org/support/plugin/litespeed-cache" rel="noopener noreferrer" target="_blank"')
18
+ . '<br />'
19
+ . __('If you would rather not move at litespeed, you can deactivate this plugin.', 'litespeed-cache');
20
+
21
+ self::add_notice(self::NOTICE_BLUE . ' lscwp-whm-notice', $buf);
admin/tpl/show_error_cookie.php ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if (!defined('WPINC')) die;
3
+
4
+ $err = __('NOTICE: Database login cookie did not match your login cookie.', 'litespeed-cache') . ' '
5
+ . __('If the login cookie was recently changed in the settings, please log out and back in.', 'litespeed-cache') . ' '
6
+ . sprintf(__('If not, please verify the setting in the <a href="%1$s">Advanced tab</a>.', 'litespeed-cache'),
7
+ admin_url('admin.php?page=lscache-settings#advanced'));
8
+
9
+ if (LITESPEED_SERVER_TYPE === 'LITESPEED_SERVER_OLS') {
10
+ $err .= ' ' . __('If using OpenLiteSpeed, the server must be restarted once for the changes to take effect.', 'litespeed-cache');
11
+ }
12
+
13
+ self::add_notice(self::NOTICE_YELLOW, $err);
admin/tpl/show_rule_conflict.php ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( ! defined( 'WPINC' ) ) die ;
3
+
4
+
5
+ $err = sprintf( __( 'Unexpected cache rule %2$s found in %1$s file. This rule may cause visitors to see old versions of pages due to the browser caching html pages. If you are sure that html pages are not being browser cached, this message can be dismissed. (<a %3$s>Learn More</a>)', 'litespeed-cache' ),
6
+ '.htaccess',
7
+ '`ExpiresDefault`',
8
+ 'href="https://www.litespeedtech.com/support/wiki/doku.php/litespeed_wiki:cache:lscwp:troubleshooting:browser_displays_stale_content" target="_blank"'
9
+ );
10
+
11
+ // other plugin left cache expired rules in .htaccess which will cause conflicts
12
+ echo self::build_notice( self::NOTICE_YELLOW . ' lscwp-notice-ruleconflict', $err ) ;
13
+
admin/tpl/snowman.inc.php ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ wp_enqueue_style('litespeed-cache-snowman', plugin_dir_url(__FILE__) . '../css/snowman.css');
3
+ ?>
4
+ <div class="olaf">
5
+ <div class="head">
6
+ <div class="top">
7
+ <div class="shadow"></div>
8
+ </div>
9
+ <div class="hair">
10
+ <span>
11
+ <span></span>
12
+ <span>
13
+ <span></span>
14
+ </span>
15
+ </span>
16
+ <span>
17
+ <span>
18
+ <span></span>
19
+ </span>
20
+ </span>
21
+ <span>
22
+ <span>
23
+ <span></span>
24
+ <span></span>
25
+ </span>
26
+ </span>
27
+ </div>
28
+ <div class="brow left"></div>
29
+ <div class="brow right"></div>
30
+ <div class="eye left">
31
+ <div class="pupil"></div>
32
+ </div>
33
+ <div class="eye right">
34
+ <div class="pupil"></div>
35
+ </div>
36
+ <div class="nose"></div>
37
+ <div class="mouth"></div>
38
+ <div class="top-lip"></div>
39
+ <div class="tooth"></div>
40
+ <div class="bottom-lip"></div>
41
+ </div>
42
+ <div class="body top">
43
+ <div class="button"></div>
44
+ </div>
45
+ <div class="body bottom">
46
+ <div class="button"></div>
47
+ <div class="button"></div>
48
+ </div>
49
+ <div class="arm left">
50
+ <div class="upper-arm">
51
+ <span></span>
52
+ <div class="lower-arm">
53
+ <span></span>
54
+ <div class="hand">
55
+ <span></span>
56
+ <div class="fingers">
57
+ <span></span>
58
+ <span></span>
59
+ <span></span>
60
+ <span></span>
61
+ </div>
62
+ </div>
63
+ </div>
64
+ </div>
65
+ </div>
66
+ <div class="arm right">
67
+ <div class="upper-arm">
68
+ <span></span>
69
+ <div class="lower-arm">
70
+ <span></span>
71
+ <div class="hand">
72
+ <span></span>
73
+ <div class="fingers">
74
+ <span></span>
75
+ <span></span>
76
+ <span></span>
77
+ <span></span>
78
+ </div>
79
+ </div>
80
+ </div>
81
+ </div>
82
+ </div>
83
+ <div class="foot left"></div>
84
+ <div class="foot right"></div>
85
+ <div class="shadow"></div>
86
+ </div>
cli/litespeed-cache-cli-admin.class.php ADDED
@@ -0,0 +1,323 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * LiteSpeed Cache Admin Interface
5
+ */
6
+ class LiteSpeed_Cache_Cli_Admin
7
+ {
8
+
9
+ private static $checkboxes ;
10
+ private static $purges ;
11
+
12
+ public function __construct()
13
+ {
14
+ self::$checkboxes = array(
15
+ LiteSpeed_Cache_Config::OPID_CACHE_PRIV,
16
+ LiteSpeed_Cache_Config::OPID_CACHE_COMMENTER,
17
+ LiteSpeed_Cache_Config::OPID_CACHE_REST,
18
+ LiteSpeed_Cache_Config::OPID_CACHE_PAGE_LOGIN,
19
+ LiteSpeed_Cache_Config::OPID_CACHE_MOBILE,
20
+ LiteSpeed_Cache_Config::OPID_PURGE_ON_UPGRADE,
21
+ LiteSpeed_Cache_Config::OPID_CACHE_FAVICON,
22
+ LiteSpeed_Cache_Config::OPID_CACHE_RES,
23
+ LiteSpeed_Cache_Config::OPID_CHECK_ADVANCEDCACHE,
24
+ LiteSpeed_Cache_Config::CRWL_POSTS,
25
+ LiteSpeed_Cache_Config::CRWL_PAGES,
26
+ LiteSpeed_Cache_Config::CRWL_CATS,
27
+ LiteSpeed_Cache_Config::CRWL_TAGS,
28
+ LiteSpeed_Cache_Config::CRWL_CRON_ACTIVE,
29
+ LiteSpeed_Cache_Config::OPID_DEBUG_LEVEL,
30
+ LiteSpeed_Cache_Config::OPID_HEARTBEAT,
31
+ LiteSpeed_Cache_Config::OPID_DEBUG_COOKIE,
32
+ LiteSpeed_Cache_Config::OPID_COLLAPS_QS,
33
+ LiteSpeed_Cache_Config::OPID_LOG_FILTERS,
34
+ ) ;
35
+ self::$purges = array(
36
+ 'purge_' . LiteSpeed_Cache_Config::PURGE_ALL_PAGES => LiteSpeed_Cache_Config::PURGE_ALL_PAGES,
37
+ 'purge_' . LiteSpeed_Cache_Config::PURGE_FRONT_PAGE => LiteSpeed_Cache_Config::PURGE_FRONT_PAGE,
38
+ 'purge_' . LiteSpeed_Cache_Config::PURGE_HOME_PAGE => LiteSpeed_Cache_Config::PURGE_HOME_PAGE,
39
+ 'purge_' . LiteSpeed_Cache_Config::PURGE_AUTHOR => LiteSpeed_Cache_Config::PURGE_AUTHOR,
40
+ 'purge_' . LiteSpeed_Cache_Config::PURGE_YEAR => LiteSpeed_Cache_Config::PURGE_YEAR,
41
+ 'purge_' . LiteSpeed_Cache_Config::PURGE_MONTH => LiteSpeed_Cache_Config::PURGE_MONTH,
42
+ 'purge_' . LiteSpeed_Cache_Config::PURGE_DATE => LiteSpeed_Cache_Config::PURGE_DATE,
43
+ 'purge_' . LiteSpeed_Cache_Config::PURGE_TERM => LiteSpeed_Cache_Config::PURGE_TERM,
44
+ 'purge_' . LiteSpeed_Cache_Config::PURGE_POST_TYPE => LiteSpeed_Cache_Config::PURGE_POST_TYPE,
45
+ ) ;
46
+ }
47
+
48
+ /**
49
+ * Set an individual LiteSpeed Cache option.
50
+ *
51
+ * ## OPTIONS
52
+ *
53
+ * <key>
54
+ * : The option key to update.
55
+ *
56
+ * <newvalue>
57
+ * : The new value to set the option to.
58
+ *
59
+ * ## EXAMPLES
60
+ *
61
+ * # Set to not cache the login page
62
+ * $ wp lscache-admin set_option cache_login false
63
+ *
64
+ */
65
+ public function set_option($args, $assoc_args)
66
+ {
67
+ $key = $args[0] ;
68
+ $val = $args[1] ;
69
+
70
+ $options = LiteSpeed_Cache_Config::get_instance()->get_options() ;
71
+
72
+ if ( ! isset($options) || ( ! isset($options[$key]) && ! isset(self::$purges[$key])) ) {
73
+ WP_CLI::error('The options array is empty or the key is not valid.') ;
74
+ return ;
75
+ }
76
+
77
+ $options = LiteSpeed_Cache_Config::convert_options_to_input($options) ;
78
+
79
+ switch ($key) {
80
+ case LiteSpeed_Cache_Config::OPID_VERSION:
81
+ //do not allow
82
+ WP_CLI::error('This option is not available for setting.') ;
83
+ return ;
84
+
85
+ case LiteSpeed_Cache_Config::OPID_CACHE_MOBILE:
86
+ // set list then do checkbox
87
+ if ( $val === 'true' ) {
88
+ $options[LiteSpeed_Cache_Config::ID_MOBILEVIEW_LIST] = 'Mobile|Android|Silk/|Kindle|BlackBerry|Opera\ Mini|Opera\ Mobi' ;
89
+ }
90
+ //fall through
91
+ case LiteSpeed_Cache_Config::OPID_CACHE_PRIV:
92
+ case LiteSpeed_Cache_Config::OPID_CACHE_COMMENTER:
93
+ case LiteSpeed_Cache_Config::OPID_CACHE_REST:
94
+ case LiteSpeed_Cache_Config::OPID_CACHE_PAGE_LOGIN:
95
+ case LiteSpeed_Cache_Config::OPID_PURGE_ON_UPGRADE:
96
+ case LiteSpeed_Cache_Config::OPID_CACHE_FAVICON:
97
+ case LiteSpeed_Cache_Config::OPID_CACHE_RES:
98
+ case LiteSpeed_Cache_Config::OPID_CHECK_ADVANCEDCACHE:
99
+ case LiteSpeed_Cache_Config::CRWL_POSTS:
100
+ case LiteSpeed_Cache_Config::CRWL_PAGES:
101
+ case LiteSpeed_Cache_Config::CRWL_CATS:
102
+ case LiteSpeed_Cache_Config::CRWL_TAGS:
103
+ case LiteSpeed_Cache_Config::CRWL_CRON_ACTIVE:
104
+ case LiteSpeed_Cache_Config::OPID_DEBUG_LEVEL:
105
+ case LiteSpeed_Cache_Config::OPID_HEARTBEAT:
106
+ case LiteSpeed_Cache_Config::OPID_DEBUG_COOKIE:
107
+ case LiteSpeed_Cache_Config::OPID_COLLAPS_QS:
108
+ case LiteSpeed_Cache_Config::OPID_LOG_FILTERS:
109
+ //checkbox
110
+ if ( $val === 'true' ) {
111
+ $options[$key] = LiteSpeed_Cache_Config::VAL_ON ;
112
+ }
113
+ elseif ( $val === 'false' ) {
114
+ unset($options[$key]) ;
115
+ }
116
+ else {
117
+ WP_CLI::error('Checkbox value must be true or false.') ;
118
+ return ;
119
+ }
120
+ break ;
121
+
122
+ case LiteSpeed_Cache_Config::ID_MOBILEVIEW_LIST:
123
+ $enable_key = LiteSpeed_Cache_Config::OPID_CACHE_MOBILE ;
124
+ if ( ! isset($options[$enable_key]) || ! $options[$enable_key] ) {
125
+ $options[$enable_key] = LiteSpeed_Cache_Config::VAL_ON ;
126
+ }
127
+ $options[$key] = $val ;
128
+ break ;
129
+
130
+ default:
131
+ if ( substr($key, 0, 6) === 'purge_' ) {
132
+ if ( $val === 'true' ) {
133
+ WP_CLI::line('key is ' . $key . ', val is ' . $val) ;
134
+ $options[$key] = LiteSpeed_Cache_Config::VAL_ON ;
135
+ }
136
+ elseif ( $val === 'false' ) {
137
+ unset($options[$key]) ;
138
+ }
139
+ else {
140
+ WP_CLI::error('Purge checkbox value must be true or false.') ;
141
+ return ;
142
+ }
143
+ }
144
+ else {
145
+ // Everything else, just set the value
146
+ $options[$key] = $val ;
147
+ }
148
+ break ;
149
+ }
150
+
151
+ $this->_update_options($options) ;
152
+ }
153
+
154
+ /**
155
+ * Get the plugin options.
156
+ *
157
+ * ## OPTIONS
158
+ *
159
+ * ## EXAMPLES
160
+ *
161
+ * # Get all options
162
+ * $ wp lscache-admin get_options
163
+ *
164
+ */
165
+ public function get_options($args, $assoc_args)
166
+ {
167
+ $options = LiteSpeed_Cache_Config::get_instance()->get_options() ;
168
+ $purge_options = LiteSpeed_Cache_Config::get_instance()->get_purge_options() ;
169
+ unset($options[LiteSpeed_Cache_Config::OPID_PURGE_BY_POST]) ;
170
+ $option_out = array() ;
171
+ $purge_diff = array_diff(self::$purges, $purge_options) ;
172
+ $purge_out = array() ;
173
+
174
+ $buf = WP_CLI::colorize("%CThe list of options:%n\n") ;
175
+ WP_CLI::line($buf) ;
176
+
177
+ foreach($options as $key => $value) {
178
+ if ( in_array($key, self::$checkboxes) ) {
179
+ if ( $value ) {
180
+ $value = 'true' ;
181
+ }
182
+ else {
183
+ $value = 'false' ;
184
+ }
185
+ }
186
+ elseif ( $value === '' ) {
187
+ $value = "''" ;
188
+ }
189
+ $option_out[] = array('key' => $key, 'value' => $value) ;
190
+ }
191
+
192
+ foreach ($purge_options as $opt_name) {
193
+ $purge_out[] = array('key' => 'purge_' . $opt_name, 'value' => 'true') ;
194
+ }
195
+
196
+ foreach ($purge_diff as $opt_name) {
197
+ $purge_out[] = array('key' => 'purge_' . $opt_name, 'value' => 'false') ;
198
+ }
199
+
200
+ WP_CLI\Utils\format_items('table', $option_out, array('key', 'value')) ;
201
+
202
+ $buf = WP_CLI::colorize("%CThe list of PURGE ON POST UPDATE options:%n\n") ;
203
+ WP_CLI::line($buf) ;
204
+ WP_CLI\Utils\format_items('table', $purge_out, array('key', 'value')) ;
205
+ }
206
+
207
+ /**
208
+ * Export plugin options to a file.
209
+ *
210
+ * ## OPTIONS
211
+ *
212
+ * [--filename=<path>]
213
+ * : The default path used is CURRENTDIR/lscache_wp_options_DATE-TIME.txt.
214
+ * To select a different file, use this option.
215
+ *
216
+ * ## EXAMPLES
217
+ *
218
+ * # Export options to a file.
219
+ * $ wp lscache-admin export_options
220
+ *
221
+ */
222
+ public function export_options($args, $assoc_args)
223
+ {
224
+ $options = LiteSpeed_Cache_Config::get_instance()->get_options() ;
225
+ $output = '' ;
226
+ if ( isset($assoc_args['filename']) ) {
227
+ $file = $assoc_args['filename'] ;
228
+ }
229
+ else {
230
+ $file = getcwd() . '/lscache_wp_options_' . date('d_m_Y-His') . '.txt' ;
231
+ }
232
+
233
+ if ( ! is_writable(dirname($file)) ) {
234
+ WP_CLI::error('Directory not writable.') ;
235
+ return ;
236
+ }
237
+
238
+ foreach ($options as $key => $val) {
239
+ $output .= sprintf("%s=%s\n", $key, $val) ;
240
+ }
241
+ $output .= "\n" ;
242
+
243
+ if ( file_put_contents($file, $output) === false ) {
244
+ WP_CLI::error('Failed to create file.') ;
245
+ }
246
+ else {
247
+ WP_CLI::success('Created file ' . $file) ;
248
+ }
249
+ }
250
+
251
+ /**
252
+ * Import plugin options from a file.
253
+ *
254
+ * The file must be formatted as such:
255
+ * option_key=option_value
256
+ * One per line.
257
+ * A Semicolon at the beginning of the line indicates a comment and will be skipped.
258
+ *
259
+ * ## OPTIONS
260
+ *
261
+ * <file>
262
+ * : The file to import options from.
263
+ *
264
+ * ## EXAMPLES
265
+ *
266
+ * # Import options from CURRENTDIR/options.txt
267
+ * $ wp lscache-admin import_options options.txt
268
+ *
269
+ */
270
+ public function import_options($args, $assoc_args)
271
+ {
272
+ $file = $args[0] ;
273
+ if ( ! file_exists($file) || ! is_readable($file) ) {
274
+ WP_CLI::error('File does not exist or is not readable.') ;
275
+ }
276
+ $content = file_get_contents($file) ;
277
+ preg_match_all("/^[^;][^=]+=[^=\n\r]*$/m", $content, $input) ;
278
+ $options = array() ;
279
+ $default = LiteSpeed_Cache_Config::get_instance()->get_options() ;
280
+
281
+ foreach ($input[0] as $opt) {
282
+ $kv = explode('=', $opt) ;
283
+ $options[$kv[0]] = $kv[1] ;
284
+ }
285
+
286
+ $options = LiteSpeed_Cache_Config::option_diff($default, $options) ;
287
+
288
+ $options = LiteSpeed_Cache_Config::convert_options_to_input($options) ;
289
+
290
+ $this->_update_options($options) ;
291
+ }
292
+
293
+ /**
294
+ * Update options
295
+ *
296
+ * @access private
297
+ * @since 1.1.0
298
+ * @param array $options The options array to store
299
+ */
300
+ private function _update_options($options)
301
+ {
302
+ $output = LiteSpeed_Cache_Admin_Settings::get_instance()->validate_plugin_settings($options) ;
303
+
304
+ global $wp_settings_errors ;
305
+
306
+ if ( ! empty($wp_settings_errors) ) {
307
+ foreach ($wp_settings_errors as $err) {
308
+ WP_CLI::error($err['message']) ;
309
+ }
310
+ return ;
311
+ }
312
+
313
+ $ret = LiteSpeed_Cache_Config::get_instance()->update_options($output) ;
314
+
315
+ if ( $ret ) {
316
+ WP_CLI::success('Options updated. Please purge the cache. New options: ' . print_r($output, true)) ;
317
+ }
318
+ else {
319
+ WP_CLI::error('No options updated.') ;
320
+ }
321
+ }
322
+ }
323
+
cli/litespeed-cache-cli-purge.class.php ADDED
@@ -0,0 +1,303 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * LiteSpeed Cache Purge Interface
5
+ */
6
+ class LiteSpeed_Cache_Cli_Purge
7
+ {
8
+ /**
9
+ * List all site domains and ids on the network.
10
+ *
11
+ * For use with the blog subcommand.
12
+ *
13
+ * ## EXAMPLES
14
+ *
15
+ * # List all the site domains and ids in a table.
16
+ * $ wp lscache-purge network_list
17
+ */
18
+ public function network_list($args, $assoc_args)
19
+ {
20
+ if ( ! is_multisite() ) {
21
+ WP_CLI::error('This is not a multisite installation!') ;
22
+
23
+ return ;
24
+ }
25
+ $buf = WP_CLI::colorize("%CThe list of installs:%n\n") ;
26
+
27
+ if ( version_compare($GLOBALS['wp_version'], '4.6', '<') ) {
28
+ $sites = wp_get_sites() ;
29
+ foreach ($sites as $site) {
30
+ $buf .= WP_CLI::colorize('%Y' . $site['domain'] . $site['path'] . ':%n ID ' . $site['blog_id']) . "\n" ;
31
+ }
32
+ }
33
+ else {
34
+ $sites = get_sites() ;
35
+ foreach ($sites as $site) {
36
+ $buf .= WP_CLI::colorize('%Y' . $site->domain . $site->path . ':%n ID ' . $site->blog_id) . "\n" ;
37
+ }
38
+ }
39
+
40
+ WP_CLI::line($buf) ;
41
+ }
42
+
43
+ /**
44
+ * Sends an ajax request to the site. Takes an action and the nonce string
45
+ * to perform.
46
+ *
47
+ * @since 1.0.14
48
+ * @param string $action The action to perform
49
+ * @param array $extra Any extra parameters needed to be sent.
50
+ * @return mixed The http request return.
51
+ */
52
+ private function _send_request($action, $extra = array())
53
+ {
54
+ $data = array(
55
+ LiteSpeed_Cache::ACTION_KEY => $action,
56
+ LiteSpeed_Cache::NONCE_NAME => wp_create_nonce($action),
57
+ ) ;
58
+ if ( ! empty($extra) ) {
59
+ $data = array_merge($data, $extra) ;
60
+ }
61
+
62
+ $url = admin_url('admin-ajax.php') ;
63
+ WP_CLI::debug('url is ' . $url) ;
64
+
65
+ $out = WP_CLI\Utils\http_request('GET', $url, $data) ;
66
+ return $out ;
67
+ }
68
+
69
+ /**
70
+ * Purges all cache entries for the blog (the entire network if multisite).
71
+ *
72
+ * ## EXAMPLES
73
+ *
74
+ * # Purge Everything associated with the WordPress install.
75
+ * $ wp lscache-purge all
76
+ *
77
+ */
78
+ public function all( $args, $assoc_args )
79
+ {
80
+ if ( is_multisite() ) {
81
+ $action = LiteSpeed_Cache::ACTION_QS_PURGE_EMPTYCACHE ;
82
+ }
83
+ else {
84
+ $action = LiteSpeed_Cache::ACTION_QS_PURGE_ALL ;
85
+ }
86
+
87
+ $purge_ret = $this->_send_request( $action ) ;
88
+
89
+ if ( $purge_ret->success ) {
90
+ WP_CLI::success(__('Purged All!', 'litespeed-cache')) ;
91
+ }
92
+ else {
93
+ WP_CLI::error('Something went wrong! Got ' . $purge_ret->status_code) ;
94
+ }
95
+ }
96
+
97
+ /**
98
+ * Purges all cache entries for the blog.
99
+ *
100
+ * ## OPTIONS
101
+ *
102
+ * <blogid>
103
+ * : The blog id to purge
104
+ *
105
+ * ## EXAMPLES
106
+ *
107
+ * # In a multisite install, purge only the shop.example.com cache (stored as blog id 2).
108
+ * $ wp lscache-purge blog 2
109
+ *
110
+ */
111
+ public function blog($args, $assoc_args)
112
+ {
113
+ if ( ! is_multisite() ) {
114
+ WP_CLI::error('Not a multisite installation.') ;
115
+ return ;
116
+ }
117
+ $blogid = $args[0] ;
118
+ if ( ! is_numeric($blogid) ) {
119
+ $error = WP_CLI::colorize('%RError: invalid blog id entered.%n') ;
120
+ WP_CLI::line($error) ;
121
+ $this->network_list($args, $assoc_args) ;
122
+ return ;
123
+ }
124
+ $site = get_blog_details($blogid) ;
125
+ if ( $site === false ) {
126
+ $error = WP_CLI::colorize('%RError: invalid blog id entered.%n') ;
127
+ WP_CLI::line($error) ;
128
+ $this->network_list($args, $assoc_args) ;
129
+ return ;
130
+ }
131
+ switch_to_blog($blogid) ;
132
+
133
+ $purge_ret = $this->_send_request(LiteSpeed_Cache::ACTION_QS_PURGE_ALL) ;
134
+ if ( $purge_ret->success ) {
135
+ WP_CLI::success(__('Purged the blog!', 'litespeed-cache')) ;
136
+ }
137
+ else {
138
+ WP_CLI::error('Something went wrong! Got ' . $purge_ret->status_code) ;
139
+ }
140
+ }
141
+
142
+ /**
143
+ * Purges all cache tags related to a url.
144
+ *
145
+ * ## OPTIONS
146
+ *
147
+ * <url>
148
+ * : The url to purge.
149
+ *
150
+ * ## EXAMPLES
151
+ *
152
+ * # Purge the front page.
153
+ * $ wp lscache-purge url https://mysite.com/
154
+ *
155
+ */
156
+ public function url($args, $assoc_args)
157
+ {
158
+ $data = array(
159
+ LiteSpeed_Cache::ACTION_KEY => LiteSpeed_Cache::ACTION_QS_PURGE,
160
+ ) ;
161
+ $url = $args[0] ;
162
+ $deconstructed = wp_parse_url($url) ;
163
+ if ( empty($deconstructed) ) {
164
+ WP_CLI::error('url passed in is invalid.') ;
165
+ return ;
166
+ }
167
+
168
+ if ( is_multisite() ) {
169
+ if ( get_blog_id_from_url($deconstructed['host'], '/') === 0 ) {
170
+ WP_CLI::error('Multisite url passed in is invalid.') ;
171
+ return ;
172
+ }
173
+ }
174
+ else {
175
+ $site_url = get_site_url() ;
176
+ $deconstructed_site = wp_parse_url($site_url) ;
177
+ if ( $deconstructed['host'] !== $deconstructed_site['host'] ) {
178
+ WP_CLI::error('Single site url passed in is invalid.') ;
179
+ return ;
180
+ }
181
+ }
182
+
183
+ WP_CLI::debug('url is ' . $url) ;
184
+
185
+ $purge_ret = WP_CLI\Utils\http_request('GET', $url, $data) ;
186
+ if ( $purge_ret->success ) {
187
+ WP_CLI::success(__('Purged the url!', 'litespeed-cache')) ;
188
+ }
189
+ else {
190
+ WP_CLI::error('Something went wrong! Got ' . $purge_ret->status_code) ;
191
+ }
192
+ }
193
+
194
+ /**
195
+ * Helper function for purging by ids.
196
+ *
197
+ * @access private
198
+ * @since 1.0.15
199
+ * @param array $args The id list to parse.
200
+ * @param string $select The purge by kind
201
+ * @param function(int $id) $callback The callback function to check the id.
202
+ */
203
+ private function _purgeby_helper($args, $select, $callback)
204
+ {
205
+ $filtered = array() ;
206
+ foreach ($args as $val) {
207
+ if ( ! ctype_digit($val) ) {
208
+ WP_CLI::debug('[LSCACHE] Skip val, not a number. ' . $val) ;
209
+ continue ;
210
+ }
211
+ $term = $callback($val) ;
212
+ if ( ! empty($term) ) {WP_CLI::line($term->name);
213
+ $filtered[] = in_array( $callback, array( 'get_tag', 'get_category' ) ) ? $term->name : $val ;
214
+ }
215
+ else {
216
+ WP_CLI::debug('[LSCACHE] Skip val, not a valid term. ' . $val) ;
217
+ }
218
+ }
219
+
220
+ if ( empty($filtered) ) {
221
+ WP_CLI::error('Arguments must be integer ids.') ;
222
+ return ;
223
+ }
224
+
225
+ $str = implode(',', $filtered) ;
226
+
227
+ WP_CLI::line('Will purge the following cache tags: ' . $str) ;
228
+
229
+ $data = array(
230
+ LiteSpeed_Cache_Admin_Display::PURGEBYOPT_SELECT => $select,
231
+ LiteSpeed_Cache_Admin_Display::PURGEBYOPT_LIST => $str,
232
+ ) ;
233
+
234
+ $purge_ret = $this->_send_request(LiteSpeed_Cache::ACTION_PURGE_BY, $data) ;
235
+ if ( $purge_ret->success ) {
236
+ WP_CLI::success(__('Purged the tags!', 'litespeed-cache')) ;
237
+ }
238
+ else {
239
+ WP_CLI::error('Something went wrong! Got ' . $purge_ret->status_code) ;
240
+ }
241
+
242
+ }
243
+
244
+ /**
245
+ * Purges cache tags for a WordPress tag
246
+ *
247
+ * ## OPTIONS
248
+ *
249
+ * <ids>...
250
+ * : the Term IDs to purge.
251
+ *
252
+ * ## EXAMPLES
253
+ *
254
+ * # Purge the tag ids 1, 3, and 5
255
+ * $ wp lscache-purge tag 1 3 5
256
+ *
257
+ */
258
+ public function tag($args, $assoc_args)
259
+ {
260
+ $this->_purgeby_helper($args, LiteSpeed_Cache_Admin_Display::PURGEBY_TAG, 'get_tag') ;
261
+ }
262
+
263
+ /**
264
+ * Purges cache tags for a WordPress category
265
+ *
266
+ * ## OPTIONS
267
+ *
268
+ * <ids>...
269
+ * : the Term IDs to purge.
270
+ *
271
+ * ## EXAMPLES
272
+ *
273
+ * # Purge the category ids 1, 3, and 5
274
+ * $ wp lscache-purge category 1 3 5
275
+ *
276
+ */
277
+ public function category($args, $assoc_args)
278
+ {
279
+ $this->_purgeby_helper($args, LiteSpeed_Cache_Admin_Display::PURGEBY_CAT, 'get_category') ;
280
+ }
281
+
282
+ /**
283
+ * Purges cache tags for a WordPress Post/Product
284
+ *
285
+ * @alias product
286
+ *
287
+ * ## OPTIONS
288
+ *
289
+ * <ids>...
290
+ * : the Post IDs to purge.
291
+ *
292
+ * ## EXAMPLES
293
+ *
294
+ * # Purge the post ids 1, 3, and 5
295
+ * $ wp lscache-purge post_id 1 3 5
296
+ *
297
+ */
298
+ public function post_id($args, $assoc_args)
299
+ {
300
+ $this->_purgeby_helper($args, LiteSpeed_Cache_Admin_Display::PURGEBY_PID, 'get_post') ;
301
+ }
302
+
303
+ }
includes/advanced-cache.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * LiteSpeed Cache Plugin
5
+ */
6
+ if (!defined('ABSPATH')) {
7
+ die();
8
+ }
9
+
10
+ define('LSCACHE_ADV_CACHE', true);
11
+
12
+ /**
13
+ * Because of the way it handles caching, the LiteSpeed Cache plugin for WordPress does not need an advanced-cache.php file.
14
+ * For this reason, there is no real logic in this file. So why include it at all?
15
+ * Setting the WP_CACHE global variable requires that an advanced-cache.php file exists.
16
+ * This variable can help to increase compatibility as other plugins can check it to determine whether or not a cache is currently being used.
17
+ * It can also help to avoid conflicts with other full page caches such as W3 Total Cache, etc.
18
+ *
19
+ */
20
+ return;
includes/deprecated-litespeed-cache-tags.class.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Deprecated Class for API backward compatibility to v1.1.2.2
5
+ */
6
+ class LiteSpeed_Cache_Tags
7
+ {
8
+ public static function add_purge_tag( $tag )
9
+ {
10
+ LiteSpeed_Cache_API::purge( $tag ) ;
11
+ }
12
+ }
includes/litespeed-cache-activation.class.php ADDED
@@ -0,0 +1,245 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The plugin activation class.
4
+ *
5
+ * @since 1.1.0
6
+ * @package LiteSpeed_Cache
7
+ * @subpackage LiteSpeed_Cache/includes
8
+ * @author LiteSpeed Technologies <info@litespeedtech.com>
9
+ */
10
+ class LiteSpeed_Cache_Activation
11
+ {
12
+ const NETWORK_TRANSIENT_COUNT = 'lscwp_network_count' ;
13
+
14
+ /**
15
+ * The activation hook callback.
16
+ *
17
+ * Attempts to set up the advanced cache file. If it fails for any reason,
18
+ * the plugin will not activate.
19
+ *
20
+ * @since 1.0.0
21
+ * @access public
22
+ */
23
+ public static function register_activation()
24
+ {
25
+ $count = 0 ;
26
+ if ( ! defined('LSCWP_LOG_TAG') ) {
27
+ define('LSCWP_LOG_TAG', 'Activate_' . get_current_blog_id()) ;
28
+ }
29
+ self::try_copy_advanced_cache() ;
30
+ LiteSpeed_Cache_Config::wp_cache_var_setter(true) ;
31
+
32
+ if ( is_multisite() ) {
33
+ $count = self::get_network_count() ;
34
+ if ( $count !== false ) {
35
+ $count = intval($count) + 1 ;
36
+ set_site_transient(self::NETWORK_TRANSIENT_COUNT, $count, DAY_IN_SECONDS) ;
37
+ }
38
+ }
39
+ do_action('litespeed_cache_api_load_thirdparty') ;
40
+ LiteSpeed_Cache_Config::get_instance()->plugin_activation($count) ;
41
+ LiteSpeed_Cache_Admin_Report::get_instance()->generate_environment_report() ;
42
+
43
+ if (defined('LSCWP_PLUGIN_NAME')) {
44
+ set_transient(LiteSpeed_Cache::WHM_TRANSIENT, LiteSpeed_Cache::WHM_TRANSIENT_VAL) ;
45
+ }
46
+
47
+ // Register crawler cron task
48
+ LiteSpeed_Cache_Task::update() ;
49
+ }
50
+
51
+ /**
52
+ * Uninstall plugin
53
+ * @since 1.1.0
54
+ */
55
+ public static function uninstall_litespeed_cache()
56
+ {
57
+ LiteSpeed_Cache_Task::clear() ;
58
+ LiteSpeed_Cache_Admin_Rules::get_instance()->clear_rules( true ) ;
59
+ delete_option( LiteSpeed_Cache_Config::OPTION_NAME ) ;
60
+ if ( is_multisite() ) {
61
+ delete_site_option( LiteSpeed_Cache_Config::OPTION_NAME ) ;
62
+ }
63
+ }
64
+
65
+ /**
66
+ * Get the blog ids for the network. Accepts function arguments.
67
+ *
68
+ * Will use wp_get_sites for WP versions less than 4.6
69
+ *
70
+ * @since 1.0.12
71
+ * @access public
72
+ * @param array $args Arguments to pass into get_sites/wp_get_sites.
73
+ * @return array The array of blog ids.
74
+ */
75
+ public static function get_network_ids($args = array())
76
+ {
77
+ global $wp_version ;
78
+ if ( version_compare($wp_version, '4.6', '<') ) {
79
+ $blogs = wp_get_sites($args) ;
80
+ if ( !empty($blogs) ) {
81
+ foreach ( $blogs as $key => $blog ) {
82
+ $blogs[$key] = $blog['blog_id'] ;
83
+ }
84
+ }
85
+ }
86
+ else {
87
+ $args['fields'] = 'ids' ;
88
+ $blogs = get_sites($args) ;
89
+ }
90
+ return $blogs ;
91
+ }
92
+
93
+ /**
94
+ * Gets the count of active litespeed cache plugins on multisite.
95
+ *
96
+ * @since 1.0.12
97
+ * @access private
98
+ * @return mixed The count on success, false on failure.
99
+ */
100
+ private static function get_network_count()
101
+ {
102
+ $count = get_site_transient(self::NETWORK_TRANSIENT_COUNT) ;
103
+ if ( $count !== false ) {
104
+ return intval($count) ;
105
+ }
106
+ // need to update
107
+ $default = array() ;
108
+ $count = 0 ;
109
+
110
+ $sites = self::get_network_ids(array('deleted' => 0)) ;
111
+ if ( empty($sites) ) {
112
+ return false ;
113
+ }
114
+
115
+ foreach ( $sites as $site ) {
116
+ $plugins = get_blog_option($site->blog_id, 'active_plugins', $default) ;
117
+ if ( in_array(LSWCP_BASENAME, $plugins, true) ) {
118
+ $count++ ;
119
+ }
120
+ }
121
+ if ( is_plugin_active_for_network(LSWCP_BASENAME) ) {
122
+ $count++ ;
123
+ }
124
+ return $count ;
125
+ }
126
+
127
+ /**
128
+ * Is this deactivate call the last active installation on the multisite
129
+ * network?
130
+ *
131
+ * @since 1.0.12
132
+ * @access private
133
+ * @return bool True if yes, false otherwise.
134
+ */
135
+ private static function is_deactivate_last()
136
+ {
137
+ $count = self::get_network_count() ;
138
+ if ( $count === false ) {
139
+ return false ;
140
+ }
141
+ if ( $count !== 1 ) {
142
+ // Not deactivating the last one.
143
+ $count-- ;
144
+ set_site_transient(self::NETWORK_TRANSIENT_COUNT, $count, DAY_IN_SECONDS) ;
145
+ return false ;
146
+ }
147
+
148
+ delete_site_transient(self::NETWORK_TRANSIENT_COUNT) ;
149
+ return true ;
150
+ }
151
+
152
+ /**
153
+ * The deactivation hook callback.
154
+ *
155
+ * Initializes all clean up functionalities.
156
+ *
157
+ * @since 1.0.0
158
+ * @access public
159
+ */
160
+ public static function register_deactivation()
161
+ {
162
+ LiteSpeed_Cache_Task::clear() ;
163
+ if (!defined('LSCWP_LOG_TAG')) {
164
+ define('LSCWP_LOG_TAG', 'Deactivate_' . get_current_blog_id()) ;
165
+ }
166
+ LiteSpeed_Cache_Purge::purge_all() ;
167
+
168
+ if ( is_multisite() ) {
169
+ if ( is_network_admin() ) {
170
+ $options = get_site_option(LiteSpeed_Cache_Config::OPTION_NAME) ;
171
+ if ( isset($options)
172
+ && is_array($options) ) {
173
+ $opt_str = serialize($options) ;
174
+ update_site_option(LiteSpeed_Cache_Config::OPTION_NAME, $opt_str) ;
175
+ }
176
+ }
177
+ if ( !self::is_deactivate_last() ) {
178
+ if ( is_network_admin()
179
+ && isset($opt_str)
180
+ && $options[LiteSpeed_Cache_Config::NETWORK_OPID_ENABLED] ) {
181
+ $reset = LiteSpeed_Cache_Config::get_rule_reset_options() ;
182
+ $errors = array() ;
183
+ LiteSpeed_Cache_Admin_Rules::get_instance()->validate_common_rewrites($reset, $errors) ;
184
+ }
185
+ return ;
186
+ }
187
+ }
188
+
189
+ $adv_cache_path = LSWCP_CONTENT_DIR . '/advanced-cache.php' ;
190
+ // this file can be generated by other cache plugin like w3tc, we only delete our own file
191
+ if ( file_exists($adv_cache_path) && is_writable($adv_cache_path) ) {
192
+ if ( strpos(file_get_contents($adv_cache_path), 'LSCACHE_ADV_CACHE') !== false ) {
193
+ unlink($adv_cache_path) ;
194
+ }
195
+ else {
196
+ error_log('Keep advanced-cache.php as it belongs to other plugins') ;
197
+ }
198
+ }
199
+ else {
200
+ error_log('Failed to remove advanced-cache.php, file does not exist or is not writable!') ;
201
+ }
202
+
203
+ if ( !LiteSpeed_Cache_Config::wp_cache_var_setter(false) ) {
204
+ error_log('In wp-config.php: WP_CACHE could not be set to false during deactivation!') ;
205
+ }
206
+ LiteSpeed_Cache_Admin_Rules::get_instance()->clear_rules( true ) ;
207
+ // delete in case it's not deleted prior to deactivation.
208
+ self::dismiss_whm() ;
209
+ }
210
+
211
+ /**
212
+ * Try to copy our advanced-cache.php file to the wordpress directory.
213
+ *
214
+ * @since 1.0.11
215
+ * @access public
216
+ * @return boolean True on success, false on failure.
217
+ */
218
+ public static function try_copy_advanced_cache()
219
+ {
220
+ $adv_cache_path = LSWCP_CONTENT_DIR . '/advanced-cache.php' ;
221
+ if (file_exists($adv_cache_path)
222
+ && (filesize($adv_cache_path) !== 0
223
+ || !is_writable($adv_cache_path)) ) {
224
+ return false ;
225
+ }
226
+
227
+ copy(LSWCP_DIR . 'includes/advanced-cache.php', $adv_cache_path) ;
228
+ include($adv_cache_path) ;
229
+ $ret = defined('LSCACHE_ADV_CACHE') ;
230
+ return $ret ;
231
+ }
232
+
233
+ /**
234
+ * Delete whm transient msg tag
235
+ *
236
+ * @since 1.1.1
237
+ * @access public
238
+ */
239
+ public static function dismiss_whm()
240
+ {
241
+ delete_transient(LiteSpeed_Cache::WHM_TRANSIENT) ;
242
+ }
243
+
244
+
245
+ }
includes/litespeed-cache-api.class.php ADDED
@@ -0,0 +1,360 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * The plugin API class.
5
+ *
6
+ * @since 1.1.3
7
+ * @package LiteSpeed_Cache
8
+ * @subpackage LiteSpeed_Cache/includes
9
+ * @author LiteSpeed Technologies <info@litespeedtech.com>
10
+ */
11
+ class LiteSpeed_Cache_API
12
+ {
13
+ const TYPE_FEED = LiteSpeed_Cache_Tag::TYPE_FEED ;
14
+ const TYPE_FRONTPAGE = LiteSpeed_Cache_Tag::TYPE_FRONTPAGE ;
15
+ const TYPE_HOME = LiteSpeed_Cache_Tag::TYPE_HOME ;
16
+ const TYPE_PAGES = LiteSpeed_Cache_Tag::TYPE_PAGES ;
17
+ const TYPE_PAGES_WITH_RECENT_POSTS = LiteSpeed_Cache_Tag::TYPE_PAGES_WITH_RECENT_POSTS ;
18
+ const TYPE_ERROR = LiteSpeed_Cache_Tag::TYPE_ERROR ;
19
+ const TYPE_POST = LiteSpeed_Cache_Tag::TYPE_POST ;
20
+ const TYPE_ARCHIVE_POSTTYPE = LiteSpeed_Cache_Tag::TYPE_ARCHIVE_POSTTYPE ;
21
+ const TYPE_ARCHIVE_TERM = LiteSpeed_Cache_Tag::TYPE_ARCHIVE_TERM ;
22
+ const TYPE_AUTHOR = LiteSpeed_Cache_Tag::TYPE_AUTHOR ;
23
+ const TYPE_ARCHIVE_DATE = LiteSpeed_Cache_Tag::TYPE_ARCHIVE_DATE ;
24
+ const TYPE_BLOG = LiteSpeed_Cache_Tag::TYPE_BLOG ;
25
+ const TYPE_LOGIN = LiteSpeed_Cache_Tag::TYPE_LOGIN ;
26
+ const TYPE_URL = LiteSpeed_Cache_Tag::TYPE_URL ;
27
+ const TYPE_WIDGET = LiteSpeed_Cache_Tag::TYPE_WIDGET ;
28
+
29
+ const PARAM_NAME = LiteSpeed_Cache_ESI::PARAM_NAME ;
30
+ const WIDGET_OPID_ESIENABLE = LiteSpeed_Cache_ESI::WIDGET_OPID_ESIENABLE ;
31
+ const WIDGET_OPID_TTL = LiteSpeed_Cache_ESI::WIDGET_OPID_TTL ;
32
+
33
+ /**
34
+ * Set mobile
35
+ *
36
+ * @since 1.1.3
37
+ * @access public
38
+ */
39
+ public static function set_mobile()
40
+ {
41
+ LiteSpeed_Cache_Control::set_mobile() ;
42
+ }
43
+
44
+ /**
45
+ * Set cache status to not cacheable
46
+ *
47
+ * @since 1.1.3
48
+ * @access public
49
+ */
50
+ public static function set_cache_private()
51
+ {
52
+ LiteSpeed_Cache_Control::set_private() ;
53
+ }
54
+
55
+ /**
56
+ * Set cache status to not cacheable
57
+ *
58
+ * @since 1.1.3
59
+ * @access public
60
+ */
61
+ public static function set_nocache( $reason = false )
62
+ {
63
+ LiteSpeed_Cache_Control::set_nocache( $reason ?: 'api' ) ;
64
+ }
65
+
66
+ /**
67
+ * Get current not cacheable status
68
+ *
69
+ * @since 1.1.3
70
+ * @access public
71
+ */
72
+ public static function not_cacheable()
73
+ {
74
+ return ! LiteSpeed_Cache_Control::is_cacheable() ;
75
+ }
76
+
77
+ /**
78
+ * Set cache control ttl to use frontpage ttl
79
+ *
80
+ * @since 1.1.3
81
+ * @access public
82
+ */
83
+ public static function set_use_frontpage_ttl()
84
+ {
85
+ LiteSpeed_Cache_Control::set_custom_ttl(self::config(LiteSpeed_Cache_Config::OPID_FRONT_PAGE_TTL)) ;
86
+ }
87
+
88
+ /**
89
+ * Set cache control ttl
90
+ *
91
+ * @since 1.1.5
92
+ * @access public
93
+ */
94
+ public static function set_ttl( $val )
95
+ {
96
+ LiteSpeed_Cache_Control::set_custom_ttl( $val ) ;
97
+ }
98
+
99
+ /**
100
+ * Get current cache control ttl
101
+ *
102
+ * @since 1.1.5
103
+ * @access public
104
+ */
105
+ public static function get_ttl()
106
+ {
107
+ return LiteSpeed_Cache_Control::get_ttl() ;
108
+ }
109
+
110
+ /**
111
+ * Add public tag to cache
112
+ *
113
+ * @since 1.1.3
114
+ * @access public
115
+ */
116
+ public static function tag_add($tags)
117
+ {
118
+ LiteSpeed_Cache_Tag::add($tags) ;
119
+ }
120
+
121
+ /**
122
+ * Add vary
123
+ *
124
+ * @since 1.1.3
125
+ * @access public
126
+ */
127
+ public static function vary_add($vary)
128
+ {
129
+ LiteSpeed_Cache_Vary::add($vary) ;
130
+ }
131
+
132
+ /**
133
+ * Purge all action
134
+ *
135
+ * @since 1.1.3
136
+ * @access public
137
+ */
138
+ public static function purge_all()
139
+ {
140
+ LiteSpeed_Cache_Purge::purge_all() ;
141
+ }
142
+
143
+ /**
144
+ * Add purge tags
145
+ *
146
+ * @since 1.1.3
147
+ * @access public
148
+ */
149
+ public static function purge($tags)
150
+ {
151
+ LiteSpeed_Cache_Purge::add($tags) ;
152
+ }
153
+
154
+ /**
155
+ * Build a switch div html snippet
156
+ *
157
+ * @since 1.1.3
158
+ * @access public
159
+ * @param string $id
160
+ * @param boolean $disabled Disable this field
161
+ * @param boolean $return Return the html or echo it
162
+ */
163
+ public static function build_switch($id, $disabled = false, $return = false)
164
+ {
165
+ return LiteSpeed_Cache_Admin_Display::get_instance()->build_switch($id, $disabled, $return) ;
166
+ }
167
+
168
+ /**
169
+ * Filter the value for checkbox via input and id (enabled/disabled)
170
+ *
171
+ * @since 1.1.6
172
+ * @access public
173
+ * @param int $input The whole input array
174
+ * @param string $id The ID of the option
175
+ * @return bool Filtered value
176
+ */
177
+ public static function parse_onoff( $input, $id )
178
+ {
179
+ return LiteSpeed_Cache_Admin_Settings::parse_onoff( $input, $id ) ;
180
+ }
181
+
182
+
183
+ /**
184
+ * Hook cacheable check to cache control
185
+ *
186
+ * @since 1.1.3
187
+ * @access public
188
+ */
189
+ public static function hook_control($hook)
190
+ {
191
+ add_action('litespeed_cache_api_control', $hook) ;
192
+ }
193
+
194
+ /**
195
+ * Hook tag appending to tag
196
+ *
197
+ * @since 1.1.3
198
+ * @access public
199
+ */
200
+ public static function hook_tag($hook)
201
+ {
202
+ add_action('litespeed_cache_api_tag', $hook) ;
203
+ }
204
+
205
+ /**
206
+ * Hook vary appending to vary
207
+ *
208
+ * @since 1.1.3
209
+ * @access public
210
+ */
211
+ public static function hook_vary($hook)
212
+ {
213
+ add_action('litespeed_cache_api_vary', $hook) ;
214
+ }
215
+
216
+ /**
217
+ * Hook purge tags appending to purge
218
+ *
219
+ * @since 1.1.3
220
+ * @access public
221
+ */
222
+ public static function hook_purge($hook)
223
+ {
224
+ add_action('litespeed_cache_api_purge', $hook) ;
225
+ }
226
+
227
+ /**
228
+ * Hook purge post action to purge
229
+ *
230
+ * @since 1.1.3
231
+ * @access public
232
+ */
233
+ public static function hook_purge_post($hook)
234
+ {
235
+ add_action('litespeed_cache_api_purge_post', $hook) ;
236
+ }
237
+
238
+ /**
239
+ * Hook not ESI template
240
+ *
241
+ * @since 1.1.3
242
+ * @access public
243
+ */
244
+ public static function hook_tpl_not_esi($hook)
245
+ {
246
+ add_action('litespeed_cache_is_not_esi_template', $hook) ;
247
+ }
248
+
249
+ /**
250
+ * Hook ESI template block
251
+ *
252
+ * @since 1.1.3
253
+ * @access public
254
+ */
255
+ public static function hook_tpl_esi($block, $hook)
256
+ {
257
+ add_action('litespeed_cache_load_esi_block-' . $block, $hook) ;
258
+ }
259
+
260
+ /**
261
+ * Hook ESI params
262
+ *
263
+ * @since 1.1.3
264
+ * @access public
265
+ */
266
+ public static function hook_esi_param($block, $hook)
267
+ {
268
+ add_filter('litespeed_cache_sub_esi_params-' . $block, $hook) ;
269
+ }
270
+
271
+ /**
272
+ * Hook setting tab
273
+ *
274
+ * @since 1.1.3
275
+ * @access public
276
+ */
277
+ public static function hook_setting_tab($hook, $priority = 10, $args = 1)
278
+ {
279
+ add_filter('litespeed_cache_add_config_tab', $hook, $priority, $args) ;
280
+ }
281
+
282
+ /**
283
+ * Hook setting saving
284
+ *
285
+ * @since 1.1.3
286
+ * @access public
287
+ */
288
+ public static function hook_setting_save($hook, $priority = 10, $args = 1)
289
+ {
290
+ add_filter('litespeed_cache_save_options', $hook, $priority, $args) ;
291
+ }
292
+
293
+ /**
294
+ * Hook widget default settings value
295
+ *
296
+ * @since 1.1.3
297
+ * @access public
298
+ */
299
+ public static function hook_widget_default_options($hook, $priority = 10, $args = 1)
300
+ {
301
+ add_filter('litespeed_cache_widget_default_options', $hook, $priority, $args) ;
302
+ }
303
+
304
+ /**
305
+ * Hook get options value
306
+ *
307
+ * @since 1.1.3
308
+ * @access public
309
+ */
310
+ public static function hook_get_options($hook)
311
+ {
312
+ add_filter('litespeed_cache_get_options', $hook) ;
313
+ }
314
+
315
+ /**
316
+ * Generate ESI block url
317
+ *
318
+ * @since 1.1.3
319
+ * @access public
320
+ * @param string $control Cache control tag
321
+ */
322
+ public static function esi_url($block_id, $wrapper, $params = array(), $control = 'private,no-vary')
323
+ {
324
+ LiteSpeed_Cache_ESI::sub_esi_block($block_id, $wrapper, $params, $control) ;
325
+ }
326
+
327
+ /**
328
+ * Log debug info
329
+ *
330
+ * @since 1.1.3
331
+ * @access public
332
+ */
333
+ public static function debug($info)
334
+ {
335
+ LiteSpeed_Cache_Log::debug($info) ;
336
+ }
337
+
338
+ /**
339
+ * Get cfg setting value
340
+ *
341
+ * @since 1.1.3
342
+ * @access public
343
+ */
344
+ public static function config($id)
345
+ {
346
+ return LiteSpeed_Cache::config($id) ;
347
+ }
348
+
349
+ /**
350
+ * register 3rd party detect hooks
351
+ *
352
+ * @since 1.1.3
353
+ * @access public
354
+ */
355
+ public static function register($cls)
356
+ {
357
+ add_action('litespeed_cache_api_load_thirdparty', $cls . '::detect') ;
358
+ }
359
+
360
+ }
includes/litespeed-cache-config.class.php ADDED
@@ -0,0 +1,727 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The core plugin config class.
4
+ *
5
+ * This maintains all the options and settings for this plugin.
6
+ *
7
+ * @since 1.0.0
8
+ * @package LiteSpeed_Cache
9
+ * @subpackage LiteSpeed_Cache/includes
10
+ * @author LiteSpeed Technologies <info@litespeedtech.com>
11
+ */
12
+ class LiteSpeed_Cache_Config
13
+ {
14
+ private static $_instance ;
15
+
16
+ const OPTION_NAME = 'litespeed-cache-conf' ;
17
+ const VAL_OFF = 0 ;
18
+ const VAL_ON = 1 ;
19
+ const VAL_NOTSET = 2 ;
20
+
21
+ const LOG_LEVEL_NONE = 0 ;
22
+ const LOG_LEVEL_ERROR = 1 ;
23
+ const LOG_LEVEL_NOTICE = 2 ;
24
+ const LOG_LEVEL_INFO = 3 ;
25
+ const LOG_LEVEL_DEBUG = 4 ;
26
+ const OPID_VERSION = 'version' ;
27
+ const OPID_ENABLED = 'enabled' ;
28
+ const OPID_ENABLED_RADIO = 'radio_select' ;
29
+
30
+ const OPID_CACHE_PRIV = 'cache_priv' ;
31
+ const OPID_CACHE_COMMENTER = 'cache_commenter' ;
32
+ const OPID_CACHE_REST = 'cache_rest' ;
33
+ const OPID_CACHE_PAGE_LOGIN = 'cache_page_login' ;
34
+ const OPID_CACHE_FAVICON = 'cache_favicon' ;
35
+ const OPID_CACHE_RES = 'cache_resources' ;
36
+ const OPID_CACHE_MOBILE = 'mobileview_enabled' ;
37
+ const ID_MOBILEVIEW_LIST = 'mobileview_rules' ;
38
+
39
+ const OPID_PURGE_ON_UPGRADE = 'purge_upgrade' ;
40
+ const OPID_TIMED_URLS = 'timed_urls' ;
41
+ const OPID_TIMED_URLS_TIME = 'timed_urls_time' ;
42
+
43
+ const OPID_LOGIN_COOKIE = 'login_cookie' ;
44
+ const OPID_CHECK_ADVANCEDCACHE = 'check_advancedcache' ;
45
+ // do NOT set default options for these three, it is used for admin.
46
+ const ID_NOCACHE_COOKIES = 'nocache_cookies' ;
47
+ const ID_NOCACHE_USERAGENTS = 'nocache_useragents' ;
48
+ const OPID_DEBUG = 'debug' ;
49
+ const OPID_ADMIN_IPS = 'admin_ips' ;
50
+ const OPID_DEBUG_LEVEL = 'debug_level' ;
51
+ const OPID_LOG_FILE_SIZE = 'log_file_size' ;
52
+ const OPID_HEARTBEAT = 'heartbeat' ;
53
+ const OPID_DEBUG_COOKIE = 'debug_cookie' ;
54
+ const OPID_COLLAPS_QS = 'collaps_qs' ;
55
+ const OPID_LOG_FILTERS = 'log_filters' ;
56
+ const OPID_LOG_IGNORE_FILTERS = 'log_ignore_filters' ;
57
+ const OPID_LOG_IGNORE_PART_FILTERS = 'log_ignore_part_filters' ;
58
+
59
+ const OPID_PUBLIC_TTL = 'public_ttl' ;
60
+ const OPID_FRONT_PAGE_TTL = 'front_page_ttl' ;
61
+ const OPID_FEED_TTL = 'feed_ttl' ;
62
+ const OPID_403_TTL = '403_ttl' ;
63
+ const OPID_404_TTL = '404_ttl' ;
64
+ const OPID_500_TTL = '500_ttl' ;
65
+ const OPID_PURGE_BY_POST = 'purge_by_post' ;
66
+ const OPID_TEST_IPS = 'test_ips' ;
67
+ const OPID_ESI_ENABLE = 'esi_enabled' ;
68
+ const OPID_ESI_CACHE = 'esi_cached' ;
69
+ const PURGE_ALL_PAGES = '-' ;
70
+ const PURGE_FRONT_PAGE = 'F' ;
71
+ const PURGE_HOME_PAGE = 'H' ;
72
+ const PURGE_PAGES = 'PGS' ;
73
+ const PURGE_PAGES_WITH_RECENT_POSTS = 'PGSRP' ;
74
+ const PURGE_AUTHOR = 'A' ;
75
+ const PURGE_YEAR = 'Y' ;
76
+ const PURGE_MONTH = 'M' ;
77
+ const PURGE_DATE = 'D' ;
78
+ const PURGE_TERM = 'T' ; // include category|tag|tax
79
+ const PURGE_POST_TYPE = 'PT' ;
80
+ const OPID_EXCLUDES_URI = 'excludes_uri' ;
81
+ const OPID_EXCLUDES_CAT = 'excludes_cat' ;
82
+ const OPID_EXCLUDES_TAG = 'excludes_tag' ;
83
+
84
+ const NETWORK_OPID_ENABLED = 'network_enabled' ;
85
+ const NETWORK_OPID_USE_PRIMARY = 'use_primary_settings' ;
86
+
87
+ const CRWL_POSTS = 'crawler_include_posts' ;
88
+ const CRWL_PAGES = 'crawler_include_pages' ;
89
+ const CRWL_CATS = 'crawler_include_cats' ;
90
+ const CRWL_TAGS = 'crawler_include_tags' ;
91
+ const CRWL_EXCLUDES_CPT = 'crawler_excludes_cpt' ;
92
+ const CRWL_ORDER_LINKS = 'crawler_order_links' ;
93
+ const CRWL_USLEEP = 'crawler_usleep' ;
94
+ const CRWL_RUN_DURATION = 'crawler_run_duration' ;
95
+ const CRWL_RUN_INTERVAL = 'crawler_run_interval' ;
96
+ const CRWL_CRAWL_INTERVAL = 'crawler_crawl_interval' ;
97
+ const CRWL_THREADS = 'crawler_threads' ;
98
+ const CRWL_LOAD_LIMIT = 'crawler_load_limit' ;
99
+ const CRWL_DOMAIN_IP = 'crawler_domain_ip' ;
100
+ const CRWL_CUSTOM_SITEMAP = 'crawler_custom_sitemap' ;
101
+
102
+ const CRWL_CRON_ACTIVE = 'crawler_cron_active' ;
103
+
104
+ const CRWL_DATE_DESC = 'date_desc' ;
105
+ const CRWL_DATE_ASC = 'date_asc' ;
106
+ const CRWL_ALPHA_DESC = 'alpha_desc' ;
107
+ const CRWL_ALPHA_ASC = 'alpha_asc' ;
108
+
109
+ protected $options ;
110
+ protected $purge_options ;
111
+ protected $debug_tag = 'LiteSpeed_Cache' ;
112
+
113
+ /**
114
+ * Initialize the class and set its properties.
115
+ *
116
+ * @since 1.0.0
117
+ * @access private
118
+ */
119
+ private function __construct()
120
+ {
121
+ if ( is_multisite() ) {
122
+ $options = $this->construct_multisite_options() ;
123
+ }
124
+ else {
125
+ $options = get_option( self::OPTION_NAME, $this->get_default_options() ) ;
126
+ }
127
+ $this->options = $options ;
128
+ $this->purge_options = explode('.', $options[ self::OPID_PURGE_BY_POST ] ) ;
129
+
130
+ if ( isset( $options[ self::OPID_CHECK_ADVANCEDCACHE ] ) && $options[self::OPID_CHECK_ADVANCEDCACHE] === false && ! defined('LSCACHE_ADV_CACHE') ) {
131
+ define('LSCACHE_ADV_CACHE', true) ;
132
+ }
133
+
134
+ if (WP_DEBUG /* && $this->options[self::OPID_DEBUG] */ ) {
135
+ $msec = microtime() ;
136
+ $msec1 = substr($msec, 2, strpos($msec, ' ') - 2) ;
137
+ if ( array_key_exists('REMOTE_ADDR', $_SERVER) && array_key_exists('REMOTE_PORT', $_SERVER) ) {
138
+ $this->debug_tag .= ' [' . $_SERVER['REMOTE_ADDR'] . ':' . $_SERVER['REMOTE_PORT'] . ':' . $msec1 . '] ' ;
139
+ }
140
+ }
141
+ }
142
+
143
+ /**
144
+ * For multisite installations, the single site options need to be updated
145
+ * with the network wide options.
146
+ *
147
+ * @since 1.0.13
148
+ * @access private
149
+ * @return array The updated options.
150
+ */
151
+ private function construct_multisite_options()
152
+ {
153
+ $site_options = get_site_option(self::OPTION_NAME) ;
154
+
155
+ if ( ! function_exists('is_plugin_active_for_network') ) {
156
+ require_once(ABSPATH . '/wp-admin/includes/plugin.php') ;
157
+ }
158
+
159
+ $options = get_option(self::OPTION_NAME, $this->get_default_options()) ;
160
+
161
+ if ( ! $site_options || ! is_array($site_options) || ! is_plugin_active_for_network('litespeed-cache/litespeed-cache.php') ) {
162
+ if ($options[self::OPID_ENABLED_RADIO] == 2) {
163
+ $options[self::OPID_ENABLED] = true ;
164
+ }
165
+ return $options ;
166
+ }
167
+
168
+ if ( isset($site_options[self::NETWORK_OPID_USE_PRIMARY]) && $site_options[self::NETWORK_OPID_USE_PRIMARY] ) {
169
+ // save temparary cron setting
170
+ $CRWL_CRON_ACTIVE = $options[self::CRWL_CRON_ACTIVE] ;
171
+
172
+ $options = get_blog_option(BLOG_ID_CURRENT_SITE, LiteSpeed_Cache_Config::OPTION_NAME, array()) ;
173
+
174
+ // crawler cron activation is separated
175
+ $options[self::CRWL_CRON_ACTIVE] = $CRWL_CRON_ACTIVE ;
176
+ }
177
+
178
+ $options[self::NETWORK_OPID_ENABLED] = $site_options[self::NETWORK_OPID_ENABLED] ;
179
+ if ($options[self::OPID_ENABLED_RADIO] == 2) {
180
+ $options[self::OPID_ENABLED] = $options[self::NETWORK_OPID_ENABLED] ;
181
+ }
182
+ unset( $site_options[ self::NETWORK_OPID_ENABLED ] ) ;
183
+ unset( $site_options[ self::NETWORK_OPID_USE_PRIMARY ] ) ;
184
+ $options = array_merge( $options, $site_options ) ;
185
+ return $options ;
186
+ }
187
+
188
+ /**
189
+ * Get the list of configured options for the blog.
190
+ *
191
+ * @since 1.0.0
192
+ * @access public
193
+ * @return array The list of configured options.
194
+ */
195
+ public function get_options()
196
+ {
197
+ return $this->options ;
198
+ }
199
+
200
+ /**
201
+ * Get the selected configuration option.
202
+ *
203
+ * @since 1.0.0
204
+ * @access public
205
+ * @param string $id Configuration ID.
206
+ * @return mixed Selected option if set, NULL if not.
207
+ */
208
+ public function get_option( $id )
209
+ {
210
+ if ( isset( $this->options[$id] ) ) {
211
+ return $this->options[$id] ;
212
+ }
213
+ if ( LiteSpeed_Cache_Log::initialized() ) {
214
+ LiteSpeed_Cache_Log::debug( 'Invalid option ID ' . $id ) ;
215
+ }
216
+ return NULL ;
217
+ }
218
+
219
+ /**
220
+ * Set the configured options.
221
+ *
222
+ * NOTE: No validation here. Do validate before use this function with LiteSpeed_Cache_Admin_Settings->validate_plugin_settings().
223
+ *
224
+ * @since 1.1.3
225
+ * @access public
226
+ * @param array $new_cfg The new settings to update, which will be update $this->options too.
227
+ * @return array The result of update.
228
+ */
229
+ public function update_options( $new_cfg = array() )
230
+ {
231
+ if ( ! empty( $new_cfg ) ) {
232
+ $this->options = array_merge( $this->options, $new_cfg ) ;
233
+ }
234
+ return update_option( self::OPTION_NAME, $this->options ) ;
235
+ }
236
+
237
+ /**
238
+ * Get the configured purge options.
239
+ *
240
+ * @since 1.0.0
241
+ * @access public
242
+ * @return array The list of purge options.
243
+ */
244
+ public function get_purge_options()
245
+ {
246
+ return $this->purge_options ;
247
+ }
248
+
249
+ /**
250
+ * Check if the flag type of posts should be purged on updates.
251
+ *
252
+ * @since 1.0.0
253
+ * @access public
254
+ * @param string $flag Post type. Refer to LiteSpeed_Cache_Config::PURGE_*
255
+ * @return boolean True if the post type should be purged, false otherwise.
256
+ */
257
+ public function purge_by_post( $flag )
258
+ {
259
+ return in_array( $flag, $this->purge_options ) ;
260
+ }
261
+
262
+ /**
263
+ * Gets the default single site options
264
+ *
265
+ * @since 1.0.0
266
+ * @access public
267
+ * @param bool $include_thirdparty Whether to include the thirdparty options.
268
+ * @return array An array of the default options.
269
+ */
270
+ public function get_default_options($include_thirdparty = true)
271
+ {
272
+ $default_purge_options = array(
273
+ self::PURGE_FRONT_PAGE,
274
+ self::PURGE_HOME_PAGE,
275
+ self::PURGE_PAGES,
276
+ self::PURGE_PAGES_WITH_RECENT_POSTS,
277
+ self::PURGE_AUTHOR,
278
+ self::PURGE_MONTH,
279
+ self::PURGE_TERM,
280
+ self::PURGE_POST_TYPE
281
+ ) ;
282
+ sort($default_purge_options) ;
283
+
284
+ //For multi site, default is 2 (Use Network Admin Settings). For single site, default is 1 (Enabled).
285
+ if ( is_multisite() ) {
286
+ $default_enabled = false ;
287
+ $default_radio = 2 ;
288
+ }
289
+ else {
290
+ $default_enabled = true ;
291
+ $default_radio = 1 ;
292
+ }
293
+
294
+ $default_options = array(
295
+ self::OPID_VERSION => LiteSpeed_Cache::PLUGIN_VERSION,
296
+ self::OPID_ENABLED => $default_enabled,
297
+ self::OPID_ENABLED_RADIO => $default_radio,
298
+ self::OPID_PURGE_ON_UPGRADE => true,
299
+ self::OPID_CACHE_PRIV => true,
300
+ self::OPID_CACHE_COMMENTER => true,
301
+ self::OPID_CACHE_REST => true,
302
+ self::OPID_CACHE_PAGE_LOGIN => true,
303
+ self::OPID_TIMED_URLS => '',
304
+ self::OPID_TIMED_URLS_TIME => '',
305
+ self::OPID_CACHE_FAVICON => true,
306
+ self::OPID_CACHE_RES => true,
307
+ self::OPID_CACHE_MOBILE => false,
308
+ self::ID_MOBILEVIEW_LIST => false,
309
+ self::OPID_LOGIN_COOKIE => '',
310
+ self::OPID_CHECK_ADVANCEDCACHE => true,
311
+ self::OPID_DEBUG => self::LOG_LEVEL_NONE,
312
+ self::OPID_ADMIN_IPS => '127.0.0.1',
313
+ self::OPID_DEBUG_LEVEL => false,
314
+ self::OPID_LOG_FILE_SIZE => 30,
315
+ self::OPID_HEARTBEAT => true,
316
+ self::OPID_DEBUG_COOKIE => false,
317
+ self::OPID_COLLAPS_QS => false,
318
+ self::OPID_LOG_FILTERS => false,
319
+ self::OPID_LOG_IGNORE_FILTERS => "gettext\ngettext_with_context\nget_the_terms\nget_term",
320
+ self::OPID_LOG_IGNORE_PART_FILTERS => "i18n\nlocale\nsettings\noption",
321
+ self::OPID_TEST_IPS => '',
322
+ self::OPID_PUBLIC_TTL => 604800,
323
+ self::OPID_FRONT_PAGE_TTL => 604800,
324
+ self::OPID_FEED_TTL => 0,
325
+ self::OPID_403_TTL => 3600,
326
+ self::OPID_404_TTL => 3600,
327
+ self::OPID_500_TTL => 3600,
328
+ self::OPID_PURGE_BY_POST => implode('.', $default_purge_options),
329
+ self::OPID_EXCLUDES_URI => '',
330
+ self::OPID_EXCLUDES_CAT => '',
331
+ self::OPID_EXCLUDES_TAG => '',
332
+ self::ID_NOCACHE_COOKIES => '',
333
+ self::ID_NOCACHE_USERAGENTS => '',
334
+ self::CRWL_POSTS => true,
335
+ self::CRWL_PAGES => true,
336
+ self::CRWL_CATS => true,
337
+ self::CRWL_TAGS => true,
338
+ self::CRWL_EXCLUDES_CPT => '',
339
+ self::CRWL_ORDER_LINKS => self::CRWL_DATE_DESC,
340
+ self::CRWL_USLEEP => 500,
341
+ self::CRWL_RUN_DURATION => 400,
342
+ self::CRWL_RUN_INTERVAL => 600,
343
+ self::CRWL_CRAWL_INTERVAL => 302400,
344
+ self::CRWL_THREADS => 3,
345
+ self::CRWL_LOAD_LIMIT => 1,
346
+ self::CRWL_DOMAIN_IP => '',
347
+ self::CRWL_CUSTOM_SITEMAP => '',
348
+ self::CRWL_CRON_ACTIVE => false,
349
+ ) ;
350
+
351
+ if ( LSWCP_ESI_SUPPORT ) {
352
+ $default_options[self::OPID_ESI_ENABLE] = false ;
353
+ $default_options[self::OPID_ESI_CACHE] = false ;
354
+ }
355
+
356
+ if ( is_multisite() ) {
357
+ $default_options[self::NETWORK_OPID_ENABLED] = false ;
358
+ }
359
+
360
+ if ( ! $include_thirdparty ) {
361
+ return $default_options ;
362
+ }
363
+
364
+ $tp_options = $this->get_thirdparty_options($default_options) ;
365
+ if ( ! isset($tp_options) || ! is_array($tp_options) ) {
366
+ return $default_options ;
367
+ }
368
+ return array_merge($default_options, $tp_options) ;
369
+ }
370
+
371
+ /**
372
+ * Gets the default network options
373
+ *
374
+ * @since 1.0.11
375
+ * @access protected
376
+ * @return array An array of the default options.
377
+ */
378
+ protected function get_default_site_options()
379
+ {
380
+ $default_site_options = array(
381
+ self::OPID_VERSION => LiteSpeed_Cache::PLUGIN_VERSION,
382
+ self::NETWORK_OPID_ENABLED => false,
383
+ self::NETWORK_OPID_USE_PRIMARY => false,
384
+ self::OPID_PURGE_ON_UPGRADE => true,
385
+ self::OPID_CACHE_FAVICON => true,
386
+ self::OPID_CACHE_RES => true,
387
+ self::OPID_CACHE_MOBILE => 0, // todo: why not false
388
+ self::ID_MOBILEVIEW_LIST => false,
389
+ self::OPID_LOGIN_COOKIE => '',
390
+ self::OPID_CHECK_ADVANCEDCACHE => true,
391
+ self::ID_NOCACHE_COOKIES => '',
392
+ self::ID_NOCACHE_USERAGENTS => '',
393
+ ) ;
394
+ return $default_site_options ;
395
+ }
396
+
397
+ /**
398
+ * When the .htaccess files need to be reset, use this array to denote
399
+ * everything off.
400
+ *
401
+ * @since 1.0.12
402
+ * @access public
403
+ * @return array The list of options to reset.
404
+ */
405
+ public static function get_rule_reset_options()
406
+ {
407
+ $reset = array(
408
+ LiteSpeed_Cache_Config::OPID_CACHE_MOBILE => false,
409
+ LiteSpeed_Cache_Config::OPID_CACHE_FAVICON => false,
410
+ LiteSpeed_Cache_Config::OPID_CACHE_RES => false,
411
+ LiteSpeed_Cache_Config::ID_MOBILEVIEW_LIST => false,
412
+ LiteSpeed_Cache_Config::ID_NOCACHE_COOKIES => '',
413
+ LiteSpeed_Cache_Config::ID_NOCACHE_USERAGENTS => '',
414
+ LiteSpeed_Cache_Config::OPID_LOGIN_COOKIE => ''
415
+ ) ;
416
+ return $reset ;
417
+ }
418
+
419
+ /**
420
+ * Get the plugin's site wide options.
421
+ *
422
+ * If the site wide options are not set yet, set it to default.
423
+ *
424
+ * @since 1.0.2
425
+ * @access public
426
+ * @return array Returns the current site options.
427
+ */
428
+ public function get_site_options()
429
+ {
430
+ if ( ! is_multisite() ) {
431
+ return null ;
432
+ }
433
+ $site_options = get_site_option(self::OPTION_NAME) ;
434
+ if ( isset($site_options) && is_array($site_options) ) {
435
+ return $site_options ;
436
+ }
437
+ elseif ( isset($site_options) && is_string($site_options) ) {
438
+ return $site_options ;
439
+ }
440
+ $default_site_options = $this->get_default_site_options() ;
441
+ add_site_option(self::OPTION_NAME, $default_site_options) ;
442
+ return $default_site_options ;
443
+ }
444
+
445
+ /**
446
+ * Gets the third party options.
447
+ * Will also strip the options that are actually normal options.
448
+ *
449
+ * @access public
450
+ * @since 1.0.9
451
+ * @param array $options Optional. The default options to compare against.
452
+ * @return mixed boolean on failure, array of keys on success.
453
+ */
454
+ public function get_thirdparty_options($options = null)
455
+ {
456
+ $tp_options = apply_filters('litespeed_cache_get_options', array()) ;
457
+ if ( empty($tp_options) ) {
458
+ return false ;
459
+ }
460
+ if ( ! isset($options) ) {
461
+ $options = $this->get_default_options(false) ;
462
+ }
463
+ return array_diff_key($tp_options, $options) ;
464
+ }
465
+
466
+ /**
467
+ * Helper function to convert the options to replicate the input format.
468
+ *
469
+ * The only difference is the checkboxes.
470
+ *
471
+ * @since 1.0.15
472
+ * @access public
473
+ * @param array $options The options array to port to input format.
474
+ * @return array $options The options array with input format.
475
+ */
476
+ public static function convert_options_to_input($options)
477
+ {
478
+ foreach ( $options as $key => $val ) {
479
+ if ( $val === true ) {
480
+ $options[$key] = self::VAL_ON ;
481
+ }
482
+ elseif ( $val === false ) {
483
+ $options[$key] = self::VAL_OFF ;
484
+ }
485
+ }
486
+ if ( isset($options[self::OPID_PURGE_BY_POST]) ) {
487
+ $purge_opts = explode('.', $options[self::OPID_PURGE_BY_POST]) ;
488
+
489
+ foreach ($purge_opts as $purge_opt) {
490
+ $options['purge_' . $purge_opt] = self::VAL_ON ;
491
+ }
492
+ }
493
+
494
+ return $options ;
495
+ }
496
+
497
+ /**
498
+ * Get the difference between the current options and the default options.
499
+ *
500
+ * @since 1.0.11
501
+ * @access public
502
+ * @param array $default_options The default options.
503
+ * @param array $options The current options.
504
+ * @return array New options.
505
+ */
506
+ public static function option_diff($default_options, $options)
507
+ {
508
+ $dkeys = array_keys($default_options) ;
509
+ $keys = array_keys($options) ;
510
+ $newkeys = array_diff($dkeys, $keys) ;
511
+ $log = '' ;//todo: useless
512
+ if ( ! empty($newkeys) ) {
513
+ foreach ( $newkeys as $newkey ) {
514
+ $options[$newkey] = $default_options[$newkey] ;
515
+ $log .= ' Added ' . $newkey . ' = ' . $default_options[$newkey] ;
516
+ }
517
+ }
518
+ $retiredkeys = array_diff($keys, $dkeys) ;
519
+ if ( ! empty($retiredkeys) ) {
520
+ foreach ( $retiredkeys as $retired ) {
521
+ unset($options[$retired]) ;
522
+ $log .= 'Removed ' . $retired ;
523
+ }
524
+ }
525
+ $options[self::OPID_VERSION] = LiteSpeed_Cache::PLUGIN_VERSION ;
526
+
527
+ if ( $options[self::OPID_CACHE_MOBILE] === false ) {
528
+ $options[self::ID_MOBILEVIEW_LIST] = false ;
529
+ }
530
+ return $options ;
531
+ }
532
+
533
+ /**
534
+ * Verify that the options are still valid.
535
+ *
536
+ * This is used only when upgrading the plugin versions.
537
+ *
538
+ * @since 1.0.0
539
+ * @access public
540
+ */
541
+ public function plugin_upgrade()
542
+ {
543
+ $default_options = $this->get_default_options() ;
544
+
545
+ if ( $this->options[self::OPID_VERSION] == $default_options[self::OPID_VERSION] && count($default_options) == count($this->options) ) {
546
+ return ;
547
+ }
548
+
549
+ $this->options = self::option_diff($default_options, $this->options) ;
550
+
551
+ $res = $this->update_options() ;
552
+ define( 'LSWCP_EMPTYCACHE', true ) ;// clear all sites caches
553
+ LiteSpeed_Cache_Purge::purge_all() ;
554
+ LiteSpeed_Cache_Log::debug("plugin_upgrade option changed = $res\n") ;
555
+ }
556
+
557
+ /**
558
+ * Upgrade network options when the plugin is upgraded.
559
+ *
560
+ * @since 1.0.11
561
+ * @access public
562
+ */
563
+ public function plugin_site_upgrade()
564
+ {
565
+ $default_options = $this->get_default_site_options() ;
566
+ $options = $this->get_site_options() ;
567
+
568
+ if ( $options[self::OPID_VERSION] == $default_options[self::OPID_VERSION] && count($default_options) == count($options) ) {
569
+ return ;
570
+ }
571
+
572
+ $options = self::option_diff($default_options, $options) ;
573
+
574
+ $res = update_site_option(self::OPTION_NAME, $options) ;
575
+
576
+ LiteSpeed_Cache_Log::debug("plugin_upgrade option changed = $res\n") ;
577
+ }
578
+
579
+ /**
580
+ * Update the WP_CACHE variable in the wp-config.php file.
581
+ *
582
+ * If enabling, check if the variable is defined, and if not, define it.
583
+ * Vice versa for disabling.
584
+ *
585
+ * @since 1.0.0
586
+ * @access public
587
+ * @param boolean $enable True if enabling, false if disabling.
588
+ * @return boolean True if the variable is the correct value, false if something went wrong.
589
+ */
590
+ public static function wp_cache_var_setter( $enable )
591
+ {
592
+ if ( $enable ) {
593
+ if ( defined('WP_CACHE') && WP_CACHE ) {
594
+ return true ;
595
+ }
596
+ }
597
+ elseif ( ! defined('WP_CACHE') || (defined('WP_CACHE') && ! WP_CACHE) ) {
598
+ return true ;
599
+ }
600
+ $file = ABSPATH . 'wp-config.php' ;
601
+ if ( ! is_writeable($file) ) {
602
+ $file = dirname(ABSPATH) . '/wp-config.php' ;
603
+ if ( ! is_writeable($file) ) {
604
+ error_log('wp-config file not writeable for \'WP_CACHE\'') ;
605
+ return LiteSpeed_Cache_Admin_Error::E_CONF_WRITE ;
606
+ }
607
+ }
608
+ $file_content = file_get_contents($file) ;
609
+
610
+ if ( $enable ) {
611
+ $count = 0 ;
612
+
613
+ $new_file_content = preg_replace('/[\/]*define\(.*\'WP_CACHE\'.+;/', "define('WP_CACHE', true);", $file_content, -1, $count) ;
614
+ if ( $count == 0 ) {
615
+ $new_file_content = preg_replace('/(\$table_prefix)/', "define('WP_CACHE', true);\n$1", $file_content) ;
616
+ if ( $count == 0 ) {
617
+ $new_file_content = preg_replace('/(\<\?php)/', "$1\ndefine('WP_CACHE', true);", $file_content, -1, $count) ;
618
+ }
619
+
620
+ if ( $count == 0 ) {
621
+ error_log('wp-config file did not find a place to insert define.') ;
622
+ return LiteSpeed_Cache_Admin_Error::E_CONF_FIND ;
623
+ }
624
+ }
625
+ }
626
+ else {
627
+ $new_file_content = preg_replace('/define\(.*\'WP_CACHE\'.+;/', "define('WP_CACHE', false);", $file_content) ;
628
+ }
629
+
630
+ file_put_contents($file, $new_file_content) ;
631
+ return true ;
632
+ }
633
+
634
+ /**
635
+ * On plugin activation, load the default options.
636
+ *
637
+ * @since 1.0.0
638
+ * @access public
639
+ * @param int $count The count of blogs active in multisite.
640
+ */
641
+ public function plugin_activation($count)
642
+ {
643
+ $errors = array() ;
644
+ $rules = LiteSpeed_Cache_Admin_Rules::get_instance() ;
645
+ $default = $this->get_default_options() ;
646
+ $res = add_option(self::OPTION_NAME, $default) ;
647
+ if ( LiteSpeed_Cache_Log::get_enabled() ) {
648
+ LiteSpeed_Cache_Log::push("plugin_activation update option = ".var_export($res, true)) ;
649
+ }
650
+ if ( is_multisite() ) {
651
+ if ( ! is_network_admin() ) {
652
+ if ( $count === 1 ) {
653
+ $rules->validate_common_rewrites(array(), $errors) ;
654
+ }
655
+ return ;
656
+ }
657
+ $options = $this->get_site_options() ;
658
+ if ( isset($options) && is_string($options) ) {
659
+ $options = unserialize($options) ;
660
+ update_site_option(self::OPTION_NAME, $options) ;
661
+ }
662
+ if ( $res == true || $options[self::NETWORK_OPID_ENABLED] == false ) {
663
+ return ;
664
+ }
665
+ }
666
+ elseif ( $res == false && $this->get_option(self::OPID_ENABLED) == false ) {
667
+ return ;
668
+ }
669
+ else {
670
+ $options = $this->get_options() ;
671
+ }
672
+
673
+ $default = self::get_rule_reset_options() ;
674
+
675
+ $diff = $rules->check_input_for_rewrite($default, $options, $errors) ;
676
+
677
+ if ( ! empty($diff) ) {
678
+ $rules->validate_common_rewrites($diff, $errors) ;
679
+ }
680
+
681
+ if ( ! empty($errors) ) {
682
+ exit(implode("\n", $errors)) ;
683
+ }
684
+
685
+ }
686
+
687
+ /**
688
+ * Checks if caching is allowed via server variable.
689
+ *
690
+ * @since 1.0.0
691
+ * @access public
692
+ * @return boolean True if allowed, false otherwise.
693
+ */
694
+ public function is_caching_allowed()
695
+ {
696
+ //lsws
697
+ if ( isset( $_SERVER['X-LSCACHE'] ) && $_SERVER['X-LSCACHE'] ) {
698
+ return true ;
699
+ }
700
+ // web adc
701
+ if ( LITESPEED_SERVER_TYPE === 'LITESPEED_SERVER_ADC' ) {
702
+ return true ;
703
+ }
704
+ // cli call
705
+ if ( PHP_SAPI == 'cli' ) {
706
+ return true ;
707
+ }
708
+ return false ;
709
+ }
710
+
711
+ /**
712
+ * Get the current instance object.
713
+ *
714
+ * @since 1.1.0
715
+ * @access public
716
+ * @return Current class instance.
717
+ */
718
+ public static function get_instance()
719
+ {
720
+ $cls = get_called_class() ;
721
+ if ( ! isset(self::$_instance) ) {
722
+ self::$_instance = new $cls() ;
723
+ }
724
+
725
+ return self::$_instance ;
726
+ }
727
+ }
includes/litespeed-cache-control.class.php ADDED
@@ -0,0 +1,602 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The plugin cache-control class for X-Litespeed-Cache-Control
4
+ *
5
+ * @since 1.1.3
6
+ * @package LiteSpeed_Cache
7
+ * @subpackage LiteSpeed_Cache/includes
8
+ * @author LiteSpeed Technologies <info@litespeedtech.com>
9
+ */
10
+ class LiteSpeed_Cache_Control
11
+ {
12
+ // private static $_instance ;
13
+
14
+ const BM_CACHEABLE = 1 ;
15
+ const BM_PRIVATE = 2 ;
16
+ const BM_SHARED = 4 ;
17
+ const BM_NO_VARY = 8 ;
18
+ const BM_STALE = 128 ;
19
+ const BM_NOTCACHEABLE = 256 ;
20
+
21
+ const X_HEADER = 'X-LiteSpeed-Cache-Control' ;
22
+
23
+ protected static $_control = 0 ;
24
+ protected static $_custom_ttl = 0 ;
25
+ private static $_mobile = false ;
26
+
27
+ /**
28
+ * 1. Initialize cacheable status for `wp` hook
29
+ * 2. Hook error page tags for cacheable pages
30
+ *
31
+ * @since 1.1.3
32
+ * @access public
33
+ */
34
+ public static function init_cacheable()
35
+ {
36
+ // Hook `wp` to mark default cacheable status
37
+ // NOTE: Any process that does NOT run into `wp` hook will not get cacheable by default
38
+ add_action( 'wp', 'LiteSpeed_Cache_Control::set_cacheable', 5 ) ;
39
+
40
+ // Hook WP REST to be cacheable
41
+ if ( LiteSpeed_Cache::config( LiteSpeed_Cache_Config::OPID_CACHE_REST ) ) {
42
+ add_action( 'rest_api_init', 'LiteSpeed_Cache_Control::set_cacheable', 5 ) ;
43
+ }
44
+
45
+ // Cache resources
46
+ // NOTE: If any strange resource doesn't use normal WP logic `wp_loaded` hook, rewrite rule can handle it
47
+ $cache_res = LiteSpeed_Cache::config( LiteSpeed_Cache_Config::OPID_CACHE_RES ) ;
48
+ if ( $cache_res ) {
49
+ $uri = esc_url( $_SERVER["REQUEST_URI"] ) ;
50
+ $pattern = '!' . LiteSpeed_Cache_Admin_Rules::RW_PATTERN_RES . '!' ;
51
+ if ( preg_match( $pattern, $uri ) ) {
52
+ add_action( 'wp_loaded', 'LiteSpeed_Cache_Control::set_cacheable', 5 ) ;
53
+ }
54
+ }
55
+
56
+ // Check error page
57
+ add_filter( 'status_header', 'LiteSpeed_Cache_Tag::check_error_codes', 10, 2 ) ;
58
+ }
59
+
60
+ /**
61
+ * Set no vary setting
62
+ *
63
+ * @access public
64
+ * @since 1.1.3
65
+ */
66
+ public static function set_no_vary()
67
+ {
68
+ if ( self::is_no_vary() ) {
69
+ return ;
70
+ }
71
+ self::$_control |= self::BM_NO_VARY ;
72
+ LiteSpeed_Cache_Log::debug('X Cache_control -> no_vary') ;
73
+ }
74
+
75
+ /**
76
+ * Get no vary setting
77
+ *
78
+ * @access public
79
+ * @since 1.1.3
80
+ */
81
+ public static function is_no_vary()
82
+ {
83
+ return self::$_control & self::BM_NO_VARY ;
84
+ }
85
+
86
+ /**
87
+ * Set stale
88
+ *
89
+ * @access public
90
+ * @since 1.1.3
91
+ */
92
+ public static function set_stale()
93
+ {
94
+ if ( self::is_stale() ) {
95
+ return ;
96
+ }
97
+ self::$_control |= self::BM_STALE ;
98
+ LiteSpeed_Cache_Log::debug('X Cache_control -> stale') ;
99
+ }
100
+
101
+ /**
102
+ * Get stale
103
+ *
104
+ * @access public
105
+ * @since 1.1.3
106
+ */
107
+ public static function is_stale()
108
+ {
109
+ return self::$_control & self::BM_STALE ;
110
+ }
111
+
112
+ /**
113
+ * Set cache control to shared private
114
+ *
115
+ * @access public
116
+ * @since 1.1.3
117
+ * @param string $reason The reason to no cache
118
+ */
119
+ public static function set_shared( $reason = false )
120
+ {
121
+ if ( self::is_shared() ) {
122
+ return ;
123
+ }
124
+ self::$_control |= self::BM_SHARED ;
125
+ self::set_private() ;
126
+ if ( $reason ) {
127
+ $reason = "( $reason )" ;
128
+ }
129
+ LiteSpeed_Cache_Log::debug( 'X Cache_control -> shared ' . $reason ) ;
130
+ }
131
+
132
+ /**
133
+ * Check if is shared private
134
+ *
135
+ * @access public
136
+ * @since 1.1.3
137
+ */
138
+ public static function is_shared()
139
+ {
140
+ return (self::$_control & self::BM_SHARED) && self::is_private() ;
141
+ }
142
+
143
+ /**
144
+ * Set cache control to private
145
+ *
146
+ * @access public
147
+ * @since 1.1.3
148
+ * @param string $reason The reason to no cache
149
+ */
150
+ public static function set_private( $reason = false )
151
+ {
152
+ if ( self::is_private() ) {
153
+ return ;
154
+ }
155
+ self::$_control |= self::BM_PRIVATE ;
156
+ if ( $reason ) {
157
+ $reason = "( $reason )" ;
158
+ }
159
+ LiteSpeed_Cache_Log::debug( 'X Cache_control -> private ' . $reason) ;
160
+ }
161
+
162
+ /**
163
+ * Check if is private
164
+ *
165
+ * @access public
166
+ * @since 1.1.3
167
+ */
168
+ public static function is_private()
169
+ {
170
+ return self::$_control & self::BM_PRIVATE ;
171
+ }
172
+
173
+ /**
174
+ * Initialize cacheable status in `wp` hook, if not call this, by default it will be non-cacheable
175
+ *
176
+ * @access public
177
+ * @since 1.1.3
178
+ */
179
+ public static function set_cacheable()
180
+ {
181
+ self::$_control |= self::BM_CACHEABLE ;
182
+ LiteSpeed_Cache_Log::debug( 'X Cache_control init on' ) ;
183
+ }
184
+
185
+ /**
186
+ * Switch to nocacheable status
187
+ *
188
+ * @access public
189
+ * @since 1.1.3
190
+ * @param string $reason The reason to no cache
191
+ */
192
+ public static function set_nocache( $reason = false )
193
+ {
194
+ self::$_control |= self::BM_NOTCACHEABLE ;
195
+ if ( $reason ) {
196
+ $reason = "( $reason )" ;
197
+ }
198
+ LiteSpeed_Cache_Log::debug( 'X Cache_control -> no Cache ' . $reason, 2 ) ;
199
+ }
200
+
201
+ /**
202
+ * Check current notcacheable bit set
203
+ *
204
+ * @access public
205
+ * @since 1.1.3
206
+ * @return bool True if notcacheable bit is set, otherwise false.
207
+ */
208
+ public static function isset_notcacheable()
209
+ {
210
+ return self::$_control & self::BM_NOTCACHEABLE ;
211
+ }
212
+
213
+ /**
214
+ * Check current cacheable status
215
+ *
216
+ * @access public
217
+ * @since 1.1.3
218
+ * @return bool True if is still cacheable, otherwise false.
219
+ */
220
+ public static function is_cacheable()
221
+ {
222
+ return ! self::isset_notcacheable() && self::$_control & self::BM_CACHEABLE ;
223
+ }
224
+
225
+
226
+
227
+
228
+ /**
229
+ * Set a custom TTL to use with the request if needed.
230
+ *
231
+ * @access public
232
+ * @since 1.1.3
233
+ * @param mixed $ttl An integer or string to use as the TTL. Must be numeric.
234
+ */
235
+ public static function set_custom_ttl($ttl)
236
+ {
237
+ if ( is_numeric($ttl) ) {
238
+ self::$_custom_ttl = $ttl ;
239
+ LiteSpeed_Cache_Log::debug('X Cache_control TTL -> ' . $ttl) ;
240
+ }
241
+ }
242
+
243
+ /**
244
+ * Generate final TTL.
245
+ *
246
+ * @access public
247
+ * @since 1.1.3
248
+ * @return int $ttl An integer to use as the TTL.
249
+ */
250
+ public static function get_ttl()
251
+ {
252
+ if ( self::$_custom_ttl != 0 ) {
253
+ return self::$_custom_ttl ;
254
+ }
255
+
256
+ // Check if is in timed url list or not
257
+ $timed_urls = LiteSpeed_Cache::config( LiteSpeed_Cache_Config::OPID_TIMED_URLS ) ;
258
+ $timed_urls_time = LiteSpeed_Cache::config( LiteSpeed_Cache_Config::OPID_TIMED_URLS_TIME ) ;
259
+ if ( $timed_urls && $timed_urls_time ) {
260
+ $timed_urls = explode( "\n", $timed_urls ) ;
261
+ $current_url = LiteSpeed_Cache_Tag::build_uri_tag( true ) ;
262
+ if ( in_array( $current_url, $timed_urls ) ) {
263
+ // Use time limit ttl
264
+ $scheduled_time = strtotime( $timed_urls_time ) ;
265
+ $ttl = $scheduled_time - time() ;
266
+ if ( $ttl < 0 ) {
267
+ $ttl += 86400 ;// add one day
268
+ }
269
+ LiteSpeed_Cache_Log::debug( 'X Cache_control TTL is limited to ' . $ttl ) ;
270
+ return $ttl ;
271
+ }
272
+ }
273
+
274
+ if ( is_front_page() ){
275
+ return LiteSpeed_Cache::config( LiteSpeed_Cache_Config::OPID_FRONT_PAGE_TTL ) ;
276
+ }
277
+
278
+ $feed_ttl = LiteSpeed_Cache::config( LiteSpeed_Cache_Config::OPID_FEED_TTL ) ;
279
+ if ( is_feed() && $feed_ttl > 0 ) {
280
+ return $feed_ttl ;
281
+ }
282
+
283
+ $ttl_404 = LiteSpeed_Cache::config( LiteSpeed_Cache_Config::OPID_404_TTL ) ;
284
+ if ( is_404() && $ttl_404 > 0 ) {
285
+ return $ttl_404 ;
286
+ }
287
+
288
+ if ( LiteSpeed_Cache_Tag::get_error_code() === 403 ) {
289
+ $ttl_403 = LiteSpeed_Cache::config( LiteSpeed_Cache_Config::OPID_403_TTL ) ;
290
+ return $ttl_403 ;
291
+ }
292
+
293
+ $ttl_500 = LiteSpeed_Cache::config( LiteSpeed_Cache_Config::OPID_500_TTL ) ;
294
+ if ( LiteSpeed_Cache_Tag::get_error_code() >= 500 ) {
295
+ return $ttl_500 ;
296
+ }
297
+
298
+ return LiteSpeed_Cache::config( LiteSpeed_Cache_Config::OPID_PUBLIC_TTL ) ;
299
+ }
300
+
301
+ /**
302
+ * Check if need to set no cache status for redirection or not
303
+ *
304
+ * @access public
305
+ * @since 1.1.3
306
+ */
307
+ public static function check_redirect( $location, $status )
308
+ {
309
+ if ( $status == '301' && ! empty( $_SERVER[ 'SCRIPT_URI' ] ) ) {
310
+ LiteSpeed_Cache_Log::debug( "301 from " . $_SERVER['SCRIPT_URI'] ) ;
311
+ LiteSpeed_Cache_Log::debug( "301 to $location" ) ;
312
+ if ( $_SERVER['SCRIPT_URI'] == $location ) {
313
+ self::set_nocache( '301 to same url' ) ;
314
+ }
315
+ }
316
+ return $location ;
317
+ }
318
+
319
+ /**
320
+ * Sets up the Cache Control header.
321
+ *
322
+ * @since 1.1.3
323
+ * @access public
324
+ * @return string empty string if empty, otherwise the cache control header.
325
+ */
326
+ public static function output()
327
+ {
328
+ $esi_hdr = '' ;
329
+ if ( LSWCP_ESI_SUPPORT && LiteSpeed_Cache_ESI::has_esi() ) {
330
+ $esi_hdr = ',esi=on' ;
331
+ }
332
+
333
+ $hdr = self::X_HEADER . ': ' ;
334
+
335
+ if ( ! self::is_cacheable() ) {
336
+ $hdr .= 'no-cache' . $esi_hdr ;
337
+ return $hdr ;
338
+ }
339
+
340
+ if ( self::is_shared() ) {
341
+ $hdr .= 'shared,private' ;
342
+ }
343
+ elseif ( self::is_private() ) {
344
+ $hdr .= 'private' ;
345
+ }
346
+ else {
347
+ $hdr .= 'public' ;
348
+ }
349
+
350
+ if ( self::is_no_vary() ) {
351
+ $hdr .= ',no-vary' ;
352
+ }
353
+
354
+ $hdr .= ',max-age=' . self::get_ttl() . $esi_hdr ;
355
+ return $hdr ;
356
+ }
357
+
358
+ /**
359
+ * Generate all `control` tags before output
360
+ *
361
+ * @access public
362
+ * @since 1.1.3
363
+ */
364
+ public static function finalize()
365
+ {
366
+ // if is not cacheable, terminate check
367
+ // Even no need to run 3rd party hook
368
+ if ( ! self::is_cacheable() ) {
369
+ LiteSpeed_Cache_Log::debug( 'not cacheable before ctrl finalize' ) ;
370
+ return ;
371
+ }
372
+
373
+ if ( defined('LSCACHE_NO_CACHE') && LSCACHE_NO_CACHE ) {
374
+ self::set_nocache('LSCACHE_NO_CACHE constant defined') ;
375
+ return ;
376
+ }
377
+
378
+ // Apply 3rd party filter
379
+ // Parse ESI block id
380
+ $esi_id = false ;
381
+ if ( defined( 'LSCACHE_IS_ESI' ) ) {
382
+ $params = LiteSpeed_Cache_ESI::parse_esi_param() ;
383
+ if ( $params !== false ) {
384
+ $esi_id = $params[LiteSpeed_Cache_ESI::PARAM_BLOCK_ID] ;
385
+ }
386
+ }
387
+ // NOTE: Hook always needs to run asap because some 3rd party set is_mobile in this hook
388
+ do_action('litespeed_cache_api_control', $esi_id) ;
389
+
390
+ // if is not cacheable, terminate check
391
+ if ( ! self::is_cacheable() ) {
392
+ LiteSpeed_Cache_Log::debug( 'not cacheable after api_control' ) ;
393
+ return ;
394
+ }
395
+
396
+ // Check litespeed setting to set cacheable status
397
+ if ( ! self::_setting_cacheable() ) {
398
+ self::set_nocache() ;
399
+ return ;
400
+ }
401
+
402
+ // If user has password cookie, do not cache (moved from vary)
403
+ global $post ;
404
+ if ( ! empty($post->post_password) && isset($_COOKIE['wp-postpass_' . COOKIEHASH]) ) {
405
+ // If user has password cookie, do not cache
406
+ self::set_nocache('pswd cookie') ;
407
+ return ;
408
+ }
409
+
410
+ // The following check to the end is ONLY for mobile
411
+ if ( ! LiteSpeed_Cache::config(LiteSpeed_Cache_Config::OPID_CACHE_MOBILE) ) {
412
+ if ( self::is_mobile() ) {
413
+ self::set_nocache('mobile') ;
414
+ }
415
+ return ;
416
+ }
417
+
418
+ if ( isset($_SERVER['LSCACHE_VARY_VALUE']) && $_SERVER['LSCACHE_VARY_VALUE'] === 'ismobile' ) {
419
+ if ( ! wp_is_mobile() && ! self::is_mobile() ) {
420
+ self::set_nocache( 'is not mobile' ) ;
421
+ return ;
422
+ }
423
+ }
424
+ elseif ( wp_is_mobile() || self::is_mobile() ) {
425
+ self::set_nocache( 'is mobile' ) ;
426
+ return ;
427
+ }
428
+
429
+ }
430
+
431
+ /**
432
+ * Check if a page is cacheable based on litespeed setting.
433
+ *
434
+ * @since 1.0.0
435
+ * @access private
436
+ * @return boolean True if cacheable, false otherwise.
437
+ */
438
+ private static function _setting_cacheable()
439
+ {
440
+ // logged_in users already excluded, no hook added
441
+
442
+ if( ! empty($_REQUEST[LiteSpeed_Cache::ACTION_KEY]) ) {
443
+ return self::_no_cache_for('Query String Action') ;
444
+ }
445
+
446
+ if ( $_SERVER["REQUEST_METHOD"] !== 'GET' ) {
447
+ return self::_no_cache_for('not GET method:' . $_SERVER["REQUEST_METHOD"]) ;
448
+ }
449
+
450
+ if ( is_feed() && LiteSpeed_Cache::config(LiteSpeed_Cache_Config::OPID_FEED_TTL) == 0 ) {
451
+ return self::_no_cache_for('feed') ;
452
+ }
453
+
454
+ if ( is_trackback() ) {
455
+ return self::_no_cache_for('trackback') ;
456
+ }
457
+
458
+ if ( is_404() && LiteSpeed_Cache::config(LiteSpeed_Cache_Config::OPID_404_TTL) == 0 ) {
459
+ return self::_no_cache_for('404 pages') ;
460
+ }
461
+
462
+ if ( is_search() ) {
463
+ return self::_no_cache_for('search') ;
464
+ }
465
+
466
+ // if ( !defined('WP_USE_THEMES') || !WP_USE_THEMES ) {
467
+ // return self::_no_cache_for('no theme used') ;
468
+ // }
469
+
470
+ $excludes = LiteSpeed_Cache::config(LiteSpeed_Cache_Config::OPID_EXCLUDES_URI) ;
471
+ if ( ! empty($excludes) && self::_is_uri_excluded(explode("\n", $excludes)) ) {
472
+ return self::_no_cache_for('Admin configured URI Do not cache: ' . $_SERVER['REQUEST_URI']) ;
473
+ }
474
+
475
+ $excludes = LiteSpeed_Cache::config(LiteSpeed_Cache_Config::OPID_EXCLUDES_CAT) ;
476
+ if ( ! empty($excludes) && has_category(explode(',', $excludes)) ) {
477
+ return self::_no_cache_for('Admin configured Category Do not cache.') ;
478
+ }
479
+
480
+ $excludes = LiteSpeed_Cache::config(LiteSpeed_Cache_Config::OPID_EXCLUDES_TAG) ;
481
+ if ( ! empty($excludes) && has_tag(explode(',', $excludes)) ) {
482
+ return self::_no_cache_for('Admin configured Tag Do not cache.') ;
483
+ }
484
+
485
+ $excludes = LiteSpeed_Cache::config(LiteSpeed_Cache_Config::ID_NOCACHE_COOKIES) ;
486
+ if ( ! empty($excludes) && ! empty($_COOKIE) ) {
487
+ $exclude_list = explode('|', $excludes) ;
488
+
489
+ foreach( $_COOKIE as $key=>$val) {
490
+ if ( in_array($key, $exclude_list) ) {
491
+ return self::_no_cache_for('Admin configured Cookie Do not cache.') ;
492
+ }
493
+ }
494
+ }
495
+
496
+ $excludes = LiteSpeed_Cache::config(LiteSpeed_Cache_Config::ID_NOCACHE_USERAGENTS) ;
497
+ if ( ! empty($excludes) && isset($_SERVER['HTTP_USER_AGENT']) ) {
498
+ $pattern = '/' . $excludes . '/' ;
499
+ $nummatches = preg_match($pattern, $_SERVER['HTTP_USER_AGENT']) ;
500
+ if ( $nummatches ) {
501
+ return self::_no_cache_for('Admin configured User Agent Do not cache.') ;
502
+ }
503
+ }
504
+
505
+ return true ;
506
+ }
507
+
508
+ /**
509
+ * Write a debug message for if a page is not cacheable.
510
+ *
511
+ * @since 1.0.0
512
+ * @access private
513
+ * @param string $reason An explanation for why the page is not cacheable.
514
+ * @return boolean Return false.
515
+ */
516
+ private static function _no_cache_for( $reason )
517
+ {
518
+ LiteSpeed_Cache_Log::debug('X Cache_control off - ' . $reason) ;
519
+ return false ;
520
+ }
521
+
522
+ /**
523
+ * Check admin configuration to see if the uri accessed is excluded from cache.
524
+ *
525
+ * @since 1.0.1
526
+ * @access private
527
+ * @param array $excludes_list List of excluded URIs
528
+ * @return boolean True if excluded, false otherwise.
529
+ */
530
+ private static function _is_uri_excluded($excludes_list)
531
+ {
532
+ $uri = esc_url($_SERVER["REQUEST_URI"]);
533
+ $uri_len = strlen( $uri ) ;
534
+ if (is_multisite()) {
535
+ $blog_details = get_blog_details(get_current_blog_id());
536
+ $blog_path = $blog_details->path;
537
+ $blog_path_len = strlen($blog_path);
538
+ if (($uri_len >= $blog_path_len)
539
+ && (strncmp($uri, $blog_path, $blog_path_len) == 0)) {
540
+ $uri = substr($uri, $blog_path_len - 1);
541
+ $uri_len = strlen( $uri ) ;
542
+ }
543
+ }
544
+ foreach( $excludes_list as $excludes_rule ){
545
+ $rule_len = strlen( $excludes_rule );
546
+ if (($excludes_rule[$rule_len - 1] == '$')) {
547
+ if ($uri_len != (--$rule_len)) {
548
+ continue;
549
+ }
550
+ }
551
+ elseif ( $uri_len < $rule_len ) {
552
+ continue;
553
+ }
554
+
555
+ if ( strncmp( $uri, $excludes_rule, $rule_len ) == 0 ){
556
+ return true ;
557
+ }
558
+ }
559
+ return false;
560
+ }
561
+
562
+ /**
563
+ * Gets whether any plugins determined that the current page is mobile.
564
+ *
565
+ * @access public
566
+ * @return boolean True if the current page was deemed mobile, false otherwise.
567
+ */
568
+ public static function is_mobile()
569
+ {
570
+ return self::$_mobile ;
571
+ }
572
+
573
+ /**
574
+ * Mark the current page as mobile. This may be useful for if the plugin does not override wp_is_mobile.
575
+ *
576
+ * Must be called before the shutdown hook point.
577
+ *
578
+ * @since 1.0.7
579
+ * @access public
580
+ */
581
+ public static function set_mobile()
582
+ {
583
+ self::$_mobile = true ;
584
+ }
585
+
586
+ /**
587
+ * Get the current instance object.
588
+ *
589
+ * @since 1.1.3
590
+ * @access public
591
+ * @return Current class instance.
592
+ */
593
+ // public static function get_instance()
594
+ // {
595
+ // $cls = get_called_class() ;
596
+ // if ( ! isset(self::$_instance) ) {
597
+ // self::$_instance = new $cls() ;
598
+ // }
599
+
600
+ // return self::$_instance ;
601
+ // }
602
+ }
includes/litespeed-cache-crawler-sitemap.class.php ADDED
@@ -0,0 +1,157 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The Crawler Sitemap Class
4
+ *
5
+ *
6
+ * @since 1.1.0
7
+ * @package LiteSpeed_Cache_Crawler_Sitemap
8
+ * @subpackage LiteSpeed_Cache/includes
9
+ * @author LiteSpeed Technologies <info@litespeedtech.com>
10
+ */
11
+
12
+ class LiteSpeed_Cache_Crawler_Sitemap
13
+ {
14
+ private static $_instance ;
15
+ private $site_url ;// Used to simplify urls
16
+
17
+ protected $_urls = array() ;
18
+
19
+ /**
20
+ * Instantiate the class
21
+ *
22
+ * @since 1.1.0
23
+ * @access private
24
+ */
25
+ private function __construct()
26
+ {
27
+ if ( is_multisite() ) {
28
+ $blog_id = get_current_blog_id() ;
29
+ $this->site_url = get_site_url($blog_id) ;
30
+ }
31
+ else{
32
+ $this->site_url = get_option('siteurl') ;
33
+ }
34
+ }
35
+
36
+ /**
37
+ * Generate all urls
38
+ *
39
+ * @since 1.1.0
40
+ * @access public
41
+ */
42
+ public function generate_data($blacklist = array())
43
+ {
44
+ global $wpdb ;
45
+
46
+ $options = LiteSpeed_Cache_Config::get_instance()->get_options() ;
47
+
48
+ $optionOrderBy = $options[LiteSpeed_Cache_Config::CRWL_ORDER_LINKS] ;
49
+
50
+ $show_pages = $options[LiteSpeed_Cache_Config::CRWL_PAGES] ;
51
+
52
+ $show_posts = $options[LiteSpeed_Cache_Config::CRWL_POSTS] ;
53
+
54
+ $show_cats = $options[LiteSpeed_Cache_Config::CRWL_CATS] ;
55
+
56
+ $show_tags = $options[LiteSpeed_Cache_Config::CRWL_TAGS] ;
57
+
58
+ switch ( $optionOrderBy ) {
59
+ case 'date_asc':
60
+ $orderBy = " ORDER BY post_date ASC" ;
61
+ break ;
62
+
63
+ case 'alpha_desc':
64
+ $orderBy = " ORDER BY post_title DESC" ;
65
+ break ;
66
+
67
+ case 'alpha_asc':
68
+ $orderBy = " ORDER BY post_title ASC" ;
69
+ break ;
70
+
71
+ case 'date_desc':
72
+ default:
73
+ $orderBy = " ORDER BY post_date DESC" ;
74
+ break ;
75
+ }
76
+
77
+ $post_type_array = array() ;
78
+ if ( isset($show_pages) && $show_pages == 1 ) {
79
+ $post_type_array[] = 'page' ;
80
+ }
81
+
82
+ if ( isset($show_posts) && $show_posts == 1 ) {
83
+ $post_type_array[] = 'post' ;
84
+ }
85
+
86
+ $id = LiteSpeed_Cache_Config::CRWL_EXCLUDES_CPT ;
87
+ if ( isset($options[$id]) ) {
88
+ $excludeCptArr = explode(',', $options[$id]) ;
89
+ $excludeCptArr = array_map('trim', $excludeCptArr) ;
90
+ $cptArr = get_post_types() ;
91
+ $cptArr = array_diff($cptArr, array('post', 'page')) ;
92
+ $cptArr = array_diff($cptArr, $excludeCptArr) ;
93
+ $post_type_array = array_merge($post_type_array, $cptArr) ;
94
+ }
95
+
96
+ if ( ! empty($post_type_array) ) {
97
+ $post_type = implode("','", $post_type_array) ;
98
+
99
+ LiteSpeed_Cache_Log::debug("Crawler sitemap log: post_type is '$post_type'") ;
100
+
101
+ $query = "SELECT ID, post_date FROM ".$wpdb->prefix."posts where post_type IN ('".$post_type."') AND post_status='publish' ".$orderBy ;
102
+ $results = $wpdb->get_results($query) ;
103
+
104
+ foreach ( $results as $result ){
105
+ $slug = str_replace($this->site_url, '', get_permalink($result->ID)) ;
106
+ if ( ! in_array($slug, $blacklist) ) {
107
+ $this->_urls[] = $slug ;
108
+ }
109
+ }
110
+ }
111
+
112
+ //Generate Categories Link if option checked
113
+ if ( isset($show_cats) && $show_cats == 1 ) {
114
+ $cats = get_terms("category", array("hide_empty"=>true, "hierarchical"=>false)) ;
115
+ if ( $cats && is_array($cats) && count($cats) > 0 ) {
116
+ foreach ( $cats as $cat ) {
117
+ $slug = str_replace($this->site_url, '', get_category_link($cat->term_id)) ;
118
+ if ( ! in_array($slug, $blacklist) ){
119
+ $this->_urls[] = $slug ;//var_dump($slug);exit;//todo: check permalink
120
+ }
121
+ }
122
+ }
123
+ }
124
+
125
+ //Generate tags Link if option checked
126
+ if ( isset($show_tags) && $show_tags == 1 ) {
127
+ $tags = get_terms("post_tag", array("hide_empty"=>true, "hierarchical"=>false)) ;
128
+ if ( $tags && is_array($tags) && count($tags) > 0 ) {
129
+ foreach ( $tags as $tag ) {
130
+ $slug = str_replace($this->site_url, '', get_tag_link($tag->term_id)) ;
131
+ if ( ! in_array($slug, $blacklist) ) {
132
+ $this->_urls[] = $slug ;
133
+ }
134
+ }
135
+ }
136
+ }
137
+
138
+ return apply_filters('litespeed_crawler_sitemap', $this->_urls) ;
139
+ }
140
+
141
+ /**
142
+ * Get the current instance object.
143
+ *
144
+ * @since 1.1.0
145
+ * @access public
146
+ * @return Current class instance.
147
+ */
148
+ public static function get_instance()
149
+ {
150
+ $cls = get_called_class() ;
151
+ if ( ! isset(self::$_instance) ) {
152
+ self::$_instance = new $cls() ;
153
+ }
154
+
155
+ return self::$_instance ;
156
+ }
157
+ }
includes/litespeed-cache-crawler.class.php ADDED
@@ -0,0 +1,451 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * The crawler class
5
+ *
6
+ *
7
+ * @since 1.1.0
8
+ * @package LiteSpeed_Cache
9
+ * @subpackage LiteSpeed_Cache/includes
10
+ * @author LiteSpeed Technologies <info@litespeedtech.com>
11
+ */
12
+ class LiteSpeed_Cache_Crawler
13
+ {
14
+ private static $_instance;
15
+ private $_sitemap_file ;
16
+ private $_blacklist_file ;
17
+ private $_site_url ;
18
+ const CRWL_BLACKLIST = 'crawler_blacklist' ;
19
+
20
+ /**
21
+ * Initialize crawler, assign sitemap path
22
+ *
23
+ * @since 1.1.0
24
+ * @access private
25
+ */
26
+ private function __construct()
27
+ {
28
+ $sitemapPath = LSWCP_DIR . 'var' ;
29
+ if ( is_multisite() ) {
30
+ $blogID = get_current_blog_id() ;
31
+ $this->_sitemap_file = $sitemapPath . '/crawlermap-' . $blogID . '.data' ;
32
+ $this->_site_url = get_site_url($blogID) ;
33
+ }
34
+ else{
35
+ $this->_sitemap_file = $sitemapPath . '/crawlermap.data' ;
36
+ $this->_site_url = get_option('siteurl') ;
37
+ }
38
+ $this->_blacklist_file = $this->_sitemap_file . '.blacklist' ;
39
+
40
+ LiteSpeed_Cache_Log::debug('Crawler log: Initialized') ;
41
+ }
42
+
43
+ /**
44
+ * Return crawler meta file
45
+ *
46
+ * @since 1.1.0
47
+ * @access public
48
+ * @return string Json data file path
49
+ */
50
+ public function get_crawler_json_path()
51
+ {
52
+ if ( ! file_exists($this->_sitemap_file . '.meta') ) {
53
+ return false ;
54
+ }
55
+ $metaUrl = implode('/', array_slice(explode('/', $this->_sitemap_file . '.meta'), -5)) ;
56
+ return $this->_site_url . '/' . $metaUrl ;
57
+ }
58
+
59
+ /**
60
+ * Return crawler meta info
61
+ *
62
+ * @since 1.1.0
63
+ * @access public
64
+ * @return array Meta array
65
+ */
66
+ public function get_meta()
67
+ {
68
+ if ( ! file_exists($this->_sitemap_file . '.meta') || ! $meta = Litespeed_File::read($this->_sitemap_file . '.meta') ) {
69
+ return false ;
70
+ }
71
+ return json_decode($meta) ;
72
+ }
73
+
74
+ /**
75
+ * Return blacklist content
76
+ *
77
+ * @since 1.1.0
78
+ * @access public
79
+ * @return string
80
+ */
81
+ public function get_blacklist()
82
+ {
83
+ return Litespeed_File::read($this->_blacklist_file) ;
84
+ }
85
+
86
+ /**
87
+ * Return blacklist count
88
+ *
89
+ * @since 1.1.0
90
+ * @access public
91
+ * @return string
92
+ */
93
+ public function count_blacklist()
94
+ {
95
+ return Litespeed_File::count_lines($this->_blacklist_file) ;
96
+ }
97
+
98
+ /**
99
+ * Save blacklist to file
100
+ *
101
+ * @since 1.1.0
102
+ * @access public
103
+ * @return bool If saved successfully
104
+ */
105
+ public function save_blacklist()
106
+ {
107
+ if ( ! isset( $_POST[ self::CRWL_BLACKLIST ] ) ) {
108
+ $msg = __( 'Can not find any form data for blacklist', 'litespeed-cache' ) ;
109
+ LiteSpeed_Cache_Admin_Display::add_notice( LiteSpeed_Cache_Admin_Display::NOTICE_RED, $msg ) ;
110
+ return false ;
111
+ }
112
+ $content = $_POST[ self::CRWL_BLACKLIST ] ;
113
+ $content = array_map( 'trim', explode( "\n", $content ) ) ;// remove space
114
+ $content = implode( "\n", array_filter( $content ) ) ;
115
+
116
+ // save blacklist file
117
+ $ret = Litespeed_File::save( $this->_blacklist_file, $content, true, false, false ) ;
118
+ if ( $ret !== true ) {
119
+ LiteSpeed_Cache_Admin_Display::add_notice( LiteSpeed_Cache_Admin_Display::NOTICE_RED, $ret ) ;
120
+ }
121
+ else {
122
+ $msg = sprintf(
123
+ __( 'File saved successfully: %s', 'litespeed-cache' ),
124
+ $this->_blacklist_file
125
+ ) ;
126
+ LiteSpeed_Cache_Admin_Display::add_notice( LiteSpeed_Cache_Admin_Display::NOTICE_GREEN, $msg ) ;
127
+ }
128
+
129
+ return true ;
130
+ }
131
+
132
+ /**
133
+ * Append urls to current list
134
+ *
135
+ * @since 1.1.0
136
+ * @access public
137
+ * @param array $list The url list needs to be appended
138
+ */
139
+ public function append_blacklist( $list )
140
+ {
141
+ if ( LiteSpeed_Cache_Log::get_enabled() ) {
142
+ LiteSpeed_Cache_Log::push( 'Crawler log: append blacklist ' . count( $list ) ) ;
143
+ }
144
+ $ori_list = Litespeed_File::read( $this->_blacklist_file ) ;
145
+ $ori_list = explode( "\n", $ori_list ) ;
146
+ $ori_list = array_merge( $ori_list, $list ) ;
147
+ $ori_list = array_map( 'trim', $ori_list ) ;
148
+ $ori_list = array_filter( $ori_list ) ;
149
+ $content = implode( "\n", $ori_list ) ;
150
+
151
+ // save blacklist
152
+ $ret = Litespeed_File::save( $this->_blacklist_file, $content, true, false, false ) ;
153
+ if ( $ret !== true ) {
154
+ LiteSpeed_Cache_Log::debug( 'Crawler log: append blacklist failed: ' . $ret ) ;
155
+ return false ;
156
+ }
157
+
158
+ return true ;
159
+ }
160
+
161
+ /**
162
+ * Generate sitemap
163
+ *
164
+ * @since 1.1.0
165
+ * @access public
166
+ */
167
+ public function generate_sitemap()
168
+ {
169
+ $ret = $this->_generate_sitemap() ;
170
+ if ( $ret !== true ) {
171
+ LiteSpeed_Cache_Admin_Display::add_notice(LiteSpeed_Cache_Admin_Display::NOTICE_RED, $ret) ;
172
+ }
173
+ else {
174
+ $msg = sprintf(
175
+ __('File created successfully: %s', 'litespeed-cache'),
176
+ $this->_sitemap_file
177
+ ) ;
178
+ LiteSpeed_Cache_Admin_Display::add_notice(LiteSpeed_Cache_Admin_Display::NOTICE_GREEN, $msg) ;
179
+ }
180
+ }
181
+
182
+ /**
183
+ * Parse custom sitemap and return urls
184
+ *
185
+ * @since 1.1.1
186
+ * @access public
187
+ * @param string $sitemap The url set map address
188
+ * @param boolean $return_detail If return url list
189
+ * @return bollean|array Url list or if is a sitemap
190
+ */
191
+ public function parse_custom_sitemap($sitemap, $return_detail = true)
192
+ {
193
+ if ( ! file_get_contents($sitemap) ) {
194
+ return LiteSpeed_Cache_Admin_Error::E_SETTING_CUSTOM_SITEMAP_READ ;
195
+ }
196
+ $xml_object = simplexml_load_file($sitemap) ;
197
+ if ( ! $xml_object ) {
198
+ return LiteSpeed_Cache_Admin_Error::E_SETTING_CUSTOM_SITEMAP_PARSE ;
199
+ }
200
+ if ( ! $return_detail ) {
201
+ return true ;
202
+ }
203
+ // start parsing
204
+ $_urls = array() ;
205
+
206
+ $xml_array = (array)$xml_object ;
207
+ if ( !empty($xml_array['sitemap']) ) {// parse sitemap set
208
+ if ( is_object($xml_array['sitemap']) ) {
209
+ $xml_array['sitemap'] = (array)$xml_array['sitemap'] ;
210
+ }
211
+ if ( !empty($xml_array['sitemap']['loc']) ) {// is single sitemap
212
+ $urls = $this->parse_custom_sitemap($xml_array['sitemap']['loc']) ;
213
+ if ( is_array($urls) && !empty($urls) ) {
214
+ $_urls = array_merge($_urls, $urls) ;
215
+ }
216
+ }
217
+ else {
218
+ // parse multiple sitemaps
219
+ foreach ($xml_array['sitemap'] as $val) {
220
+ $val = (array)$val ;
221
+ if ( !empty($val['loc']) ) {
222
+ $urls = $this->parse_custom_sitemap($val['loc']) ;// recursive parse sitemap
223
+ if ( is_array($urls) && !empty($urls) ) {
224
+ $_urls = array_merge($_urls, $urls) ;
225
+ }
226
+ }
227
+ }
228
+ }
229
+ }
230
+ elseif ( !empty($xml_array['url']) ) {// parse url set
231
+ if ( is_object($xml_array['url']) ) {
232
+ $xml_array['url'] = (array)$xml_array['url'] ;
233
+ }
234
+ // if only 1 element
235
+ if ( !empty($xml_array['url']['loc']) ) {
236
+ $_urls[] = $xml_array['url']['loc'] ;
237
+ }
238
+ else {
239
+ foreach ($xml_array['url'] as $val) {
240
+ $val = (array)$val ;
241
+ if ( !empty($val['loc']) ) {
242
+ $_urls[] = $val['loc'] ;
243
+ }
244
+ }
245
+ }
246
+ }
247
+
248
+ return $_urls ;
249
+ }
250
+
251
+ /**
252
+ * Generate the sitemap
253
+ *
254
+ * @since 1.1.0
255
+ * @access protected
256
+ * @return string|true
257
+ */
258
+ protected function _generate_sitemap()
259
+ {
260
+ // use custom sitemap
261
+ if ( $sitemap = LiteSpeed_Cache::config( LiteSpeed_Cache_Config::CRWL_CUSTOM_SITEMAP ) ) {
262
+ $sitemap_urls = $this->parse_custom_sitemap( $sitemap ) ;
263
+ $urls = array() ;
264
+ $offset = strlen( $this->_site_url ) ;
265
+ if ( is_array( $sitemap_urls ) && ! empty( $sitemap_urls ) ) {
266
+ foreach ( $sitemap_urls as $val ) {
267
+ if ( stripos( $val, $this->_site_url ) === 0 ) {
268
+ $urls[] = substr( $val, $offset ) ;
269
+ }
270
+ }
271
+ }
272
+ }
273
+ else {
274
+ $urls = LiteSpeed_Cache_Crawler_Sitemap::get_instance()->generate_data() ;
275
+ }
276
+
277
+ // filter urls
278
+ $blacklist = Litespeed_File::read( $this->_blacklist_file ) ;
279
+ $blacklist = explode( "\n", $blacklist ) ;
280
+ $urls = array_diff( $urls, $blacklist ) ;
281
+ LiteSpeed_Cache_Log::debug( 'Crawler log: Generate sitemap' ) ;
282
+
283
+ $ret = Litespeed_File::save( $this->_sitemap_file, implode( "\n", $urls ), true, false, false ) ;
284
+
285
+ // refresh list size in meta
286
+ $crawler = new Litespeed_Crawler( $this->_sitemap_file ) ;
287
+ $crawler->refresh_list_size() ;
288
+
289
+ return $ret ;
290
+ }
291
+
292
+ /**
293
+ * Get sitemap file info
294
+ *
295
+ * @since 1.1.0
296
+ * @access public
297
+ */
298
+ public function sitemap_time()
299
+ {
300
+ if ( ! file_exists($this->_sitemap_file) ) {
301
+ return false ;
302
+ }
303
+
304
+ $filetime = date('m/d/Y H:i:s', filemtime($this->_sitemap_file)) ;
305
+
306
+ return $filetime ;
307
+ }
308
+
309
+ /**
310
+ * Create reset pos file
311
+ *
312
+ * @since 1.1.0
313
+ * @access public
314
+ * @return mixed True or error message
315
+ */
316
+ public function reset_pos()
317
+ {
318
+ $crawler = new Litespeed_Crawler($this->_sitemap_file) ;
319
+ $ret = $crawler->reset_pos() ;
320
+ $log = 'Crawler log: Reset pos. ' ;
321
+ if ( $ret !== true ) {
322
+ $log .= "Error: $ret" ;
323
+ $msg = sprintf(__('Failed to send position reset notification: %s', 'litespeed-cache'), $ret) ;
324
+ LiteSpeed_Cache_Admin_Display::add_notice(LiteSpeed_Cache_Admin_Display::NOTICE_RED, $msg) ;
325
+ }
326
+ else {
327
+ $msg = __('Position reset notification sent successfully', 'litespeed-cache') ;
328
+ LiteSpeed_Cache_Admin_Display::add_notice(LiteSpeed_Cache_Admin_Display::NOTICE_GREEN, $msg) ;
329
+ }
330
+ LiteSpeed_Cache_Log::debug($log) ;
331
+ }
332
+
333
+ /**
334
+ * Proceed crawling
335
+ *
336
+ * @since 1.1.0
337
+ * @access public
338
+ * @param bool $force If ignore whole crawling interval
339
+ */
340
+ public static function crawl_data($force = false)
341
+ {
342
+ if ( ! LiteSpeed_Cache_Router::can_crawl() ) {
343
+ LiteSpeed_Cache_Log::debug('Crawler log: ......crawler is NOT allowed by the server admin......') ;
344
+ return false;
345
+ }
346
+ if ( $force ) {
347
+ LiteSpeed_Cache_Log::debug('Crawler log: ......crawler manually ran......') ;
348
+ }
349
+ return self::get_instance()->_crawl_data($force) ;
350
+ }
351
+
352
+ /**
353
+ * Crawling start
354
+ *
355
+ * @since 1.1.0
356
+ * @access protected
357
+ * @param bool $force If ignore whole crawling interval
358
+ */
359
+ protected function _crawl_data($force)
360
+ {
361
+ LiteSpeed_Cache_Log::debug('Crawler log: ......crawler started......') ;
362
+ // for the first time running
363
+ if ( ! file_exists($this->_sitemap_file) ) {
364
+ $ret = $this->_generate_sitemap() ;
365
+ if ( $ret !== true ) {
366
+ LiteSpeed_Cache_Log::debug('Crawler log: ' . $ret) ;
367
+ return $this->output($ret) ;
368
+ }
369
+ }
370
+
371
+ $options = LiteSpeed_Cache_Config::get_instance()->get_options() ;
372
+
373
+ $crawler = new Litespeed_Crawler($this->_sitemap_file) ;
374
+ // if finished last time, regenerate sitemap
375
+ if ( $last_fnished_at = $crawler->get_done_status() ) {
376
+ // check whole crawling interval
377
+ if ( ! $force && time() - $last_fnished_at < $options[LiteSpeed_Cache_Config::CRWL_CRAWL_INTERVAL] ) {
378
+ LiteSpeed_Cache_Log::debug('Crawler log: Cron abort: cache warmed already.') ;
379
+ // if not reach whole crawling interval, exit
380
+ return;
381
+ }
382
+ $this->_generate_sitemap() ;
383
+ }
384
+ $crawler->set_base_url($this->_site_url) ;
385
+ $crawler->set_run_duration($options[LiteSpeed_Cache_Config::CRWL_RUN_DURATION]) ;
386
+ $crawler->set_run_delay($options[LiteSpeed_Cache_Config::CRWL_USLEEP]) ;
387
+ $crawler->set_threads_limit($options[LiteSpeed_Cache_Config::CRWL_THREADS]) ;
388
+ $crawler->set_load_limit($options[LiteSpeed_Cache_Config::CRWL_LOAD_LIMIT]) ;
389
+ if ( $options[LiteSpeed_Cache_Config::CRWL_DOMAIN_IP] ) {
390
+ $crawler->set_domain_ip($options[LiteSpeed_Cache_Config::CRWL_DOMAIN_IP]) ;
391
+ }
392
+ $ret = $crawler->engine_start() ;
393
+
394
+ // merge blacklist
395
+ if ( $ret['blacklist'] ) {
396
+ $this->append_blacklist($ret['blacklist']) ;
397
+ }
398
+
399
+ if ( ! empty($ret['crawled']) && LiteSpeed_Cache_Log::get_enabled() ) {
400
+ LiteSpeed_Cache_Log::push('Crawler log: Last crawled ' . $ret['crawled'] . ' item(s)') ;
401
+ }
402
+
403
+ // return error
404
+ if ( $ret['error'] !== false ) {
405
+ LiteSpeed_Cache_Log::debug('Crawler log: ' . $ret['error']) ;
406
+ return $this->output($ret['error']) ;
407
+ }
408
+ else {
409
+ $msg = 'Reached end of sitemap file. Crawling completed.' ;
410
+ $msg_t = __('Reached end of sitemap file. Crawling completed.', 'litespeed-cache') ;
411
+ LiteSpeed_Cache_Log::debug('Crawler log: ' . $msg) ;
412
+ return $this->output($msg_t) ;
413
+ }
414
+ }
415
+
416
+ /**
417
+ * Output info and exit
418
+ *
419
+ * @since 1.1.0
420
+ * @access protected
421
+ * @param string $error Error info
422
+ */
423
+ protected function output($msg)
424
+ {
425
+ if ( defined('DOING_CRON') ) {
426
+ echo $msg ;
427
+ // exit();
428
+ }
429
+ else {
430
+ echo "<script>alert('" . htmlspecialchars($msg) . "');</script>" ;
431
+ // exit;
432
+ }
433
+ }
434
+
435
+ /**
436
+ * Get the current instance object.
437
+ *
438
+ * @since 1.1.0
439
+ * @access public
440
+ * @return Current class instance.
441
+ */
442
+ public static function get_instance()
443
+ {
444
+ $cls = get_called_class() ;
445
+ if ( ! isset(self::$_instance) ) {
446
+ self::$_instance = new $cls() ;
447
+ }
448
+
449
+ return self::$_instance ;
450
+ }
451
+ }
includes/litespeed-cache-esi-dummy.tpl.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is a dummy template file.
5
+ *
6
+ * It is meant to be used to skip comment processing on the main request
7
+ * when using esi comments.
8
+ */
9
+
includes/litespeed-cache-esi.class.php ADDED
@@ -0,0 +1,545 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * The esi class.
5
+ *
6
+ * This is used to define all esi related functions.
7
+ *
8
+ * @since 1.1.3
9
+ * @package LiteSpeed_Cache
10
+ * @subpackage LiteSpeed_Cache/includes
11
+ * @author LiteSpeed Technologies <info@litespeedtech.com>
12
+ */
13
+ class LiteSpeed_Cache_ESI
14
+ {
15
+ private static $_instance ;
16
+
17
+ private static $has_esi = false ;
18
+ private $esi_args = null ;
19
+
20
+ const QS_ACTION = 'lsesi' ;
21
+ const POSTTYPE = 'lswcp' ;
22
+ const QS_PARAMS = 'esi' ;
23
+
24
+ const PARAM_ARGS = 'args' ;
25
+ const PARAM_BLOCK_ID = 'block_id' ;
26
+ const PARAM_ID = 'id' ;
27
+ const PARAM_INSTANCE = 'instance' ;
28
+ const PARAM_NAME = 'name' ;
29
+
30
+ const WIDGET_OPID_ESIENABLE = 'widget_esi_enable' ;
31
+ const WIDGET_OPID_TTL = 'widget_ttl' ;
32
+
33
+ /**
34
+ * Constructor of ESI
35
+ *
36
+ * @since 1.1.3
37
+ */
38
+ private function __construct()
39
+ {
40
+ }
41
+
42
+ /**
43
+ * Check if the requested page has esi elements. If so, return esi on
44
+ * header.
45
+ *
46
+ * @since 1.1.3
47
+ * @access public
48
+ * @return string Esi On header if request has esi, empty string otherwise.
49
+ */
50
+ public static function has_esi()
51
+ {
52
+ return self::$has_esi ;
53
+ }
54
+
55
+ /**
56
+ * Sets that the requested page has esi elements.
57
+ *
58
+ * @since 1.1.3
59
+ * @access public
60
+ */
61
+ public static function set_has_esi()
62
+ {
63
+ self::$has_esi = true ;
64
+ }
65
+
66
+ /**
67
+ * Hooked to the template_include action.
68
+ * Selects the esi template file when the post type is a LiteSpeed ESI page.
69
+ *
70
+ * @since 1.1.3
71
+ * @access public
72
+ * @param string $template The template path filtered.
73
+ * @return string The new template path.
74
+ */
75
+ public static function esi_template($template)
76
+ {
77
+ // Add comment forum esi for logged-in user or commenter
78
+ if ( LiteSpeed_Cache_Router::is_ajax() && LiteSpeed_Cache_Vary::has_vary() ) {
79
+ add_filter( 'comment_form_defaults', array( self::get_instance(), 'register_comment_form_actions' ) ) ;
80
+ }
81
+
82
+ // Check if is an ESI request
83
+ if ( ! empty( $_GET[ LiteSpeed_Cache_ESI::QS_ACTION ] ) && $_GET[ LiteSpeed_Cache_ESI::QS_ACTION ] == LiteSpeed_Cache_ESI::POSTTYPE ) {
84
+ define('LSCACHE_IS_ESI', true) ;
85
+
86
+ self::get_instance()->register_esi_actions() ;
87
+
88
+ if ( ! LiteSpeed_Cache::config(LiteSpeed_Cache_Config::OPID_ESI_CACHE) ) {
89
+ LiteSpeed_Cache_Control::set_nocache( 'ESI page is not cacheable' ) ;
90
+ }
91
+ return LSWCP_DIR . 'includes/litespeed-cache-esi.tpl.php' ;
92
+ }
93
+ self::get_instance()->register_not_esi_actions() ;
94
+ return $template ;
95
+ }
96
+
97
+ /**
98
+ * Register all of the hooks related to the esi logic of the plugin.
99
+ * Specifically when the page IS an esi page.
100
+ *
101
+ * @since 1.1.3
102
+ * @access public
103
+ */
104
+ public function register_esi_actions()
105
+ {
106
+ add_action('litespeed_cache_load_esi_block-widget', array($this, 'load_widget_block')) ;
107
+ add_action('litespeed_cache_load_esi_block-admin-bar', array($this, 'load_admin_bar_block')) ;
108
+ add_action('litespeed_cache_load_esi_block-comment-form', array($this, 'load_comment_form_block')) ;
109
+ }
110
+
111
+ /**
112
+ * Register all of the hooks related to the esi logic of the plugin.
113
+ * Specifically when the page is NOT an esi page.
114
+ *
115
+ * @since 1.1.3
116
+ * @access public
117
+ */
118
+ public function register_not_esi_actions()
119
+ {
120
+ do_action('litespeed_cache_is_not_esi_template') ;
121
+
122
+ if ( LiteSpeed_Cache_Router::is_ajax() ) {
123
+ return ;
124
+ }
125
+
126
+ add_filter('widget_display_callback', array($this, 'sub_widget_block'), 0, 3) ;
127
+
128
+ // Add admin_bar esi
129
+ if ( LiteSpeed_Cache_Router::is_logged_in() ) {
130
+ remove_action('wp_footer', 'wp_admin_bar_render', 1000) ;
131
+ add_action('wp_footer', array($this, 'sub_admin_bar_block'), 1000) ;
132
+ }
133
+
134
+ }
135
+
136
+ /**
137
+ * Hooked to the comment_form_defaults filter.
138
+ * Stores the default comment form settings.
139
+ * This method initializes an output buffer and adds two hook functions to the WP process.
140
+ * If comment_form_sub_cancel is triggered, the output buffer is flushed because there is no need to make the comment form ESI.
141
+ * Else if sub_comment_form_block is triggered, the output buffer is cleared and an esi block is added. The remaining comment form is also buffered and cleared.
142
+ *
143
+ * @since 1.1.3
144
+ * @access public
145
+ * @param array $defaults The default comment form settings.
146
+ * @return array The default comment form settings.
147
+ */
148
+ public function register_comment_form_actions($defaults)
149
+ {
150
+ $this->esi_args = $defaults ;
151
+ ob_start() ;
152
+ add_action('comment_form_must_log_in_after', array($this, 'comment_form_sub_cancel')) ;
153
+ add_action('comment_form_comments_closed', array($this, 'comment_form_sub_cancel')) ;
154
+ add_filter('comment_form_submit_button', array($this, 'sub_comment_form_block'), 1000, 2) ;
155
+ return $defaults ;
156
+ }
157
+
158
+ /**
159
+ * Build the esi url. This method will build the html comment wrapper as well as serialize and encode the parameter array.
160
+ *
161
+ * The block_id parameter should contain alphanumeric and '-_' only.
162
+ *
163
+ * If echo is false *HAS_ESI WILL NOT BE SET TO TRUE*!
164
+ *
165
+ * @since 1.1.3
166
+ * @access private
167
+ * @param string $block_id The id to use to display the correct esi block.
168
+ * @param string $wrapper The wrapper for the esi comments.
169
+ * @param array $params The esi parameters.
170
+ * @param string $control The cache control attribute if any.
171
+ * @param boolean $echo Whether to echo the output or return it.
172
+ * @return mixed False on error, nothing if echo is true, the output otherwise.
173
+ */
174
+ public static function sub_esi_block($block_id, $wrapper, $params = array(), $control = 'private,no-vary', $echo = true)
175
+ {
176
+ if ( empty($block_id) || ! is_array($params) || preg_match('/[^\w-]/', $block_id) ) {
177
+ return false ;
178
+ }
179
+ $params[self::PARAM_BLOCK_ID] = $block_id ;
180
+ $params = apply_filters('litespeed_cache_sub_esi_params-' . $block_id, $params) ;
181
+ $control = apply_filters('litespeed_cache_sub_esi_control-' . $block_id, $control) ;
182
+ if ( !is_array($params) || !is_string($control) ) {
183
+ if ( LiteSpeed_Cache_Log::get_enabled() ) {
184
+ LiteSpeed_Cache_Log::push("Sub esi hooks returned Params: \n"
185
+ . print_r($params, true) . "\ncache control: \n"
186
+ . print_r($control, true)) ;
187
+ }
188
+ return false ;
189
+ }
190
+
191
+ $url = wp_make_link_relative(home_url()) . '?' . self::QS_ACTION . '=' . self::POSTTYPE . '&' . self::QS_PARAMS . '=' . urlencode(base64_encode(serialize($params))) ;
192
+ $output = "<!-- lscwp $wrapper --><esi:include src='$url'" ;
193
+ if ( ! empty( $control ) ) {
194
+ $output .= " cache-control='$control'" ;
195
+ }
196
+ $output .= " /><!-- lscwp $wrapper esi end -->" ;
197
+
198
+ LiteSpeed_Cache_Log::debug( "ESI block ID:$block_id; $wrapper; $control" ) ;
199
+
200
+ if ( $echo == false ) {
201
+ return $output ;
202
+ }
203
+ echo $output ;
204
+ self::set_has_esi() ;
205
+ }
206
+
207
+ /**
208
+ * Parses the request parameters on an ESI request
209
+ *
210
+ * @since 1.1.3
211
+ * @access public
212
+ */
213
+ public static function parse_esi_param()
214
+ {
215
+ if ( ! isset($_REQUEST[self::QS_PARAMS]) ) {
216
+ return false ;
217
+ }
218
+ $req_params = $_REQUEST[self::QS_PARAMS] ;
219
+ $unencrypted = base64_decode($req_params) ;
220
+ if ( $unencrypted === false ) {
221
+ return false ;
222
+ }
223
+ $unencoded = urldecode($unencrypted) ;
224
+ $params = unserialize($unencoded) ;
225
+ if ( $params === false || ! isset($params[self::PARAM_BLOCK_ID]) ) {
226
+ return false ;
227
+ }
228
+
229
+ return $params ;
230
+ }
231
+
232
+ /**
233
+ * Select the correct esi output based on the parameters in an ESI request.
234
+ *
235
+ * @since 1.1.3
236
+ * @access public
237
+ */
238
+ public static function load_esi_block()
239
+ {
240
+ $params = self::parse_esi_param() ;
241
+ if ( $params === false ) {
242
+ return ;
243
+ }
244
+ $esi_id = $params[ self::PARAM_BLOCK_ID ] ;
245
+ if ( LiteSpeed_Cache_Log::get_enabled() ) {
246
+ $logInfo = '------- ESI ------- ' ;
247
+ if( ! empty( $params[ self::PARAM_NAME ] ) ) {
248
+ $logInfo .= ' Name: ' . $params[ self::PARAM_NAME ] . ' ----- ' ;
249
+ }
250
+ $logInfo .= $esi_id . ' -------' ;
251
+ LiteSpeed_Cache_Log::push( $logInfo ) ;
252
+ }
253
+
254
+ $orig = $_SERVER[ 'REQUEST_URI' ] ;
255
+ $_SERVER[ 'REQUEST_URI' ] = !empty( $_SERVER[ 'ESI_REFERER' ] ) ? $_SERVER[ 'ESI_REFERER' ] : false ;
256
+
257
+ LiteSpeed_Cache_Tag::add( rtrim( LiteSpeed_Cache_Tag::TYPE_ESI, '.' ) ) ;
258
+ LiteSpeed_Cache_Tag::add( LiteSpeed_Cache_Tag::TYPE_ESI . $esi_id ) ;
259
+
260
+ // LiteSpeed_Cache_Log::debug(var_export($params, true ));
261
+
262
+ do_action('litespeed_cache_load_esi_block-' . $esi_id, $params) ;
263
+
264
+ $_SERVER[ 'REQUEST_URI' ] = $orig ;
265
+ }
266
+
267
+ // BEGIN helper functions
268
+ // The *_sub_* functions are helpers for the sub_* functions.
269
+ // The *_load_* functions are helpers for the load_* functions.
270
+
271
+ /**
272
+ * Get the configuration option for the current widget.
273
+ *
274
+ * @since 1.1.3
275
+ * @access public
276
+ * @param WP_Widget $widget The widget to get the options for.
277
+ * @return mixed null if not found, an array of the options otherwise.
278
+ */
279
+ public static function widget_load_get_options($widget)
280
+ {
281
+ add_filter('litespeed_cache_widget_default_options', 'LiteSpeed_Cache_ESI::widget_default_options', 10, 2) ;
282
+
283
+ if ( ! is_numeric($widget->number) ) {
284
+ return null ;
285
+ }
286
+
287
+ if ( $widget->updated ) {
288
+ $settings = get_option($widget->option_name) ;
289
+ }
290
+ else {
291
+ $settings = $widget->get_settings() ;
292
+ }
293
+
294
+ if ( ! isset($settings) ) {
295
+ return null ;
296
+ }
297
+
298
+ $instance = $settings[$widget->number] ;
299
+
300
+ if ( ! isset($instance) || ! isset($instance[LiteSpeed_Cache_Config::OPTION_NAME]) ) {
301
+ return null;
302
+ }
303
+
304
+ return $instance[LiteSpeed_Cache_Config::OPTION_NAME] ;
305
+ }
306
+
307
+ /**
308
+ * Loads the default options for default WordPress widgets.
309
+ *
310
+ * @since 1.1.3
311
+ * @access public
312
+ * @param array $options The current options selected.
313
+ * @param WP_Widget $widget The widget to be configured.
314
+ * @return array The updated options.
315
+ */
316
+ public static function widget_default_options($options, $widget)
317
+ {
318
+ if ( ! is_array($options) ) {
319
+ return $options ;
320
+ }
321
+
322
+ $widget_name = get_class($widget) ;
323
+ switch ($widget_name) {
324
+ case 'WP_Widget_Recent_Posts' :
325
+ case 'WP_Widget_Recent_Comments' :
326
+ $options[self::WIDGET_OPID_ESIENABLE] = true ;
327
+ $options[self::WIDGET_OPID_TTL] = 86400 ;
328
+ break ;
329
+ default :
330
+ break ;
331
+ }
332
+ return $options ;
333
+ }
334
+
335
+ /**
336
+ * Hooked to the comment_form_must_log_in_after and
337
+ * comment_form_comments_closed actions.
338
+ *
339
+ * @since 1.1.3
340
+ * @access public
341
+ */
342
+ public function comment_form_sub_cancel()
343
+ {
344
+ ob_flush() ;
345
+ }
346
+
347
+ /**
348
+ * Hooked to the comment_form_after action.
349
+ * Cleans up the remaining comment form output.
350
+ *
351
+ * @since 1.1.3
352
+ * @access public
353
+ */
354
+ public function comment_form_sub_clean()
355
+ {
356
+ ob_clean() ;
357
+ }
358
+
359
+ // END helper functions.
360
+
361
+ /**
362
+ * Hooked to the widget_display_callback filter.
363
+ * If the admin configured the widget to display via esi, this function
364
+ * will set up the esi request and cancel the widget display.
365
+ *
366
+ * @since 1.1.3
367
+ * @access public
368
+ * @param array $instance Parameter used to build the widget.
369
+ * @param WP_Widget $widget The widget to build.
370
+ * @param array $args Parameter used to build the widget.
371
+ * @return mixed Return false if display through esi, instance otherwise.
372
+ */
373
+ public function sub_widget_block(array $instance, WP_Widget $widget, array $args)
374
+ {
375
+ $name = get_class($widget) ;
376
+ if ( ! isset($instance[LiteSpeed_Cache_Config::OPTION_NAME]) ) {
377
+ return $instance ;
378
+ }
379
+ $options = $instance[LiteSpeed_Cache_Config::OPTION_NAME] ;
380
+ if ( ! isset($options) || ! $options[self::WIDGET_OPID_ESIENABLE] ) {
381
+ if ( LiteSpeed_Cache_Log::get_enabled() ) {
382
+ LiteSpeed_Cache_Log::push('ESI off for widget ' . $name . ' because '. (!isset($options) ? 'options not set' : 'esi disabled for widget')) ;
383
+ }
384
+ return $instance ;
385
+ }
386
+ $params = array(
387
+ self::PARAM_NAME => $name,
388
+ self::PARAM_ID => $widget->id,
389
+ self::PARAM_INSTANCE => $instance,
390
+ self::PARAM_ARGS => $args
391
+ ) ;
392
+
393
+ self::sub_esi_block('widget', 'widget ' . $name, $params, 'no-vary') ;
394
+ return false ;
395
+ }
396
+
397
+ /**
398
+ * Hooked to the wp_footer action.
399
+ * Sets up the ESI request for the admin bar.
400
+ *
401
+ * @access public
402
+ * @since 1.1.3
403
+ * @global type $wp_admin_bar
404
+ */
405
+ public function sub_admin_bar_block()
406
+ {
407
+ global $wp_admin_bar ;
408
+
409
+ if ( ! is_admin_bar_showing() || ! is_object($wp_admin_bar) ) {
410
+ return ;
411
+ }
412
+
413
+ self::sub_esi_block('admin-bar', 'adminbar') ;
414
+ }
415
+
416
+ /**
417
+ * Hooked to the comment_form_submit_button filter.
418
+ *
419
+ * This method will compare the used comment form args against the default args. The difference will be passed to the esi request.
420
+ *
421
+ * @access public
422
+ * @since 1.1.3
423
+ * @global type $post
424
+ * @param $unused
425
+ * @param array $args The used comment form args.
426
+ * @return unused.
427
+ */
428
+ public function sub_comment_form_block($unused, $args)
429
+ {
430
+ if ( empty($args) || empty($this->esi_args) ) {
431
+ LiteSpeed_Cache_Log::debug('comment form args empty?') ;
432
+ return $unused ;
433
+ }
434
+ $esi_args = array() ;
435
+
436
+ foreach ($args as $key => $val) {
437
+ if ( ! isset($this->esi_args[$key]) ) {
438
+ $esi_args[$key] = $val ;
439
+ }
440
+ elseif ( is_array($val) ) {
441
+ $diff = array_diff_assoc($val, $this->esi_args[$key]) ;
442
+ if ( ! empty($diff) ) {
443
+ $esi_args[$key] = $diff ;
444
+ }
445
+ }
446
+ elseif ( $val !== $this->esi_args[$key] ) {
447
+ $esi_args[$key] = $val ;
448
+ }
449
+ }
450
+
451
+ ob_clean() ;
452
+ global $post ;
453
+ $params = array(
454
+ self::PARAM_ID => $post->ID,
455
+ self::PARAM_ARGS => $esi_args,
456
+ ) ;
457
+
458
+ self::sub_esi_block('comment-form', 'comment form', $params) ;
459
+ ob_start() ;
460
+ add_action('comment_form_after', array($this, 'comment_form_sub_clean')) ;
461
+ return $unused ;
462
+ }
463
+
464
+ /**
465
+ * Parses the esi input parameters and generates the widget for esi display.
466
+ *
467
+ * @access public
468
+ * @since 1.1.3
469
+ * @global $wp_widget_factory
470
+ * @param array $params Input parameters needed to correctly display widget
471
+ */
472
+ public function load_widget_block($params)
473
+ {
474
+ global $wp_widget_factory ;
475
+ $widget = $wp_widget_factory->widgets[$params[self::PARAM_NAME]] ;
476
+ $option = self::widget_load_get_options($widget) ;
477
+ // Since we only reach here via esi, safe to assume setting exists.
478
+ $ttl = $option[self::WIDGET_OPID_TTL] ;
479
+ if ( LiteSpeed_Cache_Log::get_enabled() ) {
480
+ LiteSpeed_Cache_Log::push('ESI widget render: name ' . $params[self::PARAM_NAME] . ', id ' . $params[self::PARAM_ID] . ', ttl ' . $ttl) ;
481
+ }
482
+ if ( $ttl == 0 ) {
483
+ LiteSpeed_Cache_Control::set_nocache( 'ESI Widget time to live set to 0' ) ;
484
+ }
485
+ else {
486
+ LiteSpeed_Cache_Control::set_custom_ttl($ttl) ;
487
+ LiteSpeed_Cache_Control::set_no_vary() ;
488
+ // LiteSpeed_Cache_Control::set_public() ; no need as by default its public
489
+ LiteSpeed_Cache_Tag::add(LiteSpeed_Cache_Tag::TYPE_WIDGET . $params[self::PARAM_ID]) ;
490
+ }
491
+ the_widget($params[self::PARAM_NAME], $params[self::PARAM_INSTANCE], $params[self::PARAM_ARGS]) ;
492
+ }
493
+
494
+ /**
495
+ * Generates the admin bar for esi display.
496
+ *
497
+ * @access public
498
+ * @since 1.1.3
499
+ */
500
+ public function load_admin_bar_block()
501
+ {
502
+ wp_admin_bar_render() ;
503
+ LiteSpeed_Cache_Control::set_private() ;
504
+ LiteSpeed_Cache_Control::set_no_vary() ;
505
+ }
506
+
507
+
508
+ /**
509
+ * Parses the esi input parameters and generates the comment form for esi display.
510
+ *
511
+ * @access public
512
+ * @since 1.1.3
513
+ * @param array $params Input parameters needed to correctly display comment form
514
+ */
515
+ public function load_comment_form_block($params)
516
+ {
517
+ remove_filter('comment_form_defaults', array($this, 'register_comment_form_actions')) ;
518
+ comment_form($params[self::PARAM_ARGS], $params[self::PARAM_ID]) ;
519
+ if ( LiteSpeed_Cache_Vary::has_vary() ) {
520
+ LiteSpeed_Cache_Control::set_private() ;
521
+ LiteSpeed_Cache_Control::set_no_vary() ;
522
+ }
523
+ // else {
524
+ // LiteSpeed_Cache_Control::set_public() ; no need as by default its public
525
+ // }
526
+
527
+ }
528
+
529
+ /**
530
+ * Get the current instance object.
531
+ *
532
+ * @since 1.1.3
533
+ * @access public
534
+ * @return Current class instance.
535
+ */
536
+ public static function get_instance()
537
+ {
538
+ $cls = get_called_class() ;
539
+ if ( ! isset(self::$_instance) ) {
540
+ self::$_instance = new $cls() ;
541
+ }
542
+
543
+ return self::$_instance ;
544
+ }
545
+ }
includes/litespeed-cache-esi.tpl.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if ( ! defined('ABSPATH') ) {
4
+ die() ;
5
+ }
6
+
7
+ LiteSpeed_Cache_ESI::load_esi_block() ;
8
+
9
+
includes/litespeed-cache-log.class.php ADDED
@@ -0,0 +1,293 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The plugin logging class.
4
+ *
5
+ * This generate the valid action.
6
+ *
7
+ * @since 1.1.0
8
+ * @package LiteSpeed_Cache
9
+ * @subpackage LiteSpeed_Cache/includes
10
+ * @author LiteSpeed Technologies <info@litespeedtech.com>
11
+ */
12
+ class LiteSpeed_Cache_Log
13
+ {
14
+ private static $_instance ;
15
+ private static $_debug ;
16
+ private static $log_path ;
17
+ private static $_prefix ;
18
+ private static $_enabled = false ;
19
+
20
+ /**
21
+ * Log class Constructor
22
+ *
23
+ * NOTE: in this process, until last step ( self::$_debug = true ), any usage to WP filter should not be used to prevent infinite loop with log_filters()
24
+ *
25
+ * @since 1.1.2
26
+ * @access public
27
+ */
28
+ private function __construct()
29
+ {
30
+ self::$log_path = LSWCP_CONTENT_DIR . '/debug.log' ;
31
+ if ( ! empty( $_SERVER[ 'HTTP_USER_AGENT' ] ) && $_SERVER[ 'HTTP_USER_AGENT' ] === Litespeed_Crawler::FAST_USER_AGENT ) {
32
+ self::$log_path = LSWCP_CONTENT_DIR . '/crawler.log' ;
33
+ }
34
+ if ( ! defined( 'LSCWP_LOG_TAG' ) ) {
35
+ define( 'LSCWP_LOG_TAG', get_current_blog_id() ) ;
36
+ }
37
+
38
+ if ( LiteSpeed_Cache::config( LiteSpeed_Cache_Config::OPID_DEBUG_LEVEL ) ) {
39
+ define( 'LSCWP_LOG_MORE', true ) ;
40
+ }
41
+
42
+ $this->_init_request() ;
43
+ self::$_debug = true ;
44
+ }
45
+
46
+ /**
47
+ * Heartbeat control
48
+ *
49
+ * @since 1.1.5
50
+ * @access public
51
+ */
52
+ public static function disable_heartbeat()
53
+ {
54
+ wp_deregister_script( 'heartbeat' ) ;
55
+ }
56
+
57
+ /**
58
+ * Check if log class finished initialized
59
+ *
60
+ * @since 1.1.3
61
+ * @access public
62
+ */
63
+ public static function initialized()
64
+ {
65
+ return isset( self::$_debug ) ;
66
+ }
67
+
68
+ /**
69
+ * Enable debug log
70
+ *
71
+ * @since 1.1.0
72
+ * @access public
73
+ */
74
+ public static function set_enabled()
75
+ {
76
+ self::$_enabled = true ;
77
+
78
+ if ( ! isset( self::$_debug ) ) {// If not initialized, do it now
79
+ self::get_instance() ;
80
+ }
81
+
82
+ // Check if hook filters
83
+ if ( LiteSpeed_Cache::config( LiteSpeed_Cache_Config::OPID_LOG_FILTERS ) ) {
84
+ add_action( 'all', 'LiteSpeed_Cache_Log::log_filters' ) ;
85
+ }
86
+ }
87
+
88
+ /**
89
+ * Log all filters and action hooks
90
+ *
91
+ * @since 1.1.5
92
+ * @access public
93
+ */
94
+ public static function log_filters()
95
+ {
96
+ $action = current_filter() ;
97
+ if ( $ignore_filters = LiteSpeed_Cache::config( LiteSpeed_Cache_Config::OPID_LOG_IGNORE_FILTERS ) ) {
98
+ $ignore_filters = explode( "\n", $ignore_filters ) ;
99
+ if ( in_array( $action, $ignore_filters ) ) {
100
+ return ;
101
+ }
102
+ }
103
+
104
+ if ( $ignore_part_filters = LiteSpeed_Cache::config( LiteSpeed_Cache_Config::OPID_LOG_IGNORE_PART_FILTERS ) ) {
105
+ $ignore_part_filters = explode( "\n", $ignore_part_filters ) ;
106
+ foreach ( $ignore_part_filters as $val ) {
107
+ if ( stripos( $action, $val ) !== false ) {
108
+ return ;
109
+ }
110
+ }
111
+ }
112
+
113
+ self::debug( "===log filter: $action" ) ;
114
+ }
115
+
116
+ /**
117
+ * Get debug log status
118
+ *
119
+ * @since 1.1.0
120
+ * @access public
121
+ */
122
+ public static function get_enabled()
123
+ {
124
+ return self::$_enabled ;
125
+ }
126
+
127
+ /**
128
+ * Formats the log message with a consistent prefix.
129
+ *
130
+ * @since 1.0.12
131
+ * @access private
132
+ * @param string $msg The log message to write.
133
+ * @return string The formatted log message.
134
+ */
135
+ private static function format_message( $msg )
136
+ {
137
+ if ( ! isset( self::$_prefix ) ) {
138
+ // address
139
+ if ( PHP_SAPI == 'cli' ) {
140
+ $addr = '=CLI=' ;
141
+ if ( isset( $_SERVER[ 'USER' ] ) ) {
142
+ $addr .= $_SERVER[ 'USER' ] ;
143
+ }
144
+ elseif ( $_SERVER[ 'HTTP_X_FORWARDED_FOR' ] ) {
145
+ $addr .= $_SERVER[ 'HTTP_X_FORWARDED_FOR' ] ;
146
+ }
147
+ }
148
+ else {
149
+ $addr = $_SERVER[ 'REMOTE_ADDR' ] . ':' . $_SERVER[ 'REMOTE_PORT' ] ;
150
+ }
151
+ // Generate a unique string per request
152
+ $unique = '' ;
153
+ $_random_list = '0123456789abcdefghijklmnopqrstuvwxyz' ;
154
+ $max = strlen( $_random_list ) - 1 ;
155
+ for( $i = 0 ; $i < 3 ; $i++ ) {
156
+ $unique .= $_random_list[ mt_rand( 0, $max ) ] ;
157
+ }
158
+ self::$_prefix = sprintf( " [%s %s %s] ", $addr, LSCWP_LOG_TAG, $unique ) ;
159
+ }
160
+ return date( 'm/d/y H:i:s' ) . self::$_prefix . $msg . "\n" ;
161
+ }
162
+
163
+ /**
164
+ * Direct call to log a debug message.
165
+ *
166
+ * @since 1.1.3
167
+ * @access public
168
+ * @param string $msg The debug message.
169
+ * @param int $backtrace_limit Backtrace depth.
170
+ */
171
+ public static function debug( $msg, $backtrace_limit = false )
172
+ {
173
+ if ( self::get_enabled() ) {
174
+ self::push( $msg, $backtrace_limit !== false ? $backtrace_limit+1 : false ) ;
175
+ }
176
+ }
177
+
178
+ /**
179
+ * Logs a debug message.
180
+ *
181
+ * @since 1.1.0
182
+ * @access public
183
+ * @param string $msg The debug message.
184
+ * @param int $backtrace_limit Backtrace depth.
185
+ */
186
+ public static function push( $msg, $backtrace_limit = false )
187
+ {
188
+ // backtrace handler
189
+ if ( defined( 'LSCWP_LOG_MORE' ) && $backtrace_limit !== false ) {
190
+ $trace = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS, $backtrace_limit + 2 ) ;
191
+ for ( $i=1 ; $i <= $backtrace_limit + 1 ; $i++ ) {// the 0st item is push()
192
+ if ( empty( $trace[$i]['class'] ) ) {
193
+ break ;
194
+ }
195
+ if ( $trace[$i]['class'] == 'LiteSpeed_Cache_Log' ) {
196
+ continue ;
197
+ }
198
+ $log = str_replace('LiteSpeed_Cache', 'LSC', $trace[$i]['class']) . $trace[$i]['type'] . $trace[$i]['function'] . '()' ;
199
+ if ( ! empty( $trace[$i-1]['line'] ) ) {
200
+ $log .= '@' . $trace[$i-1]['line'] ;
201
+ }
202
+ $msg .= " \ $log" ;
203
+ }
204
+
205
+ }
206
+
207
+ Litespeed_File::append( self::$log_path, self::format_message( $msg ) ) ;
208
+ }
209
+
210
+ /**
211
+ * Create the initial log messages with the request parameters.
212
+ *
213
+ * @since 1.0.12
214
+ * @access private
215
+ */
216
+ private function _init_request()
217
+ {
218
+ // Check log file size
219
+ $log_file_size = LiteSpeed_Cache::config( LiteSpeed_Cache_Config::OPID_LOG_FILE_SIZE ) ;
220
+ if ( file_exists( self::$log_path ) && filesize( self::$log_path ) > $log_file_size*1000000 ) {
221
+ Litespeed_File::save( self::$log_path, '' ) ;
222
+ }
223
+
224
+ // For more than 2s's requests, add more break
225
+ if ( file_exists( self::$log_path ) && time() - filemtime( self::$log_path ) > 2 ) {
226
+ Litespeed_File::append( self::$log_path, "\n\n\n\n" ) ;
227
+ }
228
+
229
+ if ( PHP_SAPI == 'cli' ) {
230
+ return ;
231
+ }
232
+
233
+ $SERVERVARS = array(
234
+ 'Query String' => '',
235
+ 'HTTP_USER_AGENT' => '',
236
+ 'HTTP_ACCEPT_ENCODING' => '',
237
+ 'HTTP_COOKIE' => '',
238
+ 'X-LSCACHE' => '',
239
+ 'LSCACHE_VARY_COOKIE' => '',
240
+ 'LSCACHE_VARY_VALUE' => ''
241
+ ) ;
242
+ $SERVER = array_merge( $SERVERVARS, $_SERVER ) ;
243
+ $params = array() ;
244
+
245
+ $params[] = sprintf( '%s %s %s', $SERVER['REQUEST_METHOD'], $SERVER['SERVER_PROTOCOL'], strtok( $SERVER['REQUEST_URI'], '?' ) ) ;
246
+
247
+ $qs = ! empty( $SERVER['QUERY_STRING'] ) ? $SERVER['QUERY_STRING'] : '' ;
248
+ if ( LiteSpeed_Cache::config( LiteSpeed_Cache_Config::OPID_COLLAPS_QS ) && strlen( $qs ) > 53 ) {
249
+ $qs = substr( $qs, 0, 53 ) . '...' ;
250
+ }
251
+ $params[] = 'Query String: ' . $qs ;
252
+ if ( defined( 'LSCWP_LOG_MORE' ) ) {
253
+ $params[] = 'User Agent: ' . $SERVER[ 'HTTP_USER_AGENT' ] ;
254
+ $params[] = 'Accept Encoding: ' . $SERVER['HTTP_ACCEPT_ENCODING'] ;
255
+ }
256
+ if ( LiteSpeed_Cache::config( LiteSpeed_Cache_Config::OPID_DEBUG_COOKIE ) ) {
257
+ $params[] = 'Cookie: ' . $SERVER['HTTP_COOKIE'] ;
258
+ }
259
+ if ( isset( $_COOKIE[ '_lscache_vary' ] ) ) {
260
+ $params[] = 'Cookie _lscache_vary: ' . $_COOKIE[ '_lscache_vary' ] ;
261
+ }
262
+ if ( defined( 'LSCWP_LOG_MORE' ) ) {
263
+ $params[] = 'X-LSCACHE: ' . ( $SERVER[ 'X-LSCACHE' ] ? 'true' : 'false' ) ;
264
+ }
265
+ if( $SERVER['LSCACHE_VARY_COOKIE'] ) {
266
+ $params[] = 'LSCACHE_VARY_COOKIE: ' . $SERVER['LSCACHE_VARY_COOKIE'] ;
267
+ }
268
+ if( $SERVER['LSCACHE_VARY_VALUE'] ) {
269
+ $params[] = 'LSCACHE_VARY_VALUE: ' . $SERVER['LSCACHE_VARY_VALUE'] ;
270
+ }
271
+
272
+ $request = array_map( 'self::format_message', $params ) ;
273
+
274
+ Litespeed_File::append( self::$log_path, $request ) ;
275
+ }
276
+
277
+ /**
278
+ * Get the current instance object.
279
+ *
280
+ * @since 1.1.0
281
+ * @access public
282
+ * @return Current class instance.
283
+ */
284
+ public static function get_instance()
285
+ {
286
+ $cls = get_called_class() ;
287
+ if ( ! isset( self::$_instance ) ) {
288
+ self::$_instance = new $cls() ;
289
+ }
290
+
291
+ return self::$_instance ;
292
+ }
293
+ }
includes/litespeed-cache-purge.class.php ADDED
@@ -0,0 +1,732 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The plugin purge class for X-LiteSpeed-Purge
4
+ *
5
+ * @since 1.1.3
6
+ * @package LiteSpeed_Cache
7
+ * @subpackage LiteSpeed_Cache/includes
8
+ * @author LiteSpeed Technologies <info@litespeedtech.com>
9
+ */
10
+ class LiteSpeed_Cache_Purge
11
+ {
12
+ private static $_instance ;
13
+ protected static $_pub_purge = array() ;
14
+ protected static $_priv_purge = array() ;
15
+ protected static $_purge_related = false ;
16
+ protected static $_purge_single = false ;
17
+
18
+ const X_HEADER = 'X-LiteSpeed-Purge' ;
19
+ const PURGE_QUEUE = 'litespeed-cache-purge-queue' ;
20
+
21
+ /**
22
+ * Adds new public purge tags to the array of purge tags for the request.
23
+ *
24
+ * @since 1.1.3
25
+ * @access public
26
+ * @param mixed $tags Tags to add to the list.
27
+ */
28
+ public static function add( $tags )
29
+ {
30
+ if ( ! is_array( $tags ) ) {
31
+ $tags = array( $tags ) ;
32
+ }
33
+ if ( ! array_diff( $tags, self::$_pub_purge ) ) {
34
+ return ;
35
+ }
36
+
37
+ self::$_pub_purge = array_merge( self::$_pub_purge, $tags ) ;
38
+
39
+ // Send purge header immediately
40
+ $curr_built = self::_build() ;
41
+ if ( defined( 'LITESPEED_DID_send_headers' ) ) {
42
+ // Can't send, already has output, need to save and wait for next run
43
+ update_option( self::PURGE_QUEUE, $curr_built ) ;
44
+ LiteSpeed_Cache_Log::debug( 'Output existed, Purge queue stored: ' . $curr_built ) ;
45
+ }
46
+ else {
47
+ @header( $curr_built ) ;
48
+ LiteSpeed_Cache_Log::debug( $curr_built ) ;
49
+ }
50
+ }
51
+
52
+ /**
53
+ * Adds new private purge tags to the array of purge tags for the request.
54
+ *
55
+ * @since 1.1.3
56
+ * @access public
57
+ * @param mixed $tags Tags to add to the list.
58
+ */
59
+ public static function add_private( $tags )
60
+ {
61
+ if ( ! is_array( $tags ) ) {
62
+ $tags = array( $tags ) ;
63
+ }
64
+ if ( ! array_diff( $tags, self::$_priv_purge ) ) {
65
+ return ;
66
+ }
67
+
68
+ self::$_priv_purge = array_merge( self::$_priv_purge, $tags ) ;
69
+
70
+ // Send purge header immediately
71
+ @header( self::_build() ) ;
72
+ }
73
+
74
+ /**
75
+ * Activate `purge related tags` for Admin QS.
76
+ *
77
+ * @since 1.1.3
78
+ * @access public
79
+ */
80
+ public static function set_purge_related()
81
+ {
82
+ self::$_purge_related = true ;
83
+ }
84
+
85
+ /**
86
+ * Activate `purge single url tag` for Admin QS.
87
+ *
88
+ * @since 1.1.3
89
+ * @access public
90
+ */
91
+ public static function set_purge_single()
92
+ {
93
+ self::$_purge_single = true ;
94
+ }
95
+
96
+ /**
97
+ * Check qs purge status
98
+ *
99
+ * @since 1.1.3
100
+ * @access public
101
+ */
102
+ public static function get_qs_purge()
103
+ {
104
+ return self::$_purge_single || self::$_purge_related ;
105
+ }
106
+
107
+ /**
108
+ * Alerts LiteSpeed Web Server to purge all pages.
109
+ *
110
+ * For multisite installs, if this is called by a site admin (not network admin),
111
+ * it will only purge all posts associated with that site.
112
+ *
113
+ * @since 1.0.0
114
+ * @access public
115
+ */
116
+ public static function purge_all()
117
+ {
118
+ self::add( '*' ) ;
119
+
120
+ // check if need to reset crawler
121
+ if ( LiteSpeed_Cache::config( LiteSpeed_Cache_Config::CRWL_CRON_ACTIVE ) ) {
122
+ LiteSpeed_Cache_Crawler::get_instance()->reset_pos() ;
123
+ }
124
+ }
125
+
126
+ /**
127
+ * Alerts LiteSpeed Web Server to purge the front page.
128
+ *
129
+ * @since 1.0.3
130
+ * @access public
131
+ */
132
+ public static function purge_front()
133
+ {
134
+ self::add( LiteSpeed_Cache_Tag::TYPE_FRONTPAGE ) ;
135
+ if ( LITESPEED_SERVER_TYPE !== 'LITESPEED_SERVER_OLS' ) {
136
+ self::add_private( LiteSpeed_Cache_Tag::TYPE_FRONTPAGE ) ;
137
+ }
138
+ }
139
+
140
+ /**
141
+ * Alerts LiteSpeed Web Server to purge pages.
142
+ *
143
+ * @since 1.0.15
144
+ * @access public
145
+ */
146
+ public static function purge_pages()
147
+ {
148
+ self::add( LiteSpeed_Cache_Tag::TYPE_PAGES ) ;
149
+ }
150
+
151
+ /**
152
+ * Alerts LiteSpeed Web Server to purge error pages.
153
+ *
154
+ * @since 1.0.14
155
+ * @access public
156
+ */
157
+ public static function purge_errors()
158
+ {
159
+ self::add( LiteSpeed_Cache_Tag::TYPE_ERROR ) ;
160
+ if ( ! isset( $_POST[LiteSpeed_Cache_Config::OPTION_NAME] ) ) {
161
+ return ;
162
+ }
163
+ $input = $_POST[LiteSpeed_Cache_Config::OPTION_NAME] ;
164
+ if ( isset( $input['include_403'] ) ) {
165
+ self::add( LiteSpeed_Cache_Tag::TYPE_ERROR . '403' ) ;
166
+ }
167
+ if ( isset( $input['include_404'] ) ) {
168
+ self::add( LiteSpeed_Cache_Tag::TYPE_ERROR . '404' ) ;
169
+ }
170
+ if ( isset( $input['include_500'] ) ) {
171
+ self::add( LiteSpeed_Cache_Tag::TYPE_ERROR . '500' ) ;
172
+ }
173
+ }
174
+
175
+ /**
176
+ * Callback to add purge tags if admin selects to purge selected category pages.
177
+ *
178
+ * @since 1.0.7
179
+ * @access public
180
+ * @param string $value The category slug.
181
+ * @param string $key Unused.
182
+ */
183
+ public function purgeby_cat_cb( $value, $key )
184
+ {
185
+ $val = trim( $value ) ;
186
+ if ( empty( $val ) ) {
187
+ return ;
188
+ }
189
+ if ( preg_match( '/^[a-zA-Z0-9-]+$/', $val ) == 0 ) {
190
+ LiteSpeed_Cache_Admin_Display::add_error( LiteSpeed_Cache_Admin_Error::E_PURGEBY_CAT_INV ) ;
191
+ return ;
192
+ }
193
+ $cat = get_category_by_slug( $val ) ;
194
+ if ( $cat == false ) {
195
+ LiteSpeed_Cache_Admin_Display::add_error( LiteSpeed_Cache_Admin_Error::E_PURGEBY_CAT_DNE, $val ) ;
196
+ return ;
197
+ }
198
+
199
+ LiteSpeed_Cache_Admin_Display::add_notice( LiteSpeed_Cache_Admin_Display::NOTICE_GREEN, sprintf( __( 'Purge category %s', 'litespeed-cache' ), $val ) ) ;
200
+
201
+ self::add( LiteSpeed_Cache_Tag::TYPE_ARCHIVE_TERM . $cat->term_id ) ;
202
+ }
203
+
204
+ /**
205
+ * Callback to add purge tags if admin selects to purge selected post IDs.
206
+ *
207
+ * @since 1.0.7
208
+ * @access public
209
+ * @param string $value The post ID.
210
+ * @param string $key Unused.
211
+ */
212
+ public function purgeby_pid_cb( $value, $key )
213
+ {
214
+ $val = trim( $value ) ;
215
+ if ( empty( $val ) ) {
216
+ return ;
217
+ }
218
+ if ( ! is_numeric( $val ) ) {
219
+ LiteSpeed_Cache_Admin_Display::add_error( LiteSpeed_Cache_Admin_Error::E_PURGEBY_PID_NUM, $val ) ;
220
+ return ;
221
+ }
222
+ elseif ( get_post_status( $val ) !== 'publish' ) {
223
+ LiteSpeed_Cache_Admin_Display::add_error( LiteSpeed_Cache_Admin_Error::E_PURGEBY_PID_DNE, $val ) ;
224
+ return ;
225
+ }
226
+ LiteSpeed_Cache_Admin_Display::add_notice( LiteSpeed_Cache_Admin_Display::NOTICE_GREEN, sprintf( __( 'Purge Post ID %s', 'litespeed-cache' ), $val ) ) ;
227
+
228
+ self::add( LiteSpeed_Cache_Tag::TYPE_POST . $val ) ;
229
+ }
230
+
231
+ /**
232
+ * Callback to add purge tags if admin selects to purge selected tag pages.
233
+ *
234
+ * @since 1.0.7
235
+ * @access public
236
+ * @param string $value The tag slug.
237
+ * @param string $key Unused.
238
+ */
239
+ public function purgeby_tag_cb( $value, $key )
240
+ {
241
+ $val = trim( $value ) ;
242
+ if ( empty( $val ) ) {
243
+ return ;
244
+ }
245
+ if ( preg_match( '/^[a-zA-Z0-9-]+$/', $val ) == 0 ) {
246
+ LiteSpeed_Cache_Admin_Display::add_error( LiteSpeed_Cache_Admin_Error::E_PURGEBY_TAG_INV ) ;
247
+ return ;
248
+ }
249
+ $term = get_term_by( 'slug', $val, 'post_tag' ) ;
250
+ if ( $term == 0 ) {
251
+ LiteSpeed_Cache_Admin_Display::add_error( LiteSpeed_Cache_Admin_Error::E_PURGEBY_TAG_DNE, $val ) ;
252
+ return ;
253
+ }
254
+
255
+ LiteSpeed_Cache_Admin_Display::add_notice( LiteSpeed_Cache_Admin_Display::NOTICE_GREEN, sprintf( __( 'Purge tag %s', 'litespeed-cache' ), $val ) ) ;
256
+
257
+ self::add( LiteSpeed_Cache_Tag::TYPE_ARCHIVE_TERM . $term->term_id ) ;
258
+ }
259
+
260
+ /**
261
+ * Callback to add purge tags if admin selects to purge selected urls.
262
+ *
263
+ * @since 1.0.7
264
+ * @access public
265
+ * @param string $value A url to purge.
266
+ * @param string $key Unused.
267
+ */
268
+ public function purgeby_url_cb( $value, $key )
269
+ {
270
+ $val = trim( $value ) ;
271
+ if ( empty( $val ) ) {
272
+ return ;
273
+ }
274
+
275
+ if ( strpos( $val, '<' ) !== false ) {
276
+ LiteSpeed_Cache_Admin_Display::add_error( LiteSpeed_Cache_Admin_Error::E_PURGEBY_URL_BAD ) ;
277
+ return ;
278
+ }
279
+
280
+ $val = LiteSpeed_Cache_Utility::make_relative( $val ) ;
281
+
282
+ $hash = LiteSpeed_Cache_Tag::get_uri_tag( $val ) ;
283
+
284
+ if ( $hash === false ) {
285
+ LiteSpeed_Cache_Admin_Display::add_error( LiteSpeed_Cache_Admin_Error::E_PURGEBY_URL_INV, $val ) ;
286
+ return ;
287
+ }
288
+
289
+ LiteSpeed_Cache_Admin_Display::add_notice( LiteSpeed_Cache_Admin_Display::NOTICE_GREEN, sprintf( __( 'Purge url %s', 'litespeed-cache' ), $val ) ) ;
290
+
291
+ self::add( $hash ) ;
292
+ return ;
293
+ }
294
+
295
+ /**
296
+ * Purge a list of pages when selected by admin. This method will
297
+ * look at the post arguments to determine how and what to purge.
298
+ *
299
+ * @since 1.0.7
300
+ * @access public
301
+ */
302
+ public function purge_list()
303
+ {
304
+ if ( ! isset($_REQUEST[LiteSpeed_Cache_Admin_Display::PURGEBYOPT_SELECT]) || ! isset($_REQUEST[LiteSpeed_Cache_Admin_Display::PURGEBYOPT_LIST]) ) {
305
+ LiteSpeed_Cache_Admin_Display::add_error(LiteSpeed_Cache_Admin_Error::E_PURGE_FORM) ;
306
+ return ;
307
+ }
308
+ $sel = $_REQUEST[LiteSpeed_Cache_Admin_Display::PURGEBYOPT_SELECT] ;
309
+ $list_buf = $_REQUEST[LiteSpeed_Cache_Admin_Display::PURGEBYOPT_LIST] ;
310
+ if ( empty($list_buf) ) {
311
+ LiteSpeed_Cache_Admin_Display::add_error(LiteSpeed_Cache_Admin_Error::E_PURGEBY_EMPTY) ;
312
+ return ;
313
+ }
314
+ $list_buf = str_replace(",", "\n", $list_buf) ;// for cli
315
+ $list = explode("\n", $list_buf) ;
316
+ switch($sel) {
317
+ case LiteSpeed_Cache_Admin_Display::PURGEBY_CAT:
318
+ $cb = 'purgeby_cat_cb' ;
319
+ break ;
320
+ case LiteSpeed_Cache_Admin_Display::PURGEBY_PID:
321
+ $cb = 'purgeby_pid_cb' ;
322
+ break ;
323
+ case LiteSpeed_Cache_Admin_Display::PURGEBY_TAG:
324
+ $cb = 'purgeby_tag_cb' ;
325
+ break ;
326
+ case LiteSpeed_Cache_Admin_Display::PURGEBY_URL:
327
+ $cb = 'purgeby_url_cb' ;
328
+ break ;
329
+ default:
330
+ LiteSpeed_Cache_Admin_Display::add_error(LiteSpeed_Cache_Admin_Error::E_PURGEBY_BAD) ;
331
+ return ;
332
+ }
333
+ array_walk($list, Array($this, $cb)) ;
334
+
335
+ // for redirection
336
+ $_GET[LiteSpeed_Cache_Admin_Display::PURGEBYOPT_SELECT] = $sel ;
337
+ }
338
+
339
+ /**
340
+ * Purge a post on update.
341
+ *
342
+ * This function will get the relevant purge tags to add to the response
343
+ * as well.
344
+ *
345
+ * @since 1.0.0
346
+ * @access public
347
+ * @param integer $id The post id to purge.
348
+ */
349
+ public static function purge_post( $id )
350
+ {
351
+ $post_id = intval($id) ;
352
+ // ignore the status we don't care
353
+ if ( ! in_array(get_post_status($post_id), array( 'publish', 'trash', 'private', 'draft' )) ) {
354
+ return ;
355
+ }
356
+
357
+ $purge_tags = self::get_purge_tags_by_post($post_id) ;
358
+ if ( empty($purge_tags) ) {
359
+ return ;
360
+ }
361
+ if ( in_array( '*', $purge_tags ) ) {
362
+ self::purge_all() ;
363
+ }
364
+ else {
365
+ self::add( $purge_tags ) ;
366
+ if ( LiteSpeed_Cache::config( LiteSpeed_Cache_Config::OPID_CACHE_REST ) ) {
367
+ self::add( LiteSpeed_Cache_Tag::TYPE_REST ) ;
368
+ }
369
+ }
370
+ LiteSpeed_Cache_Control::set_stale() ;
371
+ }
372
+
373
+ /**
374
+ * Hooked to the load-widgets.php action.
375
+ * Attempts to purge a single widget from cache.
376
+ * If no widget id is passed in, the method will attempt to find the widget id.
377
+ *
378
+ * @since 1.1.3
379
+ * @access public
380
+ * @param type $widget_id The id of the widget to purge.
381
+ */
382
+ public static function purge_widget($widget_id = null)
383
+ {
384
+ if ( is_null($widget_id) ) {
385
+ $widget_id = $_POST['widget-id'] ;
386
+ if ( is_null($widget_id) ) {
387
+ return ;
388
+ }
389
+ }
390
+ self::add(LiteSpeed_Cache_Tag::TYPE_WIDGET . $widget_id) ;
391
+ self::add_private(LiteSpeed_Cache_Tag::TYPE_WIDGET . $widget_id) ;
392
+ }
393
+
394
+ /**
395
+ * Hooked to the wp_update_comment_count action.
396
+ * Purges the comment widget when the count is updated.
397
+ *
398
+ * @access public
399
+ * @since 1.1.3
400
+ * @global type $wp_widget_factory
401
+ */
402
+ public static function purge_comment_widget()
403
+ {
404
+ global $wp_widget_factory ;
405
+ $recent_comments = $wp_widget_factory->widgets['WP_Widget_Recent_Comments'] ;
406
+ if ( !is_null($recent_comments) ) {
407
+ self::add(LiteSpeed_Cache_Tag::TYPE_WIDGET . $recent_comments->id) ;
408
+ self::add_private(LiteSpeed_Cache_Tag::TYPE_WIDGET . $recent_comments->id) ;
409
+ }
410
+ }
411
+
412
+ /**
413
+ * Purges feeds on comment count update.
414
+ *
415
+ * @since 1.0.9
416
+ * @access public
417
+ */
418
+ public static function purge_feeds()
419
+ {
420
+ if ( LiteSpeed_Cache::config(LiteSpeed_Cache_Config::OPID_FEED_TTL) > 0 ) {
421
+ self::add(LiteSpeed_Cache_Tag::TYPE_FEED) ;
422
+ }
423
+ }
424
+
425
+ /**
426
+ * Purges all private cache entries when the user logs out.
427
+ *
428
+ * @access public
429
+ * @since 1.1.3
430
+ */
431
+ public static function purge_on_logout()
432
+ {
433
+ self::add_private('*') ;
434
+ }
435
+
436
+ /**
437
+ * Generate all purge tags before output
438
+ *
439
+ * @access private
440
+ * @since 1.1.3
441
+ */
442
+ private static function _finalize()
443
+ {
444
+ // Make sure header output only run once
445
+ if ( ! defined( 'LITESPEED_DID_' . __FUNCTION__ ) ) {
446
+ define( 'LITESPEED_DID_' . __FUNCTION__, true ) ;
447
+ }
448
+ else {
449
+ return ;
450
+ }
451
+
452
+ do_action('litespeed_cache_api_purge') ;
453
+
454
+ // Append unique uri purge tags if Admin QS is `PURGESINGLE`
455
+ if ( self::$_purge_single ) {
456
+ self::$_pub_purge[] = LiteSpeed_Cache_Tag::build_uri_tag() ; // TODO: add private tag too
457
+ }
458
+ // Append related purge tags if Admin QS is `PURGE`
459
+ if ( self::$_purge_related ) {
460
+ // Before this, tags need to be finalized
461
+ $tags_related = LiteSpeed_Cache_Tag::output_tags() ;
462
+ // NOTE: need to remove the empty item `B1_` to avoid purging all
463
+ $tags_related = array_filter($tags_related) ;
464
+ if ( $tags_related ) {
465
+ self::$_pub_purge = array_merge(self::$_pub_purge, $tags_related) ;
466
+ }
467
+ }
468
+
469
+ if ( ! empty(self::$_pub_purge) ) {
470
+ self::$_pub_purge = array_unique(self::$_pub_purge) ;
471
+ }
472
+
473
+ if ( ! empty(self::$_priv_purge) ) {
474
+ self::$_priv_purge = array_unique(self::$_priv_purge) ;
475
+ }
476
+ }
477
+
478
+ /**
479
+ * Gathers all the purge headers.
480
+ *
481
+ * This will collect all site wide purge tags as well as third party plugin defined purge tags.
482
+ *
483
+ * @since 1.1.0
484
+ * @access public
485
+ * @return string the built purge header
486
+ */
487
+ public static function output()
488
+ {
489
+ self::_finalize() ;
490
+
491
+ return self::_build() ;
492
+ }
493
+
494
+ /**
495
+ * Build the current purge headers.
496
+ *
497
+ * @since 1.1.5
498
+ * @access private
499
+ * @return string the built purge header
500
+ */
501
+ private static function _build()
502
+ {
503
+ if ( empty( self::$_pub_purge ) && empty( self::$_priv_purge ) ) {
504
+ return ;
505
+ }
506
+
507
+ $purge_header = '' ;
508
+ $private_prefix = self::X_HEADER . ': private,' ;
509
+
510
+ if ( ! empty( self::$_pub_purge ) ) {
511
+ $public_tags = self::_append_prefix( self::$_pub_purge ) ;
512
+ if ( empty( $public_tags ) ) {
513
+ // If this ends up empty, private will also end up empty
514
+ return ;
515
+ }
516
+ $purge_header = self::X_HEADER . ': public,' ;
517
+ if ( LiteSpeed_Cache_Control::is_stale() ) {
518
+ $purge_header .= 'stale,' ;
519
+ }
520
+ $purge_header .= implode( ',', $public_tags ) ;
521
+ $private_prefix = ';private,' ;
522
+ }
523
+
524
+ // Handle priv purge tags
525
+ if ( ! empty( self::$_priv_purge ) ) {
526
+ $private_tags = self::_append_prefix( self::$_priv_purge, true ) ;
527
+ $purge_header .= $private_prefix . implode( ',', $private_tags ) ;
528
+ }
529
+
530
+ return $purge_header ;
531
+ }
532
+
533
+ /**
534
+ * Append prefix to an array of purge headers
535
+ *
536
+ * @since 1.1.0
537
+ * @access private
538
+ * @param array $purge_tags The purge tags to apply the prefix to.
539
+ * @param boolean $is_private If is private tags or not.
540
+ * @return array The array of built purge tags.
541
+ */
542
+ private static function _append_prefix( $purge_tags, $is_private = false )
543
+ {
544
+ $curr_bid = get_current_blog_id() ;
545
+
546
+ if ( ! in_array('*', $purge_tags) ) {
547
+ $tags = array() ;
548
+ foreach ($purge_tags as $val) {
549
+ $tags[] = LSWCP_TAG_PREFIX . $curr_bid . '_' . $val ;
550
+ }
551
+ return $tags ;
552
+ }
553
+
554
+ if ( defined('LSWCP_EMPTYCACHE') || $is_private ) {
555
+ return array('*') ;
556
+ }
557
+
558
+ // Would only use multisite and network admin except is_network_admin
559
+ // is false for ajax calls, which is used by wordpress updates v4.6+
560
+ if ( is_multisite() && (is_network_admin() || (
561
+ LiteSpeed_Cache_Router::is_ajax() && (check_ajax_referer('updates', false, false) || check_ajax_referer('litespeed-purgeall-network', false, false))
562
+ )) ) {
563
+ $blogs = LiteSpeed_Cache_Activation::get_network_ids() ;
564
+ if ( empty($blogs) ) {
565
+ LiteSpeed_Cache_Log::debug('build_purge_headers: blog list is empty') ;
566
+ return '' ;
567
+ }
568
+ $tags = array() ;
569
+ foreach ($blogs as $blog_id) {
570
+ $tags[] = LSWCP_TAG_PREFIX . $blog_id . '_' ;
571
+ }
572
+ return $tags ;
573
+ }
574
+ else {
575
+ return array(LSWCP_TAG_PREFIX . $curr_bid . '_') ;
576
+ }
577
+ }
578
+
579
+ /**
580
+ * Gets all the purge tags correlated with the post about to be purged.
581
+ *
582
+ * If the purge all pages configuration is set, all pages will be purged.
583
+ *
584
+ * This includes site wide post types (e.g. front page) as well as
585
+ * any third party plugin specific post tags.
586
+ *
587
+ * @since 1.0.0
588
+ * @access public
589
+ * @param integer $post_id The id of the post about to be purged.
590
+ * @return array The list of purge tags correlated with the post.
591
+ */
592
+ public static function get_purge_tags_by_post( $post_id )
593
+ {
594
+ // If this is a valid post we want to purge the post, the home page and any associated tags & cats
595
+ // If not, purge everything on the site.
596
+
597
+ $purge_tags = array() ;
598
+ $config = LiteSpeed_Cache_Config::get_instance() ;
599
+
600
+ if ( $config->purge_by_post(LiteSpeed_Cache_Config::PURGE_ALL_PAGES) ) {
601
+ // ignore the rest if purge all
602
+ return array( '*' ) ;
603
+ }
604
+
605
+ // now do API hook action for post purge
606
+ do_action('litespeed_cache_api_purge_post', $post_id) ;
607
+
608
+ // post
609
+ $purge_tags[] = LiteSpeed_Cache_Tag::TYPE_POST . $post_id ;
610
+ $purge_tags[] = LiteSpeed_Cache_Tag::get_uri_tag(wp_make_link_relative(get_permalink($post_id))) ;
611
+
612
+ // for archive of categories|tags|custom tax
613
+ global $post ;
614
+ $post = get_post($post_id) ;
615
+ $post_type = $post->post_type ;
616
+
617
+ global $wp_widget_factory ;
618
+ $recent_posts = $wp_widget_factory->widgets['WP_Widget_Recent_Posts'] ;
619
+ if ( ! is_null($recent_posts) ) {
620
+ $purge_tags[] = LiteSpeed_Cache_Tag::TYPE_WIDGET . $recent_posts->id ;
621
+ }
622
+
623
+ // get adjacent posts id as related post tag
624
+ if( $post_type == 'post' ){
625
+ $prev_post = get_previous_post() ;
626
+ $next_post = get_next_post() ;
627
+ if( ! empty($prev_post->ID) ) {
628
+ $purge_tags[] = LiteSpeed_Cache_Tag::TYPE_POST . $prev_post->ID ;
629
+ LiteSpeed_Cache_Log::debug('--------purge_tags prev is: '.$prev_post->ID) ;
630
+ }
631
+ if( ! empty($next_post->ID) ) {
632
+ $purge_tags[] = LiteSpeed_Cache_Tag::TYPE_POST . $next_post->ID ;
633
+ LiteSpeed_Cache_Log::debug('--------purge_tags next is: '.$next_post->ID) ;
634
+ }
635
+ }
636
+
637
+ if ( $config->purge_by_post(LiteSpeed_Cache_Config::PURGE_TERM) ) {
638
+ $taxonomies = get_object_taxonomies($post_type) ;
639
+ //LiteSpeed_Cache_Log::push('purge by post, check tax = ' . print_r($taxonomies, true)) ;
640
+ foreach ( $taxonomies as $tax ) {
641
+ $terms = get_the_terms($post_id, $tax) ;
642
+ if ( ! empty($terms) ) {
643
+ foreach ( $terms as $term ) {
644
+ $purge_tags[] = LiteSpeed_Cache_Tag::TYPE_ARCHIVE_TERM . $term->term_id ;
645
+ }
646
+ }
647
+ }
648
+ }
649
+
650
+ if ( $config->get_option(LiteSpeed_Cache_Config::OPID_FEED_TTL) > 0 ) {
651
+ $purge_tags[] = LiteSpeed_Cache_Tag::TYPE_FEED ;
652
+ }
653
+
654
+ // author, for author posts and feed list
655
+ if ( $config->purge_by_post(LiteSpeed_Cache_Config::PURGE_AUTHOR) ) {
656
+ $purge_tags[] = LiteSpeed_Cache_Tag::TYPE_AUTHOR . get_post_field('post_author', $post_id) ;
657
+ }
658
+
659
+ // archive and feed of post type
660
+ // todo: check if type contains space
661
+ if ( $config->purge_by_post(LiteSpeed_Cache_Config::PURGE_POST_TYPE) ) {
662
+ if ( get_post_type_archive_link($post_type) ) {
663
+ $purge_tags[] = LiteSpeed_Cache_Tag::TYPE_ARCHIVE_POSTTYPE . $post_type ;
664
+ }
665
+ }
666
+
667
+ if ( $config->purge_by_post(LiteSpeed_Cache_Config::PURGE_FRONT_PAGE) ) {
668
+ $purge_tags[] = LiteSpeed_Cache_Tag::TYPE_FRONTPAGE ;
669
+ }
670
+
671
+ if ( $config->purge_by_post(LiteSpeed_Cache_Config::PURGE_HOME_PAGE) ) {
672
+ $purge_tags[] = LiteSpeed_Cache_Tag::TYPE_HOME ;
673
+ }
674
+
675
+ if ( $config->purge_by_post(LiteSpeed_Cache_Config::PURGE_PAGES) ) {
676
+ $purge_tags[] = LiteSpeed_Cache_Tag::TYPE_PAGES ;
677
+ }
678
+
679
+ if ( $config->purge_by_post(LiteSpeed_Cache_Config::PURGE_PAGES_WITH_RECENT_POSTS) ) {
680
+ $purge_tags[] = LiteSpeed_Cache_Tag::TYPE_PAGES_WITH_RECENT_POSTS ;
681
+ }
682
+
683
+ // if configured to have archived by date
684
+ $date = $post->post_date ;
685
+ $date = strtotime($date) ;
686
+
687
+ if ( $config->purge_by_post(LiteSpeed_Cache_Config::PURGE_DATE) ) {
688
+ $purge_tags[] = LiteSpeed_Cache_Tag::TYPE_ARCHIVE_DATE . date('Ymd', $date) ;
689
+ }
690
+
691
+ if ( $config->purge_by_post(LiteSpeed_Cache_Config::PURGE_MONTH) ) {
692
+ $purge_tags[] = LiteSpeed_Cache_Tag::TYPE_ARCHIVE_DATE . date('Ym', $date) ;
693
+ }
694
+
695
+ if ( $config->purge_by_post(LiteSpeed_Cache_Config::PURGE_YEAR) ) {
696
+ $purge_tags[] = LiteSpeed_Cache_Tag::TYPE_ARCHIVE_DATE . date('Y', $date) ;
697
+ }
698
+
699
+ return array_unique($purge_tags) ;
700
+ }
701
+
702
+ /**
703
+ * The dummy filter for purge all
704
+ *
705
+ * @since 1.1.5
706
+ * @access public
707
+ * @param string $val The filter value
708
+ * @return string The filter value
709
+ */
710
+ public static function filter_with_purge_all( $val )
711
+ {
712
+ self::purge_all() ;
713
+ return $val ;
714
+ }
715
+
716
+ /**
717
+ * Get the current instance object.
718
+ *
719
+ * @since 1.1.3
720
+ * @access public
721
+ * @return Current class instance.
722
+ */
723
+ public static function get_instance()
724
+ {
725
+ $cls = get_called_class() ;
726
+ if ( ! isset(self::$_instance) ) {
727
+ self::$_instance = new $cls() ;
728
+ }
729
+
730
+ return self::$_instance ;
731
+ }
732
+ }
includes/litespeed-cache-router.class.php ADDED
@@ -0,0 +1,414 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * The core plugin router class.
5
+ *
6
+ * This generate the valid action.
7
+ *
8
+ * @since 1.1.0
9
+ * @package LiteSpeed_Cache
10
+ * @subpackage LiteSpeed_Cache/includes
11
+ * @author LiteSpeed Technologies <info@litespeedtech.com>
12
+ */
13
+ class LiteSpeed_Cache_Router
14
+ {
15
+ private static $_instance ;
16
+ private static $_is_enabled ;
17
+ private static $_is_ajax ;
18
+ private static $_is_logged_in ;
19
+ private static $_is_cli ;
20
+ private static $_can_crawl ;
21
+ private static $_ip ;
22
+ private static $_action ;
23
+ private static $_is_admin_ip ;
24
+ private static $_siteurl ;
25
+ private static $_has_whm_msg ;
26
+ private static $_has_msg_ruleconflict ;
27
+
28
+ /**
29
+ * Check if crawler is enabled on server level
30
+ *
31
+ * @since 1.1.1
32
+ * @access public
33
+ * @return string
34
+ */
35
+ public static function get_siteurl()
36
+ {
37
+ if ( ! isset( self::$_siteurl ) ) {
38
+ if ( is_multisite() ) {
39
+ $blogID = get_current_blog_id() ;
40
+ self::$_siteurl = get_site_url( $blogID ) ;
41
+ }
42
+ else{
43
+ self::$_siteurl = get_option( 'siteurl' ) ;
44
+ }
45
+ }
46
+ return self::$_siteurl ;
47
+ }
48
+
49
+ /**
50
+ * Check if cache is enabled or not
51
+ *
52
+ * @since 1.1.5
53
+ * @access public
54
+ * @return boolean
55
+ */
56
+ public static function cache_enabled()
57
+ {
58
+ if ( ! isset( self::$_is_enabled ) ) {
59
+ if ( ! LiteSpeed_Cache_Config::get_instance()->is_caching_allowed() ) {
60
+ self::$_is_enabled = false ;
61
+ }
62
+ elseif ( is_multisite() && is_network_admin() && current_user_can( 'manage_network_options' ) ) {
63
+ self::$_is_enabled = LiteSpeed_Cache::config( LiteSpeed_Cache_Config::NETWORK_OPID_ENABLED ) ;
64
+ }
65
+ else {
66
+ self::$_is_enabled = LiteSpeed_Cache::config( LiteSpeed_Cache_Config::OPID_ENABLED ) ;
67
+ }
68
+ }
69
+ return self::$_is_enabled ;
70
+ }
71
+
72
+ /**
73
+ * Check if has rule conflict notice
74
+ *
75
+ * @since 1.1.5
76
+ * @access public
77
+ * @return boolean
78
+ */
79
+ public static function has_msg_ruleconflict()
80
+ {
81
+ if ( ! isset( self::$_has_msg_ruleconflict ) ) {
82
+ self::$_has_msg_ruleconflict = get_option( LiteSpeed_Cache_Admin_Display::DISMISS_MSG ) == LiteSpeed_Cache_Admin_Display::RULECONFLICT_ON ;
83
+ }
84
+ return self::$_has_msg_ruleconflict ;
85
+ }
86
+
87
+ /**
88
+ * Check if has whm notice
89
+ *
90
+ * @since 1.1.1
91
+ * @access public
92
+ * @return boolean
93
+ */
94
+ public static function has_whm_msg()
95
+ {
96
+ if ( ! isset( self::$_has_whm_msg ) ) {
97
+ self::$_has_whm_msg = get_transient( LiteSpeed_Cache::WHM_TRANSIENT ) == LiteSpeed_Cache::WHM_TRANSIENT_VAL ;
98
+ }
99
+ return self::$_has_whm_msg ;
100
+ }
101
+
102
+ /**
103
+ * Check if crawler is enabled on server level
104
+ *
105
+ * @since 1.1.1
106
+ * @access public
107
+ * @return boolean
108
+ */
109
+ public static function can_crawl()
110
+ {
111
+ if ( ! isset( self::$_can_crawl ) ) {
112
+ self::$_can_crawl = false ;
113
+ if ( isset( $_SERVER['X-LSCACHE'] ) && strpos( $_SERVER['X-LSCACHE'], 'crawler' ) !== false ) {
114
+ self::$_can_crawl = true ;
115
+ }
116
+ // CLI will bypass this check as crawler library can always do the 428 check
117
+ if ( PHP_SAPI == 'cli' ) {
118
+ self::$_can_crawl = true ;
119
+ }
120
+ }
121
+ return self::$_can_crawl ;
122
+ }
123
+
124
+ /**
125
+ * Check action
126
+ *
127
+ * @since 1.1.0
128
+ * @access public
129
+ * @return string
130
+ */
131
+ public static function get_action()
132
+ {
133
+ if ( ! isset( self::$_action ) ) {
134
+ self::$_action = false;
135
+ self::get_instance()->verify_action() ;
136
+ if ( self::$_action && LiteSpeed_Cache_Log::get_enabled() ) {
137
+ LiteSpeed_Cache_Log::push( 'LSCWP_CTRL verified: ' . var_export( self::$_action, true ) ) ;
138
+ }
139
+
140
+ }
141
+ return self::$_action ;
142
+ }
143
+
144
+ /**
145
+ * Check if is logged in
146
+ *
147
+ * @since 1.1.3
148
+ * @access public
149
+ * @return boolean
150
+ */
151
+ public static function is_logged_in()
152
+ {
153
+ if ( ! isset( self::$_is_logged_in ) ) {
154
+ self::$_is_logged_in = is_user_logged_in() ;
155
+ }
156
+ return self::$_is_logged_in ;
157
+ }
158
+
159
+ /**
160
+ * Check if is cli usage
161
+ *
162
+ * @since 1.1.0
163
+ * @access public
164
+ * @return boolean
165
+ */
166
+ public static function is_cli()
167
+ {
168
+ if ( ! isset( self::$_is_cli ) ) {
169
+ self::$_is_cli = defined( 'WP_CLI' ) && WP_CLI ;
170
+ }
171
+ return self::$_is_cli ;
172
+ }
173
+
174
+ /**
175
+ * Check if is ajax call
176
+ *
177
+ * @since 1.1.0
178
+ * @access public
179
+ * @return boolean
180
+ */
181
+ public static function is_ajax()
182
+ {
183
+ if ( ! isset( self::$_is_ajax ) ) {
184
+ self::$_is_ajax = defined( 'DOING_AJAX' ) && DOING_AJAX ;
185
+ }
186
+ return self::$_is_ajax ;
187
+ }
188
+
189
+ /**
190
+ * Check if is admin ip
191
+ *
192
+ * @since 1.1.0
193
+ * @access public
194
+ * @return boolean
195
+ */
196
+ public static function is_admin_ip()
197
+ {
198
+ if ( ! isset( self::$_is_admin_ip ) ) {
199
+ $ips = LiteSpeed_Cache::config( LiteSpeed_Cache_Config::OPID_ADMIN_IPS ) ;
200
+
201
+ self::$_is_admin_ip = self::get_instance()->ip_access( $ips ) ;
202
+ }
203
+ return self::$_is_admin_ip ;
204
+ }
205
+
206
+ /**
207
+ * Check privilege and nonce for the action
208
+ *
209
+ * @since 1.1.0
210
+ * @access private
211
+ */
212
+ private function verify_action()
213
+ {
214
+ if( empty( $_REQUEST[LiteSpeed_Cache::ACTION_KEY] ) ) {
215
+ return ;
216
+ }
217
+
218
+ $action = $_REQUEST[LiteSpeed_Cache::ACTION_KEY] ;
219
+ $_is_public_action = false ;
220
+
221
+ // Each action must have a valid nonce unless its from admin ip and is public action
222
+ // Validate requests nonce (from admin logged in page or cli)
223
+ if ( ! $this->verify_nonce( $action ) ) {
224
+ // check if it is from admin ip
225
+ if ( ! $this->is_admin_ip() ) {
226
+ LiteSpeed_Cache_Log::debug( 'LSCWP_CTRL query string - did not match admin IP: ' . $action ) ;
227
+ return ;
228
+ }
229
+
230
+ // check if it is public action
231
+ if ( ! in_array( $action, array(
232
+ LiteSpeed_Cache::ACTION_QS_NOCACHE,
233
+ LiteSpeed_Cache::ACTION_QS_PURGE,
234
+ LiteSpeed_Cache::ACTION_QS_PURGE_SINGLE,
235
+ LiteSpeed_Cache::ACTION_QS_SHOW_HEADERS,
236
+ LiteSpeed_Cache::ACTION_QS_PURGE_ALL,
237
+ LiteSpeed_Cache::ACTION_QS_PURGE_EMPTYCACHE,
238
+ ) ) ) {
239
+ LiteSpeed_Cache_Log::debug( 'LSCWP_CTRL query string - did not match admin IP Actions: ' . $action ) ;
240
+ return ;
241
+ }
242
+
243
+ $_is_public_action = true ;
244
+ }
245
+
246
+ /* Now it is a valid action, lets log and check the permission */
247
+ LiteSpeed_Cache_Log::debug( 'LSCWP_CTRL: ' . $action ) ;
248
+
249
+ // OK, as we want to do something magic, lets check if its allowed
250
+ $_is_enabled = self::cache_enabled() ;
251
+ $_is_multisite = is_multisite() ;
252
+ $_is_network_admin = $_is_multisite && is_network_admin() ;
253
+ $_can_network_option = $_is_network_admin && current_user_can( 'manage_network_options' ) ;
254
+ $_can_option = current_user_can( 'manage_options' ) ;
255
+
256
+ switch ( $action ) {
257
+ // Save htaccess
258
+ case LiteSpeed_Cache::ACTION_SAVE_HTACCESS:
259
+ if ( ( ! $_is_multisite && $_can_option ) || $_can_network_option ) {
260
+ self::$_action = $action ;
261
+ }
262
+ return ;
263
+
264
+ // Save network settings
265
+ case LiteSpeed_Cache::ACTION_SAVE_SETTINGS_NETWORK:
266
+ if ( $_can_network_option ) {
267
+ self::$_action = $action ;
268
+ }
269
+ return ;
270
+
271
+ case LiteSpeed_Cache::ACTION_PURGE_FRONT:
272
+ case LiteSpeed_Cache::ACTION_PURGE_PAGES:
273
+ case LiteSpeed_Cache::ACTION_PURGE_ERRORS:
274
+ case LiteSpeed_Cache::ACTION_PURGE_ALL:
275
+ case LiteSpeed_Cache::ACTION_PURGE_BY:
276
+ if ( $_is_enabled
277
+ && ( $_can_network_option || $_can_option || self::is_ajax() ) ) {//here may need more security
278
+ self::$_action = $action ;
279
+ }
280
+ return ;
281
+
282
+ case LiteSpeed_Cache::ACTION_PURGE_EMPTYCACHE:
283
+ if ( $_is_enabled
284
+ && ( $_can_network_option
285
+ || ( ! $_is_multisite && $_can_option ) ) ) {
286
+ self::$_action = $action ;
287
+ }
288
+ return ;
289
+
290
+ case LiteSpeed_Cache::ACTION_QS_NOCACHE:
291
+ case LiteSpeed_Cache::ACTION_QS_PURGE:
292
+ case LiteSpeed_Cache::ACTION_QS_PURGE_SINGLE:
293
+ case LiteSpeed_Cache::ACTION_QS_SHOW_HEADERS:
294
+ case LiteSpeed_Cache::ACTION_QS_PURGE_ALL:
295
+ case LiteSpeed_Cache::ACTION_QS_PURGE_EMPTYCACHE:
296
+ if ( $_is_enabled && ( $_is_public_action || self::is_ajax() ) ) {
297
+ self::$_action = $action ;
298
+ }
299
+ return ;
300
+
301
+ case LiteSpeed_Cache::ACTION_CRAWLER_GENERATE_FILE:
302
+ case LiteSpeed_Cache::ACTION_CRAWLER_RESET_POS:
303
+ case LiteSpeed_Cache::ACTION_CRAWLER_CRON_ENABLE:
304
+ case LiteSpeed_Cache::ACTION_DO_CRAWL:
305
+ case LiteSpeed_Cache::ACTION_BLACKLIST_SAVE:
306
+ if ( $_is_enabled && $_can_option && ! $_is_network_admin ) {
307
+ self::$_action = $action ;
308
+ }
309
+ return ;
310
+
311
+ case LiteSpeed_Cache::ACTION_DISMISS_WHM:
312
+ case LiteSpeed_Cache::ACTION_DISMISS_EXPIRESDEFAULT:
313
+ if ( self::is_ajax() ) {
314
+ self::$_action = $action ;
315
+ }
316
+ return ;
317
+
318
+ default:
319
+ LiteSpeed_Cache_Log::debug( 'LSCWP_CTRL match falied: ' . $action ) ;
320
+ return ;
321
+ }
322
+
323
+ }
324
+
325
+ /**
326
+ * Verify nonce
327
+ *
328
+ * @since 1.1.0
329
+ * @access private
330
+ * @param string $action
331
+ * @return bool
332
+ */
333
+ private function verify_nonce( $action )
334
+ {
335
+ if ( ! isset( $_REQUEST[LiteSpeed_Cache::NONCE_NAME] ) || ! wp_verify_nonce( $_REQUEST[LiteSpeed_Cache::NONCE_NAME], $action ) ) {
336
+ return false ;
337
+ }
338
+ else{
339
+ return true ;
340
+ }
341
+ }
342
+
343
+ /**
344
+ * Check if the ip is in the range
345
+ *
346
+ * @since 1.1.0
347
+ * @access private
348
+ * @param string $ip_list IP list
349
+ * @return bool
350
+ */
351
+ private function ip_access( $ip_list )
352
+ {
353
+ if ( ! $ip_list ) {
354
+ return false ;
355
+ }
356
+ if ( ! isset( self::$_ip ) ) {
357
+ self::$_ip = $this->get_ip() ;
358
+ }
359
+ // $uip = explode('.', $_ip) ;
360
+ // if(empty($uip) || count($uip) != 4) Return false ;
361
+ if ( ! is_array( $ip_list ) ) {
362
+ $ip_list = explode( "\n", $ip_list ) ;
363
+ }
364
+ // foreach($ip_list as $key => $ip) $ip_list[$key] = explode('.', trim($ip)) ;
365
+ // foreach($ip_list as $key => $ip) {
366
+ // if(count($ip) != 4) continue ;
367
+ // for($i = 0 ; $i <= 3 ; $i++) if($ip[$i] == '*') $ip_list[$key][$i] = $uip[$i] ;
368
+ // }
369
+ return in_array( self::$_ip, $ip_list ) ;
370
+ }
371
+
372
+ /**
373
+ * Get client ip
374
+ *
375
+ * @since 1.1.0
376
+ * @access private
377
+ * @return string
378
+ */
379
+ private function get_ip()
380
+ {
381
+ $_ip = '' ;
382
+ if ( function_exists( 'apache_request_headers' ) ) {
383
+ $apache_headers = apache_request_headers() ;
384
+ $_ip = ! empty( $apache_headers['True-Client-IP'] ) ? $apache_headers['True-Client-IP'] : false ;
385
+ if ( ! $_ip ) {
386
+ $_ip = ! empty( $apache_headers['X-Forwarded-For'] ) ? $apache_headers['X-Forwarded-For'] : false ;
387
+ $_ip = explode( ", ", $_ip ) ;
388
+ $_ip = array_shift( $_ip ) ;
389
+ }
390
+
391
+ if ( ! $_ip ) {
392
+ $_ip = ! empty( $_SERVER['REMOTE_ADDR'] ) ? $_SERVER['REMOTE_ADDR'] : false ;
393
+ }
394
+ }
395
+ return $_ip ;
396
+ }
397
+
398
+ /**
399
+ * Get the current instance object.
400
+ *
401
+ * @since 1.1.0
402
+ * @access public
403
+ * @return Current class instance.
404
+ */
405
+ public static function get_instance()
406
+ {
407
+ $cls = get_called_class() ;
408
+ if ( ! isset( self::$_instance ) ) {
409
+ self::$_instance = new $cls() ;
410
+ }
411
+
412
+ return self::$_instance ;
413
+ }
414
+ }
includes/litespeed-cache-tag.class.php ADDED
@@ -0,0 +1,367 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The plugin cache-tag class for X-LiteSpeed-Tag
4
+ *
5
+ * @since 1.1.3
6
+ * @package LiteSpeed_Cache
7
+ * @subpackage LiteSpeed_Cache/includes
8
+ * @author LiteSpeed Technologies <info@litespeedtech.com>
9
+ */
10
+ class LiteSpeed_Cache_Tag
11
+ {
12
+ // private static $_instance ;
13
+
14
+ const TYPE_FEED = 'FD' ;
15
+ const TYPE_FRONTPAGE = 'F' ;
16
+ const TYPE_HOME = 'H' ;
17
+ const TYPE_PAGES = 'PGS' ;
18
+ const TYPE_PAGES_WITH_RECENT_POSTS = 'PGSRP' ;
19
+ const TYPE_ERROR = 'ERR.' ;
20
+ const TYPE_POST = 'Po.' ; // Post. Cannot use P, reserved for litemage.
21
+ const TYPE_ARCHIVE_POSTTYPE = 'PT.' ;
22
+ const TYPE_ARCHIVE_TERM = 'T.' ; //for is_category|is_tag|is_tax
23
+ const TYPE_AUTHOR = 'A.' ;
24
+ const TYPE_ARCHIVE_DATE = 'D.' ;
25
+ const TYPE_BLOG = 'B.' ;
26
+ const TYPE_LOGIN = 'L' ;
27
+ const TYPE_URL = 'URL.' ;
28
+ const TYPE_WIDGET = 'W.' ;
29
+ const TYPE_ESI = 'ESI.' ;
30
+ const TYPE_REST = 'REST' ;
31
+ const TYPE_LIST = 'LIST' ;
32
+
33
+ const X_HEADER = 'X-LiteSpeed-Tag' ;
34
+
35
+ private static $_tags = array() ;
36
+ private static $_tags_priv = array( 'tag_priv' ) ;
37
+ protected static $_error_status = false ;
38
+
39
+ /**
40
+ * Check if the login page is cacheable.
41
+ * If not, unset the cacheable member variable.
42
+ *
43
+ * NOTE: This is checked separately because login page doesn't go through WP logic.
44
+ *
45
+ * @since 1.0.0
46
+ * @access public
47
+ */
48
+ public static function check_login_cacheable()
49
+ {
50
+ if ( ! LiteSpeed_Cache::config( LiteSpeed_Cache_Config::OPID_CACHE_PAGE_LOGIN ) ) {
51
+ return ;
52
+ }
53
+ if ( LiteSpeed_Cache_Control::isset_notcacheable() ) {
54
+ return ;
55
+ }
56
+
57
+ if ( ! empty( $_GET ) ) {
58
+ LiteSpeed_Cache_Control::set_nocache( 'has GET request' ) ;
59
+ return ;
60
+ }
61
+
62
+ LiteSpeed_Cache_Control::set_cacheable() ;
63
+
64
+ self::add( self::TYPE_LOGIN ) ;
65
+
66
+ // we need to send lsc-cookie manually to make it be sent to all other users when is cacheable
67
+ $list = headers_list() ;
68
+ if ( empty( $list ) ) {
69
+ return ;
70
+ }
71
+ foreach ( $list as $hdr ) {
72
+ if ( strncasecmp( $hdr, 'set-cookie:', 11 ) == 0 ) {
73
+ $cookie = substr( $hdr, 12 ) ;
74
+ @header( 'lsc-cookie: ' . $cookie, false ) ;
75
+ }
76
+ }
77
+ }
78
+
79
+ /**
80
+ * Check if the page returns 403 and 500 errors.
81
+ *
82
+ * @since 1.0.13.1
83
+ * @access public
84
+ * @param $header
85
+ * @param $code
86
+ * @return $eror_status
87
+ */
88
+ public static function check_error_codes( $header, $code )
89
+ {
90
+ $ttl_403 = LiteSpeed_Cache::config( LiteSpeed_Cache_Config::OPID_403_TTL ) ;
91
+ $ttl_500 = LiteSpeed_Cache::config( LiteSpeed_Cache_Config::OPID_500_TTL ) ;
92
+ if ( $code == 403 ) {
93
+ if ( $ttl_403 <= 30 && LiteSpeed_Cache_Control::is_cacheable() ) {
94
+ LiteSpeed_Cache_Control::set_nocache( '403 TTL is less than 30s' ) ;
95
+ }
96
+ else {
97
+ self::$_error_status = $code ;
98
+ }
99
+ }
100
+ elseif ( $code >= 500 && $code < 600 ) {
101
+ if ( $ttl_500 <= 30 && LiteSpeed_Cache_Control::is_cacheable() ) {
102
+ LiteSpeed_Cache_Control::set_nocache( 'TTL is less than 30s' ) ;
103
+ }
104
+ }
105
+ elseif ( $code > 400 ) {
106
+ self::$_error_status = $code ;
107
+ }
108
+ return self::$_error_status ;
109
+ }
110
+
111
+ /**
112
+ * Get error code.
113
+ *
114
+ * @since 1.1.3
115
+ * @access public
116
+ */
117
+ public static function get_error_code()
118
+ {
119
+ return self::$_error_status ;
120
+ }
121
+
122
+ /**
123
+ * Register purge tag for pages with recent posts widget
124
+ * of the plugin.
125
+ *
126
+ * @since 1.0.15
127
+ * @access public
128
+ * @param array $params [wordpress params for widget_posts_args]
129
+ */
130
+ public static function add_widget_recent_posts( $params )
131
+ {
132
+ self::add( self::TYPE_PAGES_WITH_RECENT_POSTS ) ;
133
+ return $params ;
134
+ }
135
+
136
+ /**
137
+ * Adds cache tags to the list of cache tags for the current page.
138
+ *
139
+ * @since 1.0.5
140
+ * @access public
141
+ * @param mixed $tags A string or array of cache tags to add to the current list.
142
+ */
143
+ public static function add( $tags )
144
+ {
145
+ if ( ! is_array( $tags ) ) {
146
+ $tags = array( $tags ) ;
147
+ }
148
+
149
+ self::$_tags = array_merge( self::$_tags, $tags ) ;
150
+ }
151
+
152
+ /**
153
+ * Return tags for Admin QS
154
+ *
155
+ * @since 1.1.3
156
+ * @access public
157
+ */
158
+ public static function output_tags()
159
+ {
160
+ return self::$_tags ;
161
+ }
162
+
163
+ /**
164
+ * Will get a hash of the URI. Removes query string and appends a '/' if it is missing.
165
+ *
166
+ * @since 1.0.12
167
+ * @access public
168
+ * @param string $uri The uri to get the hash of.
169
+ * @param boolean $ori Return the original url or not
170
+ * @return bool|string False on input error, hash otherwise.
171
+ */
172
+ public static function get_uri_tag( $uri, $ori = false )
173
+ {
174
+ $no_qs = strtok( $uri, '?' ) ;
175
+ if ( empty( $no_qs ) ) {
176
+ return false ;
177
+ }
178
+ $slashed = trailingslashit( $no_qs ) ;
179
+
180
+ // If only needs uri tag
181
+ if ( $ori ) {
182
+ return $slashed ;
183
+ }
184
+ // return self::TYPE_URL . ( $slashed ) ;
185
+ return self::TYPE_URL . md5( $slashed ) ;
186
+ }
187
+
188
+ /**
189
+ * Get the unique tag based on self url.
190
+ *
191
+ * @since 1.1.3
192
+ * @access public
193
+ * @param boolean $ori Return the original url or not
194
+ */
195
+ public static function build_uri_tag( $ori = false )
196
+ {
197
+ return self::get_uri_tag( urldecode( $_SERVER['REQUEST_URI'] ), $ori ) ;
198
+ }
199
+
200
+ /**
201
+ * Gets the cache tags to set for the page.
202
+ *
203
+ * This includes site wide post types (e.g. front page) as well as
204
+ * any third party plugin specific cache tags.
205
+ *
206
+ * @since 1.0.0
207
+ * @access private
208
+ * @return array The list of cache tags to set.
209
+ */
210
+ private static function _build_type_tags()
211
+ {
212
+ $tags = array() ;
213
+
214
+ $tags[] = self::build_uri_tag() ;
215
+
216
+ if ( is_front_page() ) {
217
+ $tags[] = self::TYPE_FRONTPAGE ;
218
+ }
219
+ elseif ( is_home() ) {
220
+ $tags[] = self::TYPE_HOME ;
221
+ }
222
+
223
+ $err = self::get_error_code() ;
224
+ if ( $err !== false ) {
225
+ $tags[] = self::TYPE_ERROR . $err ;
226
+ }
227
+
228
+ $queried_obj_id = get_queried_object_id() ;
229
+ if ( is_archive() ) {
230
+ //An Archive is a Category, Tag, Author, Date, Custom Post Type or Custom Taxonomy based pages.
231
+ if ( is_category() || is_tag() || is_tax() ) {
232
+ $tags[] = self::TYPE_ARCHIVE_TERM . $queried_obj_id ;
233
+ }
234
+ elseif ( is_post_type_archive() ) {
235
+ global $wp_query ;
236
+ $post_type = $wp_query->get( 'post_type' ) ;
237
+ $tags[] = self::TYPE_ARCHIVE_POSTTYPE . $post_type ;
238
+ }
239
+ elseif ( is_author() ) {
240
+ $tags[] = self::TYPE_AUTHOR . $queried_obj_id ;
241
+ }
242
+ elseif ( is_date() ) {
243
+ global $post ;
244
+ $date = $post->post_date ;
245
+ $date = strtotime( $date ) ;
246
+ if ( is_day() ) {
247
+ $tags[] = self::TYPE_ARCHIVE_DATE . date( 'Ymd', $date ) ;
248
+ }
249
+ elseif ( is_month() ) {
250
+ $tags[] = self::TYPE_ARCHIVE_DATE . date( 'Ym', $date ) ;
251
+ }
252
+ elseif ( is_year() ) {
253
+ $tags[] = self::TYPE_ARCHIVE_DATE . date( 'Y', $date ) ;
254
+ }
255
+ }
256
+ }
257
+ elseif ( is_singular() ) {
258
+ //$this->is_singular = $this->is_single || $this->is_page || $this->is_attachment;
259
+ $tags[] = self::TYPE_POST . $queried_obj_id ;
260
+
261
+ if ( is_page() ) {
262
+ $tags[] = self::TYPE_PAGES ;
263
+ }
264
+ }
265
+ elseif ( is_feed() ) {
266
+ $tags[] = self::TYPE_FEED ;
267
+ }
268
+
269
+ // Check REST API
270
+ if ( defined( 'REST_REQUEST' ) ) {
271
+ $tags[] = self::TYPE_REST ;
272
+
273
+ $path = ! empty( $_SERVER[ 'SCRIPT_URL' ] ) ? $_SERVER[ 'SCRIPT_URL' ] : false ;
274
+ if ( $path ) {
275
+ // posts collections tag
276
+ if ( substr( $path, -6 ) == '/posts' ) {
277
+ $tags[] = self::TYPE_LIST ;// Not used for purge yet
278
+ }
279
+
280
+ // single post tag
281
+ global $post;
282
+ if ( ! empty( $post->ID ) && substr( $path, - strlen( $post->ID ) - 1 ) === '/' . $post->ID ) {
283
+ $tags[] = self::TYPE_POST . $post->ID ;
284
+ }
285
+
286
+ // pages collections & single page tag
287
+ if ( stripos( $path, '/pages' ) !== false ) {
288
+ $tags[] = self::TYPE_PAGES ;
289
+ }
290
+ }
291
+
292
+ }
293
+
294
+ return $tags ;
295
+ }
296
+
297
+ /**
298
+ * Generate all cache tags before output
299
+ *
300
+ * @access private
301
+ * @since 1.1.3
302
+ */
303
+ private static function _finalize()
304
+ {
305
+ // run 3rdparty hooks to tag
306
+ do_action( 'litespeed_cache_api_tag' ) ;
307
+ // generate wp tags
308
+ if ( ! defined( 'LSCACHE_IS_ESI' ) ) {
309
+ $type_tags = self::_build_type_tags() ;
310
+ self::$_tags = array_merge( self::$_tags, $type_tags ) ;
311
+ }
312
+ // append blog main tag
313
+ self::$_tags[] = '' ;
314
+ // removed duplicates
315
+ self::$_tags = array_unique( self::$_tags ) ;
316
+ }
317
+
318
+ /**
319
+ * Sets up the Cache Tags header.
320
+ * ONLY need to run this if is cacheable
321
+ *
322
+ * @since 1.1.3
323
+ * @access public
324
+ * @return string empty string if empty, otherwise the cache tags header.
325
+ */
326
+ public static function output()
327
+ {
328
+ self::_finalize() ;
329
+
330
+ $prefix_tags = array() ;
331
+ $prefix = LSWCP_TAG_PREFIX . get_current_blog_id() . '_' ;
332
+
333
+ // If is_private and has private tags, append them first, then specify prefix to `public` for public tags
334
+ if ( LiteSpeed_Cache_Control::is_private() ) {
335
+ foreach ( self::$_tags_priv as $priv_tag ) {
336
+ $prefix_tags[] = $prefix . $priv_tag ;
337
+ }
338
+ $prefix = 'public:' . $prefix ;
339
+ }
340
+
341
+ foreach ( self::$_tags as $tag ) {
342
+ $prefix_tags[] = $prefix . $tag ;
343
+ }
344
+
345
+ $hdr = self::X_HEADER . ': ' . implode( ',', $prefix_tags ) ;
346
+
347
+ return $hdr ;
348
+ }
349
+
350
+ /**
351
+ * Get the current instance object.
352
+ *
353
+ * @since 1.1.3
354
+ * @access public
355
+ * @return Current class instance.
356
+ */
357
+ // public static function get_instance()
358
+ // {
359
+ // $cls = get_called_class() ;
360
+ // if ( ! isset(self::$_instance) ) {
361
+ // self::$_instance = new $cls() ;
362
+ // }
363
+
364
+ // return self::$_instance ;
365
+ // }
366
+
367
+ }
includes/litespeed-cache-task.class.php ADDED
@@ -0,0 +1,128 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * The cron task class.
5
+ *
6
+ * @since 1.1.3
7
+ * @package LiteSpeed_Cache
8
+ * @subpackage LiteSpeed_Cache/includes
9
+ * @author LiteSpeed Technologies <info@litespeedtech.com>
10
+ */
11
+ class LiteSpeed_Cache_Task
12
+ {
13
+ const CRON_ACTION_HOOK = 'litespeed_crawl_trigger' ;
14
+ const CRON_FITLER = 'litespeed_crawl_filter' ;
15
+
16
+ /**
17
+ * Enable/Disable cron task
18
+ *
19
+ * @since 1.1.0
20
+ * @access public
21
+ */
22
+ public static function enable()
23
+ {
24
+ $id = LiteSpeed_Cache_Config::CRWL_CRON_ACTIVE ;
25
+
26
+ // get new setting
27
+ $is_enabled = ! LiteSpeed_Cache::config( $id ) ;
28
+
29
+ // log
30
+ LiteSpeed_Cache_Log::debug( 'Crawler log: Crawler is ' . ( $is_enabled ? 'enabled' : 'disabled' ) ) ;
31
+
32
+ // update config
33
+ LiteSpeed_Cache_Config::get_instance()->update_options( array( $id => $is_enabled ) ) ;
34
+
35
+ self::update() ;
36
+
37
+ echo json_encode( array( 'enable' => $is_enabled ) ) ;
38
+ wp_die() ;
39
+ }
40
+
41
+ /**
42
+ * Update cron status
43
+ *
44
+ * @since 1.1.0
45
+ * @access public
46
+ * @param array $options The options to check if cron should be enabled
47
+ */
48
+ public static function update( $options = false )
49
+ {
50
+ $id_task_enabled = LiteSpeed_Cache_Config::CRWL_CRON_ACTIVE ;
51
+ $id_plugin_enabled = LiteSpeed_Cache_Config::OPID_ENABLED ;
52
+ if ( $options && isset( $options[$id_task_enabled] ) && isset( $options[$id_plugin_enabled] ) ) {
53
+ $is_active = $options[$id_task_enabled] && $options[$id_plugin_enabled] ;
54
+ }
55
+ else {
56
+ $is_active = LiteSpeed_Cache::config( $id_task_enabled ) && LiteSpeed_Cache::config( $id_plugin_enabled ) ;
57
+ }
58
+
59
+ if ( $is_active ) {
60
+ self::schedule_filter() ;
61
+ self::register() ;
62
+ }
63
+ else {
64
+ self::clear() ;
65
+ }
66
+
67
+ }
68
+
69
+ /**
70
+ * Schedule cron
71
+ *
72
+ * @since 1.1.0
73
+ * @access public
74
+ */
75
+ public static function schedule_filter()
76
+ {
77
+ add_filter( 'cron_schedules', 'LiteSpeed_Cache_Task::lscache_cron_filter' ) ;
78
+ }
79
+
80
+ /**
81
+ * Register cron interval
82
+ *
83
+ * @since 1.1.0
84
+ * @access public
85
+ * @param array $schedules WP Hook
86
+ */
87
+ public static function lscache_cron_filter( $schedules )
88
+ {
89
+ $interval = LiteSpeed_Cache::config( LiteSpeed_Cache_Config::CRWL_RUN_INTERVAL ) ;
90
+ // $wp_schedules = wp_get_schedules() ;
91
+ if ( ! array_key_exists( self::CRON_FITLER, $schedules ) ) {
92
+ // if ( LiteSpeed_Cache_Log::get_enabled() ) {
93
+ // LiteSpeed_Cache_Log::push('Crawler cron log: ......cron filter '.$interval.' added......') ;
94
+ // }
95
+ $schedules[self::CRON_FITLER] = array(
96
+ 'interval' => $interval,
97
+ 'display' => __( 'LiteSpeed Cache Custom Cron', 'litespeed-cache' ),
98
+ ) ;
99
+ }
100
+ return $schedules ;
101
+ }
102
+
103
+ /**
104
+ * Register the cron task to WP
105
+ *
106
+ * @since 1.1.0
107
+ * @access public
108
+ */
109
+ public static function register()
110
+ {
111
+ if( ! wp_next_scheduled( self::CRON_ACTION_HOOK ) ) {
112
+ LiteSpeed_Cache_Log::debug( 'Crawler cron log: ......cron hook register......' ) ;
113
+ wp_schedule_event( time(), self::CRON_FITLER, self::CRON_ACTION_HOOK ) ;
114
+ }
115
+ }
116
+
117
+ /**
118
+ * Clear cron
119
+ *
120
+ * @since 1.1.0
121
+ * @access public
122
+ */
123
+ public static function clear()
124
+ {
125
+ LiteSpeed_Cache_Log::debug( 'Crawler cron log: ......cron hook cleared......' ) ;
126
+ wp_clear_scheduled_hook( self::CRON_ACTION_HOOK ) ;
127
+ }
128
+ }
includes/litespeed-cache-utility.class.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * The utility class.
5
+ *
6
+ * @since 1.1.5
7
+ * @package LiteSpeed_Cache
8
+ * @subpackage LiteSpeed_Cache/includes
9
+ * @author LiteSpeed Technologies <info@litespeedtech.com>
10
+ */
11
+ class LiteSpeed_Cache_Utility
12
+ {
13
+
14
+ /**
15
+ * Make URL to be relative
16
+ *
17
+ * @param string $url
18
+ * @return string Relative URL
19
+ */
20
+ public static function make_relative( $url )
21
+ {
22
+ // replace site_url if the url is full url
23
+ // NOTE: for subfolder site_url, need to strip subfolder part (strip anything but scheme and host)
24
+ require_once LSWCP_DIR . 'lib/litespeed-php-compatibility.func.php' ;
25
+ $site_url_domain = http_build_url( LiteSpeed_Cache_Router::get_siteurl(), array(), HTTP_URL_STRIP_ALL ) ;
26
+ if ( strpos( $url, $site_url_domain ) === 0 ) {
27
+ $url = substr( $url, strlen( $site_url_domain ) ) ;
28
+ }
29
+ return trim( $url ) ;
30
+ }
31
+ }
includes/litespeed-cache-vary.class.php ADDED
@@ -0,0 +1,402 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The plugin vary class to manage X-LiteSpeed-Vary
4
+ *
5
+ * @since 1.1.3
6
+ * @package LiteSpeed_Cache
7
+ * @subpackage LiteSpeed_Cache/includes
8
+ * @author LiteSpeed Technologies <info@litespeedtech.com>
9
+ */
10
+ class LiteSpeed_Cache_Vary
11
+ {
12
+ private static $_instance ;
13
+
14
+ const X_HEADER = 'X-LiteSpeed-Vary' ;
15
+
16
+ private static $_vary_name = '_lscache_vary' ; // this default vary cookie is used for logged in status check
17
+ private static $_vary_cookies = array() ; // vary header only!
18
+
19
+ /**
20
+ * Adds the actions used for setting up cookies on log in/out.
21
+ *
22
+ * Also checks if the database matches the rewrite rule.
23
+ *
24
+ * @since 1.0.4
25
+ */
26
+ private function __construct()
27
+ {
28
+ // logged in user
29
+ if ( LiteSpeed_Cache_Router::is_logged_in() ) {
30
+ // Make sure the cookie value is corrent
31
+ self::add_logged_in() ;
32
+
33
+ // If not esi, check cache logged-in user setting
34
+ if ( ! LSWCP_ESI_SUPPORT || ! LiteSpeed_Cache::config( LiteSpeed_Cache_Config::OPID_ESI_ENABLE ) ) {
35
+ // If cache logged-in, then init cacheable to private
36
+ if ( LiteSpeed_Cache::config( LiteSpeed_Cache_Config::OPID_CACHE_PRIV ) ) {
37
+ add_action( 'wp_logout', 'LiteSpeed_Cache_Purge::purge_on_logout' ) ;
38
+
39
+ LiteSpeed_Cache_Control::init_cacheable() ;
40
+ LiteSpeed_Cache_Control::set_private( 'logged in user' ) ;
41
+ }
42
+ // No cache for logged-in user
43
+ else {
44
+ LiteSpeed_Cache_Control::set_nocache( 'logged in user' ) ;
45
+ }
46
+ }
47
+ // ESI is on, can be public cache
48
+ else {
49
+ LiteSpeed_Cache_Control::init_cacheable() ;
50
+ }
51
+
52
+ // register logout hook to clear login status
53
+ add_action( 'clear_auth_cookie', 'LiteSpeed_Cache_Vary::remove_logged_in' ) ;
54
+
55
+ }
56
+ else {
57
+ // Make sure the cookie value is corrent
58
+ self::remove_logged_in() ;
59
+
60
+ // Set vary cookie for logging in user, otherwise the user will hit public with vary=0 (guest version)
61
+ add_action( 'set_logged_in_cookie', 'LiteSpeed_Cache_Vary::add_logged_in', 10, 2 ) ;
62
+ add_action( 'wp_login', 'LiteSpeed_Cache_Purge::purge_on_logout' ) ;
63
+
64
+ LiteSpeed_Cache_Control::init_cacheable() ;
65
+
66
+ // Check `login page` cacheable setting because they don't go through main WP logic
67
+ add_action( 'login_init', 'LiteSpeed_Cache_Tag::check_login_cacheable', 5 ) ;
68
+
69
+ }
70
+
71
+ // Add comment list ESI
72
+ add_filter('comments_array', array( $this, 'check_commenter' ) ) ;
73
+
74
+ // Set vary cookie for commenter.
75
+ add_action('set_comment_cookies', array( $this, 'append_commenter' ) ) ;
76
+
77
+ /******** Below to the end is only for cookie name setting check ********/
78
+ // Get specific cookie name
79
+ $db_cookie = false ;
80
+ if ( is_multisite() ) {
81
+ $options = LiteSpeed_Cache_Config::get_instance()->get_site_options() ;
82
+ if ( is_array($options) ) {
83
+ $db_cookie = $options[LiteSpeed_Cache_Config::OPID_LOGIN_COOKIE] ;
84
+ }
85
+ }
86
+ else {
87
+ $db_cookie = LiteSpeed_Cache::config(LiteSpeed_Cache_Config::OPID_LOGIN_COOKIE) ;
88
+ }
89
+
90
+ // If no vary set in rewrite rule
91
+ if ( ! isset($_SERVER['LSCACHE_VARY_COOKIE']) ) {
92
+ if ( $db_cookie ) {
93
+ // Display cookie error msg to admin
94
+ if ( is_multisite() ? is_network_admin() : is_admin() ) {
95
+ LiteSpeed_Cache_Admin_Display::show_error_cookie() ;
96
+ }
97
+ LiteSpeed_Cache_Control::set_nocache('vary cookie setting error') ;
98
+ return ;
99
+ }
100
+ return ;
101
+ }
102
+ // If db setting does not exist, skip checking db value
103
+ if ( ! $db_cookie ) {
104
+ return ;
105
+ }
106
+
107
+ // beyond this point, need to make sure db vary setting is in $_SERVER env.
108
+ $vary_arr = explode(',', $_SERVER['LSCACHE_VARY_COOKIE']) ;
109
+
110
+ if ( in_array($db_cookie, $vary_arr) ) {
111
+ self::$_vary_name = $db_cookie ;
112
+ return ;
113
+ }
114
+
115
+ if ( is_multisite() ? is_network_admin() : is_admin() ) {
116
+ LiteSpeed_Cache_Admin_Display::show_error_cookie() ;
117
+ }
118
+ LiteSpeed_Cache_Control::set_nocache('vary cookie setting lost error') ;
119
+ }
120
+
121
+ /**
122
+ * Hooked to the comments_array filter.
123
+ *
124
+ * Check if the user accessing the page has the commenter cookie.
125
+ *
126
+ * If the user does not want to cache commenters, just check if user is commenter.
127
+ * Otherwise if the vary cookie is set, unset it. This is so that when the page is cached, the page will appear as if the user was a normal user.
128
+ * Normal user is defined as not a logged in user and not a commenter.
129
+ *
130
+ * @since 1.0.4
131
+ * @access public
132
+ * @global type $post
133
+ * @param array $comments The current comments to output
134
+ * @return array The comments to output.
135
+ */
136
+ public function check_commenter( $comments )
137
+ {
138
+ $pending = false ;
139
+ foreach ( $comments as $comment ) {
140
+ if ( ! $comment->comment_approved ) {// current user has pending comment
141
+ $pending = true ;
142
+ break ;
143
+ }
144
+ }
145
+
146
+ // No pending comments, don't need to add private cache
147
+ if ( ! $pending ) {
148
+ $this->remove_commenter() ;
149
+
150
+ foreach( $_COOKIE as $cookie_name => $cookie_value ) {
151
+ if ( strlen( $cookie_name ) >= 15 && strncmp( $cookie_name, 'comment_author_', 15 ) == 0 ) {
152
+ unset( $_COOKIE[ $cookie_name ] ) ;
153
+ }
154
+ }
155
+
156
+ return $comments ;
157
+ }
158
+
159
+ // Current user/visitor has pending comments
160
+ // set vary=2 for next time vary lookup
161
+ $this->add_commenter() ;
162
+
163
+ if ( LiteSpeed_Cache::config( LiteSpeed_Cache_Config::OPID_CACHE_COMMENTER ) ) {
164
+ LiteSpeed_Cache_Control::set_private( 'existing commenter' ) ;
165
+ }
166
+ else {
167
+ LiteSpeed_Cache_Control::set_nocache( 'existing commenter' ) ;
168
+ }
169
+
170
+ return $comments ;
171
+ }
172
+
173
+ /**
174
+ * Check if default vary has a value
175
+ *
176
+ * @since 1.1.3
177
+ * @access private
178
+ */
179
+ private static function has_vary()
180
+ {
181
+ if ( empty( $_COOKIE[ self::$_vary_name ] ) ) {
182
+ return false ;
183
+ }
184
+ return intval( $_COOKIE[ self::$_vary_name ] ) ;
185
+ }
186
+
187
+ /**
188
+ * Append user status with logged in
189
+ *
190
+ * @since 1.1.3
191
+ * @access public
192
+ */
193
+ public static function add_logged_in($logged_in_cookie = false, $expire = false)
194
+ {
195
+ // If the cookie is lost somehow, set it
196
+ if ( ! self::has_vary() ) {
197
+ $_COOKIE[ self::$_vary_name ] = 1 ;
198
+
199
+ // save it
200
+ if ( ! $expire ) {
201
+ $expire = time() + 2 * DAY_IN_SECONDS ;
202
+ }
203
+ self::_cookie( $_COOKIE[ self::$_vary_name ], $expire ) ;
204
+ LiteSpeed_Cache_Control::set_nocache( 'adding logged in status' ) ;
205
+ }
206
+ }
207
+
208
+ /**
209
+ * Remove user logged in status
210
+ *
211
+ * @since 1.1.3
212
+ * @access public
213
+ */
214
+ public static function remove_logged_in()
215
+ {
216
+ // If the cookie is set, unset it.
217
+ if ( self::has_vary() === 1 ) {
218
+ // remove logged in status from global var
219
+ unset( $_COOKIE[ self::$_vary_name ] ) ;
220
+ // save it
221
+ self::_cookie() ;
222
+ LiteSpeed_Cache_Control::set_nocache( 'removing logged in status' ) ;
223
+ }
224
+ }
225
+
226
+ /**
227
+ * Append user status with commenter
228
+ *
229
+ * This is ONLY used when submit a comment
230
+ *
231
+ * @since 1.1.6
232
+ * @access public
233
+ */
234
+ public function append_commenter()
235
+ {
236
+ $this->add_commenter( true ) ;
237
+ }
238
+
239
+ /**
240
+ * Correct user status with commenter
241
+ *
242
+ * @since 1.1.3
243
+ * @access private
244
+ * @param boolean $from_redirect If the request is from redirect page or not
245
+ */
246
+ private function add_commenter( $from_redirect = false )
247
+ {
248
+ // If the cookie is lost somehow, set it
249
+ if ( self::has_vary() !== 2 ) {
250
+ $_COOKIE[ self::$_vary_name ] = 2 ;
251
+ // save it
252
+ // only set commenter status for current domain path
253
+ self::_cookie( $_COOKIE[ self::$_vary_name ], time() + apply_filters( 'comment_cookie_lifetime', 30000000 ), self::_relative_path( $from_redirect ) ) ;
254
+ LiteSpeed_Cache_Control::set_nocache( 'adding commenter status' ) ;
255
+ }
256
+ }
257
+
258
+ /**
259
+ * Remove user commenter status
260
+ *
261
+ * @since 1.1.3
262
+ * @access private
263
+ */
264
+ private function remove_commenter()
265
+ {
266
+ if ( self::has_vary() === 2 ) {
267
+ // remove logged in status from global var
268
+ unset( $_COOKIE[ self::$_vary_name ] ) ;
269
+ // save it
270
+ self::_cookie( false, false, self::_relative_path() ) ;
271
+ LiteSpeed_Cache_Control::set_nocache( 'removing commenter status' ) ;
272
+ }
273
+ }
274
+
275
+ /**
276
+ * Generate relative path for cookie
277
+ *
278
+ * @since 1.1.3
279
+ * @access private
280
+ * @param boolean $from_redirect If the request is from redirect page or not
281
+ */
282
+ private static function _relative_path( $from_redirect = false )
283
+ {
284
+ $path = false ;
285
+ $tag = $from_redirect ? 'HTTP_REFERER' : 'SCRIPT_URL' ;
286
+ if ( ! empty( $_SERVER[ $tag ] ) ) {
287
+ $path = parse_url( $_SERVER[ $tag ] ) ;
288
+ $path = ! empty( $path[ 'path' ] ) ? $path[ 'path' ] : false ;
289
+ LiteSpeed_Cache_Log::debug( 'Cookie Vary path: ' . $path ) ;
290
+ }
291
+ return $path ;
292
+ }
293
+
294
+ /**
295
+ * Gets vary cookies that are already added for the current page.
296
+ *
297
+ * @since 1.0.13
298
+ * @access private
299
+ * @return array An array of all vary cookies currently added.
300
+ */
301
+ private static function _format_vary_cookies()
302
+ {
303
+ if ( empty(self::$_vary_cookies) ) {
304
+ return false ;
305
+ }
306
+ $cookies = array_filter(array_unique(self::$_vary_cookies)) ;
307
+ if ( empty($cookies) ) {
308
+ return false ;
309
+ }
310
+ foreach ($cookies as $key => $val) {
311
+ $cookies[$key] = 'cookie=' . $val ;
312
+ }
313
+ return $cookies ;
314
+ }
315
+
316
+ /**
317
+ * Builds the vary header.
318
+ *
319
+ * Currently, this only checks post passwords.
320
+ *
321
+ * @since 1.0.13
322
+ * @access public
323
+ * @global $post
324
+ * @return mixed false if the user has the postpass cookie. Empty string
325
+ * if the post is not password protected. Vary header otherwise.
326
+ */
327
+ public static function output()
328
+ {
329
+ if ( ! LiteSpeed_Cache_Control::is_cacheable() ) {
330
+ return ;
331
+ }
332
+ $tp_cookies = self::_format_vary_cookies() ;
333
+ global $post ;
334
+ if ( ! empty($post->post_password) ) {
335
+ if ( isset($_COOKIE['wp-postpass_' . COOKIEHASH]) ) {
336
+ // If user has password cookie, do not cache
337
+ LiteSpeed_Cache_Control::set_nocache('password protected vary') ;
338
+ return ;
339
+ }
340
+
341
+ $tp_cookies[] = 'cookie=wp-postpass_' . COOKIEHASH ;
342
+ }
343
+
344
+ if ( empty($tp_cookies) ) {
345
+ return ;
346
+ }
347
+ return self::X_HEADER . ': ' . implode(',', $tp_cookies) ;
348
+ }
349
+
350
+ /**
351
+ * Adds vary to the list of vary cookies for the current page.
352
+ *
353
+ * @since 1.0.13
354
+ * @access public
355
+ * @param mixed $vary A string or array of vary cookies to add to the current list.
356
+ */
357
+ public static function add($vary)
358
+ {
359
+ if ( ! is_array($vary) ) {
360
+ $vary = array($vary) ;
361
+ }
362
+
363
+ self::$_vary_cookies = array_merge(self::$_vary_cookies, $vary) ;
364
+ }
365
+
366
+ /**
367
+ * Set the vary cookie.
368
+ *
369
+ * If vary cookie changed, must set non cacheable.
370
+ *
371
+ * @since 1.0.4
372
+ * @access private
373
+ * @param integer $val The value to update.
374
+ * @param integer $expire Expire time.
375
+ * @param boolean $path False if use wp root path as cookie path
376
+ */
377
+ private static function _cookie($val = false, $expire = false, $path = false)
378
+ {
379
+ if ( ! $val ) {
380
+ $expire = 1 ;
381
+ }
382
+
383
+ setcookie(self::$_vary_name, $val, $expire, $path?: COOKIEPATH, COOKIE_DOMAIN, is_ssl(), true) ;
384
+ }
385
+
386
+ /**
387
+ * Get the current instance object.
388
+ *
389
+ * @since 1.1.3
390
+ * @access public
391
+ * @return Current class instance.
392
+ */
393
+ public static function get_instance()
394
+ {
395
+ $cls = get_called_class() ;
396
+ if ( ! isset(self::$_instance) ) {
397
+ self::$_instance = new $cls() ;
398
+ }
399
+
400
+ return self::$_instance ;
401
+ }
402
+ }
includes/litespeed-cache.class.php ADDED
@@ -0,0 +1,522 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The core plugin class.
4
+ *
5
+ * This is used to define internationalization, admin-specific hooks, and
6
+ * public-facing site hooks.
7
+ *
8
+ * Also maintains the unique identifier of this plugin as well as the current
9
+ * version of the plugin.
10
+ *
11
+ * @since 1.0.0
12
+ * @package LiteSpeed_Cache
13
+ * @subpackage LiteSpeed_Cache/includes
14
+ * @author LiteSpeed Technologies <info@litespeedtech.com>
15
+ */
16
+ class LiteSpeed_Cache
17
+ {
18
+ private static $_instance ;
19
+
20
+ const PLUGIN_NAME = 'litespeed-cache' ;
21
+ const PLUGIN_VERSION = '1.1.6' ;
22
+
23
+ const PAGE_EDIT_HTACCESS = 'lscache-edit-htaccess' ;
24
+
25
+ const NONCE_NAME = 'LSCWP_NONCE' ;
26
+ const ACTION_KEY = 'LSCWP_CTRL' ;
27
+ const ACTION_DISMISS_WHM = 'dismiss-whm' ;
28
+ const ACTION_DISMISS_EXPIRESDEFAULT = 'dismiss-ExpiresDefault' ;
29
+ const ACTION_SAVE_HTACCESS = 'save-htaccess' ;
30
+ const ACTION_SAVE_SETTINGS = 'save-settings' ;
31
+ const ACTION_SAVE_SETTINGS_NETWORK = 'save-settings-network' ;
32
+ const ACTION_PURGE_ERRORS = 'PURGE_ERRORS' ;
33
+ const ACTION_PURGE_PAGES = 'PURGE_PAGES' ;
34
+ const ACTION_PURGE_BY = 'PURGE_BY' ;
35
+ const ACTION_PURGE_FRONT = 'PURGE_FRONT' ;
36
+ const ACTION_PURGE_ALL = 'PURGE_ALL' ;
37
+ const ACTION_PURGE_EMPTYCACHE = 'PURGE_EMPTYCACHE' ;
38
+ const ACTION_QS_PURGE = 'PURGE' ;
39
+ const ACTION_QS_PURGE_SINGLE = 'PURGESINGLE' ;
40
+ const ACTION_QS_SHOW_HEADERS = 'SHOWHEADERS' ;
41
+ const ACTION_QS_PURGE_ALL = 'purge_all' ;
42
+ const ACTION_QS_PURGE_EMPTYCACHE = 'empty_all' ;
43
+ const ACTION_QS_NOCACHE = 'NOCACHE' ;
44
+ const ACTION_CRAWLER_GENERATE_FILE = 'crawler-generate-file' ;
45
+ const ACTION_CRAWLER_RESET_POS = 'crawler-reset-pos' ;
46
+ const ACTION_CRAWLER_CRON_ENABLE = 'crawler-cron-enable' ;
47
+ const ACTION_DO_CRAWL = 'do-crawl' ;
48
+ const ACTION_BLACKLIST_SAVE = 'blacklist-save' ;
49
+
50
+ const WHM_TRANSIENT = 'lscwp_whm_install' ;
51
+ const WHM_TRANSIENT_VAL = 'whm_install' ;
52
+
53
+ const HEADER_DEBUG = 'X-LiteSpeed-Debug' ;
54
+
55
+ protected static $_debug_show_header = false ;
56
+
57
+ /**
58
+ * Define the core functionality of the plugin.
59
+ *
60
+ * Set the plugin name and the plugin version that can be used throughout the plugin.
61
+ * Load the dependencies, define the locale, and set the hooks for the admin area and
62
+ * the public-facing side of the site.
63
+ *
64
+ * @since 1.0.0
65
+ */
66
+ private function __construct()
67
+ {
68
+ // Check if debug is on
69
+ if ( self::config(LiteSpeed_Cache_Config::OPID_ENABLED) ) {
70
+ $should_debug = intval(self::config(LiteSpeed_Cache_Config::OPID_DEBUG)) ;
71
+ if ( $should_debug == LiteSpeed_Cache_Config::VAL_ON || ($should_debug == LiteSpeed_Cache_Config::VAL_NOTSET && LiteSpeed_Cache_Router::is_admin_ip()) ) {
72
+ LiteSpeed_Cache_Log::set_enabled() ;
73
+ }
74
+
75
+ // Load third party detection if lscache enabled.
76
+ include_once LSWCP_DIR . 'thirdparty/lscwp-registry-3rd.php' ;
77
+ }
78
+
79
+ if ( ! LiteSpeed_Cache::config( LiteSpeed_Cache_Config::OPID_HEARTBEAT ) ) {
80
+ add_action( 'init', 'LiteSpeed_Cache_Log::disable_heartbeat', 1 ) ;
81
+ }
82
+
83
+ // Register plugin activate/deactivate/uninstall hooks
84
+ // NOTE: this can't be moved under after_setup_theme, otherwise activation will be bypassed somehow
85
+ if( is_admin() || LiteSpeed_Cache_Router::is_cli() ) {
86
+ $plugin_file = LSWCP_DIR . 'litespeed-cache.php' ;
87
+ register_activation_hook($plugin_file, array('LiteSpeed_Cache_Activation', 'register_activation' )) ;
88
+ register_deactivation_hook($plugin_file, array('LiteSpeed_Cache_Activation', 'register_deactivation' )) ;
89
+ register_uninstall_hook($plugin_file, 'LiteSpeed_Cache_Activation::uninstall_litespeed_cache') ;
90
+ }
91
+
92
+ add_action( 'after_setup_theme', array( $this, 'init' ) ) ;
93
+
94
+ // Check if there is a purge request in queue
95
+ if ( $purge_queue = get_option( LiteSpeed_Cache_Purge::PURGE_QUEUE ) ) {
96
+ @header( $purge_queue ) ;
97
+ LiteSpeed_Cache_Log::debug( 'Purge Queue found&sent: ' . $purge_queue ) ;
98
+ delete_option( LiteSpeed_Cache_Purge::PURGE_QUEUE ) ;
99
+ }
100
+ }
101
+
102
+ /**
103
+ * The plugin initializer.
104
+ *
105
+ * This function checks if the cache is enabled and ready to use, then
106
+ * determines what actions need to be set up based on the type of user
107
+ * and page accessed. Output is buffered if the cache is enabled.
108
+ *
109
+ * @since 1.0.0
110
+ * @access public
111
+ */
112
+ public function init()
113
+ {
114
+ if( is_admin() ) {
115
+ LiteSpeed_Cache_Admin::get_instance() ;
116
+ }
117
+
118
+ if ( ! LiteSpeed_Cache_Router::cache_enabled() || ! defined( 'LSCACHE_ADV_CACHE' ) || ! LSCACHE_ADV_CACHE ) {
119
+ return ;
120
+ }
121
+
122
+ define( 'LITESPEED_CACHE_ENABLED', true ) ;
123
+ ob_start( array( $this, 'send_headers_force' ) ) ;
124
+ add_action( 'shutdown', array( $this, 'send_headers' ), 0 ) ;
125
+ add_action( 'wp_footer', 'LiteSpeed_Cache::litespeed_comment_info' ) ;
126
+
127
+ // 1. Init vary
128
+ // 2. Init cacheable status
129
+ LiteSpeed_Cache_Vary::get_instance() ;
130
+
131
+ // Load public hooks
132
+ $this->load_public_actions() ;
133
+
134
+ // load cron task for crawler
135
+ if ( self::config( LiteSpeed_Cache_Config::CRWL_CRON_ACTIVE ) && LiteSpeed_Cache_Router::can_crawl() ) {
136
+ // keep cron intval filter
137
+ LiteSpeed_Cache_Task::schedule_filter() ;
138
+
139
+ // cron hook
140
+ add_action( LiteSpeed_Cache_Task::CRON_ACTION_HOOK, 'LiteSpeed_Cache_Crawler::crawl_data' ) ;
141
+ }
142
+
143
+ // Load 3rd party hooks
144
+ add_action( 'wp_loaded', array( $this, 'load_thirdparty' ), 2 ) ;
145
+
146
+ // load litespeed actions
147
+ if ( $action = LiteSpeed_Cache_Router::get_action() ) {
148
+ $this->proceed_action( $action ) ;
149
+ }
150
+ }
151
+
152
+ /**
153
+ * Run frontend actions
154
+ *
155
+ * @since 1.1.0
156
+ * @access public
157
+ */
158
+ public function proceed_action( $action )
159
+ {
160
+ $msg = false ;
161
+ // handle actions
162
+ switch ( $action ) {
163
+ case LiteSpeed_Cache::ACTION_QS_PURGE:
164
+ LiteSpeed_Cache_Purge::set_purge_related() ;
165
+ break;
166
+
167
+ case self::ACTION_QS_SHOW_HEADERS:
168
+ self::$_debug_show_header = true ;
169
+ break;
170
+
171
+ case LiteSpeed_Cache::ACTION_QS_PURGE_SINGLE:
172
+ LiteSpeed_Cache_Purge::set_purge_single() ;
173
+ break;
174
+
175
+ case LiteSpeed_Cache::ACTION_CRAWLER_GENERATE_FILE:
176
+ LiteSpeed_Cache_Crawler::get_instance()->generate_sitemap() ;
177
+ LiteSpeed_Cache_Admin::redirect() ;
178
+ break;
179
+
180
+ case LiteSpeed_Cache::ACTION_CRAWLER_RESET_POS:
181
+ LiteSpeed_Cache_Crawler::get_instance()->reset_pos() ;
182
+ LiteSpeed_Cache_Admin::redirect() ;
183
+ break;
184
+
185
+ case LiteSpeed_Cache::ACTION_CRAWLER_CRON_ENABLE:
186
+ LiteSpeed_Cache_Task::enable() ;
187
+ break;
188
+
189
+ // Handle the ajax request to proceed crawler manually by admin
190
+ case LiteSpeed_Cache::ACTION_DO_CRAWL:
191
+ LiteSpeed_Cache_Crawler::crawl_data( true ) ;
192
+ break ;
193
+
194
+ case LiteSpeed_Cache::ACTION_BLACKLIST_SAVE:
195
+ LiteSpeed_Cache_Crawler::get_instance()->save_blacklist() ;
196
+ $msg = __( 'Crawler blacklist is saved.', 'litespeed-cache' ) ;
197
+ break ;
198
+
199
+ case LiteSpeed_Cache::ACTION_PURGE_FRONT:
200
+ LiteSpeed_Cache_Purge::purge_front() ;
201
+ $msg = __( 'Notified LiteSpeed Web Server to purge the front page.', 'litespeed-cache' ) ;
202
+ break ;
203
+
204
+ case LiteSpeed_Cache::ACTION_PURGE_PAGES:
205
+ LiteSpeed_Cache_Purge::purge_pages() ;
206
+ $msg = __( 'Notified LiteSpeed Web Server to purge pages.', 'litespeed-cache' ) ;
207
+ break ;
208
+
209
+ case LiteSpeed_Cache::ACTION_PURGE_ERRORS:
210
+ LiteSpeed_Cache_Purge::purge_errors() ;
211
+ $msg = __( 'Notified LiteSpeed Web Server to purge error pages.', 'litespeed-cache' ) ;
212
+ break ;
213
+
214
+ case LiteSpeed_Cache::ACTION_PURGE_ALL:
215
+ case LiteSpeed_Cache::ACTION_QS_PURGE_ALL:
216
+ LiteSpeed_Cache_Purge::purge_all() ;
217
+ $msg = __( 'Notified LiteSpeed Web Server to purge all caches.', 'litespeed-cache' ) ;
218
+ break;
219
+
220
+ case LiteSpeed_Cache::ACTION_PURGE_EMPTYCACHE:
221
+ case LiteSpeed_Cache::ACTION_QS_PURGE_EMPTYCACHE:
222
+ define( 'LSWCP_EMPTYCACHE', true ) ;// clear all sites caches
223
+ LiteSpeed_Cache_Purge::purge_all() ;
224
+ $msg = __( 'Notified LiteSpeed Web Server to purge everything.', 'litespeed-cache' ) ;
225
+ break;
226
+
227
+ case LiteSpeed_Cache::ACTION_PURGE_BY:
228
+ LiteSpeed_Cache_Purge::get_instance()->purge_list() ;
229
+ $msg = __( 'Notified LiteSpeed Web Server to purge the list.', 'litespeed-cache' ) ;
230
+ break;
231
+
232
+ case LiteSpeed_Cache::ACTION_DISMISS_WHM:// Even its from ajax, we don't need to register wp ajax callback function but directly use our action
233
+ LiteSpeed_Cache_Activation::dismiss_whm() ;
234
+ break ;
235
+
236
+ case LiteSpeed_Cache::ACTION_DISMISS_EXPIRESDEFAULT:
237
+ update_option( LiteSpeed_Cache_Admin_Display::DISMISS_MSG, LiteSpeed_Cache_Admin_Display::RULECONFLICT_DISMISSED ) ;
238
+ break ;
239
+
240
+ default:
241
+ break ;
242
+ }
243
+ if ( $msg && ! LiteSpeed_Cache_Router::is_ajax() ) {
244
+ LiteSpeed_Cache_Admin_Display::add_notice( LiteSpeed_Cache_Admin_Display::NOTICE_GREEN, $msg ) ;
245
+ LiteSpeed_Cache_Admin::redirect() ;
246
+ return ;
247
+ }
248
+ }
249
+
250
+ /**
251
+ * Callback used to call the detect third party action.
252
+ *
253
+ * The detect action is used by third party plugin integration classes to determine if they should add the rest of their hooks.
254
+ *
255
+ * @since 1.0.5
256
+ * @access public
257
+ */
258
+ public function load_thirdparty()
259
+ {
260
+ do_action( 'litespeed_cache_api_load_thirdparty' ) ;
261
+ }
262
+
263
+ /**
264
+ * Register all of the hooks related to the all users
265
+ * of the plugin.
266
+ *
267
+ * @since 1.0.0
268
+ * @access private
269
+ */
270
+ private function load_public_actions()
271
+ {
272
+ //register purge actions
273
+ $purge_post_events = array(
274
+ 'edit_post',
275
+ 'save_post',
276
+ 'deleted_post',
277
+ 'trashed_post',
278
+ 'delete_attachment',
279
+ // 'clean_post_cache', // This will disable wc's not purge product when stock status not change setting
280
+ ) ;
281
+ foreach ( $purge_post_events as $event ) {
282
+ // this will purge all related tags
283
+ add_action( $event, 'LiteSpeed_Cache_Purge::purge_post', 10, 2 ) ;
284
+ }
285
+
286
+ // The ESI functionality is an enterprise feature.
287
+ // Removing the openlitespeed check will simply break the page.
288
+ //todo: make a constant for esiEnable included cfg esi eanbled
289
+ if ( LSWCP_ESI_SUPPORT ) {
290
+ if ( ! LiteSpeed_Cache_Router::is_ajax() && self::config( LiteSpeed_Cache_Config::OPID_ESI_ENABLE ) ) {
291
+ add_action( 'template_include', 'LiteSpeed_Cache_ESI::esi_template', 100 ) ;
292
+ add_action( 'load-widgets.php', 'LiteSpeed_Cache_Purge::purge_widget' ) ;
293
+ add_action( 'wp_update_comment_count', 'LiteSpeed_Cache_Purge::purge_comment_widget' ) ;
294
+ }
295
+ }
296
+ add_action( 'wp_update_comment_count', 'LiteSpeed_Cache_Purge::purge_feeds' ) ;
297
+
298
+ // register recent posts widget tag before theme renders it to make it work
299
+ add_filter( 'widget_posts_args', 'LiteSpeed_Cache_Tag::add_widget_recent_posts' ) ;
300
+
301
+ // 301 redirect hook
302
+ add_filter( 'wp_redirect', 'LiteSpeed_Cache_Control::check_redirect', 10, 2 ) ;
303
+ }
304
+
305
+ /**
306
+ * A shortcut to get the LiteSpeed_Cache_Config config value
307
+ *
308
+ * @since 1.0.0
309
+ * @access public
310
+ * @param string $opt_id An option ID if getting an option.
311
+ * @return the option value
312
+ */
313
+ public static function config( $opt_id )
314
+ {
315
+ return LiteSpeed_Cache_Config::get_instance()->get_option( $opt_id ) ;
316
+ }
317
+
318
+ /**
319
+ * Tigger coment info display for wp_footer hook
320
+ *
321
+ * @since 1.1.1
322
+ * @access public
323
+ */
324
+ public static function litespeed_comment_info()
325
+ {
326
+ // double check to make sure it is a html file
327
+ $buffer = ob_get_contents() ;
328
+ if ( strlen( $buffer ) > 300 ) {
329
+ $buffer = substr( $buffer, 0, 300 ) ;
330
+ }
331
+ if ( strstr( $buffer, '<!--' ) !== false ) {
332
+ $buffer = preg_replace( '|<!--.*?-->|s', '', $buffer ) ;
333
+ }
334
+ $is_html = stripos( $buffer, '<html' ) === 0 || stripos( $buffer, '<!DOCTYPE' ) === 0 ;
335
+ if ( defined( 'DOING_AJAX' ) ) {
336
+ return ;
337
+ }
338
+ if ( defined( 'DOING_CRON' ) ) {
339
+ return ;
340
+ }
341
+ if ( ! $is_html ) {
342
+ return ;
343
+ }
344
+
345
+ if ( ! defined( 'LITESPEED_COMMENT_INFO' ) ) {
346
+ define( 'LITESPEED_COMMENT_INFO', true ) ;
347
+ }
348
+ }
349
+
350
+ /**
351
+ * For compatibility with those plugins have 'Bad' logic that forced all buffer output even it is NOT their buffer :(
352
+ *
353
+ * @since 1.1.5
354
+ * @access public
355
+ * @param string $buffer
356
+ * @return string
357
+ */
358
+ public function send_headers_force( $buffer )
359
+ {
360
+ $buffer .= $this->send_headers( true ) ;
361
+ return $buffer ;
362
+ }
363
+
364
+ /**
365
+ * Sends the headers out at the end of processing the request.
366
+ *
367
+ * This will send out all LiteSpeed Cache related response headers
368
+ * needed for the post.
369
+ *
370
+ * @since 1.0.5
371
+ * @access public
372
+ * @param boolean $is_forced If the header is sent following our normal finalizing logic
373
+ */
374
+ public function send_headers( $is_forced = false )
375
+ {
376
+ // Make sure header output only run once
377
+ if ( ! defined( 'LITESPEED_DID_' . __FUNCTION__ ) ) {
378
+ define( 'LITESPEED_DID_' . __FUNCTION__, true ) ;
379
+ }
380
+ else {
381
+ return ;
382
+ }
383
+
384
+ // NOTE: cache ctrl output needs to be done first, as currently some varies are added in 3rd party hook `litespeed_cache_api_control`.
385
+ LiteSpeed_Cache_Control::finalize() ;
386
+
387
+ $vary_header = LiteSpeed_Cache_Vary::output() ;
388
+
389
+ // If is not cacheable but Admin QS is `purge` or `purgesingle`, `tag` still needs to be generated
390
+ $tag_header = LiteSpeed_Cache_Tag::output() ;
391
+ if ( LiteSpeed_Cache_Control::is_cacheable() && ! $tag_header ) {
392
+ LiteSpeed_Cache_Control::set_nocache( 'empty tag header' ) ;
393
+ }
394
+
395
+ // NOTE: `purge` output needs to be after `tag` output as Admin QS may need to send `tag` header
396
+ $purge_header = LiteSpeed_Cache_Purge::output() ;
397
+
398
+ // generate `control` header in the end in case control status is changed by other headers.
399
+ $control_header = LiteSpeed_Cache_Control::output() ;
400
+
401
+ // Init comment info
402
+ $running_info_showing = defined( 'LITESPEED_COMMENT_INFO' ) || defined( 'LSCACHE_IS_ESI' ) ;
403
+ $comment = '' ;
404
+ if ( $running_info_showing ) {
405
+ if ( LiteSpeed_Cache_Control::is_cacheable() ) {
406
+ $comment .= '<!-- ' . ( defined( 'LSCACHE_IS_ESI' ) ? 'Block' : 'Page' ) . ' generated by LiteSpeed Cache on '.date('Y-m-d H:i:s').' -->' ;
407
+ }
408
+ else {
409
+ $comment .= '<!-- LiteSpeed Cache on '.date('Y-m-d H:i:s').' -->' ;
410
+ }
411
+ }
412
+
413
+ // send Control header
414
+ if ( $control_header ) {
415
+ @header( $control_header ) ;
416
+ if ( LiteSpeed_Cache_Log::get_enabled() ) {
417
+ LiteSpeed_Cache_Log::push( $control_header ) ;
418
+ if ( $running_info_showing ) {
419
+ $comment .= "\n<!-- " . $control_header . " -->" ;
420
+ }
421
+ }
422
+ }
423
+ // send PURGE header
424
+ if ( $purge_header ) {
425
+ @header( $purge_header ) ;
426
+ if ( LiteSpeed_Cache_Log::get_enabled() ) {
427
+ LiteSpeed_Cache_Log::push( $purge_header ) ;
428
+ if ( $running_info_showing ) {
429
+ $comment .= "\n<!-- " . $purge_header . " -->" ;
430
+ }
431
+ }
432
+ }
433
+ // send Vary header
434
+ if ( $vary_header ) {
435
+ @header( $vary_header ) ;
436
+ if ( LiteSpeed_Cache_Log::get_enabled() ) {
437
+ LiteSpeed_Cache_Log::push( $vary_header ) ;
438
+ if ( $running_info_showing ) {
439
+ $comment .= "\n<!-- " . $vary_header . " -->" ;
440
+ }
441
+ }
442
+ }
443
+
444
+ // Admin QS show header action
445
+ if ( self::$_debug_show_header ) {
446
+ $debug_header = self::HEADER_DEBUG . ': ' ;
447
+ if ( $control_header ) {
448
+ $debug_header .= $control_header . '; ' ;
449
+ }
450
+ if ( $purge_header ) {
451
+ $debug_header .= $purge_header . '; ' ;
452
+ }
453
+ if ( $tag_header ) {
454
+ $debug_header .= $tag_header . '; ' ;
455
+ }
456
+ if ( $vary_header ) {
457
+ $debug_header .= $vary_header . '; ' ;
458
+ }
459
+ @header( $debug_header ) ;
460
+ LiteSpeed_Cache_Log::debug( $debug_header ) ;
461
+ }
462
+ else {
463
+ // Control header
464
+ if ( LiteSpeed_Cache_Control::is_cacheable() && $tag_header ) {
465
+ @header( $tag_header ) ;
466
+ if ( LiteSpeed_Cache_Log::get_enabled() ) {
467
+ LiteSpeed_Cache_Log::push( $tag_header ) ;
468
+ if ( $running_info_showing ) {
469
+ $comment .= "\n<!-- " . $tag_header . " -->" ;
470
+ }
471
+ }
472
+ }
473
+ }
474
+
475
+ LiteSpeed_Cache_Log::debug(
476
+ 'End response' . ( $is_forced ? '(forced)' : '' ) . ".\n--------------------------------------------------------------------------------\n"
477
+ ) ;
478
+
479
+ if ( $comment ) {
480
+ if ( $is_forced ) {
481
+ return $comment ;
482
+ }
483
+ else {
484
+ echo $comment ;
485
+ }
486
+ }
487
+ }
488
+
489
+ /**
490
+ * Get the current instance object.
491
+ *
492
+ * @since 1.1.0
493
+ * @access public
494
+ * @return Current class instance.
495
+ */
496
+ public static function get_instance()
497
+ {
498
+ $cls = get_called_class() ;
499
+ if ( ! isset(self::$_instance) ) {
500
+ self::$_instance = new $cls() ;
501
+ }
502
+
503
+ return self::$_instance ;
504
+ }
505
+
506
+ /**
507
+ * Deprecated calls for backward compatibility to v1.1.2.2
508
+ */
509
+ public function purge_post( $id )
510
+ {
511
+ litespeed_purge_single_post( $id ) ;
512
+ }
513
+
514
+ /**
515
+ * Deprecated calls for backward compatibility to v1.1.2.2
516
+ */
517
+ public function purge_all()
518
+ {
519
+ LiteSpeed_Cache_API::purge_all() ;
520
+ }
521
+
522
+ }
includes/litespeed.autoload.php ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Auto registration for LiteSpeed classes
4
+ *
5
+ * @since 1.1.0
6
+ * @package LiteSpeed_Cache
7
+ * @subpackage LiteSpeed_Cache/includes
8
+ * @author LiteSpeed Technologies <info@litespeedtech.com>
9
+ */
10
+
11
+ if ( ! defined('WPINC') ) {
12
+ die ;
13
+ }
14
+
15
+ if ( !function_exists('_litespeed_autoload') ) {
16
+ function _litespeed_autoload($cls)
17
+ {
18
+ $class2fileArr = array(
19
+ 'LiteSpeed' => 'lib/litespeed/litespeed.class.php',
20
+ 'Litespeed_Crawler' => 'lib/litespeed/litespeed-crawler.class.php',
21
+ 'Litespeed_File' => 'lib/litespeed/litespeed-file.class.php',
22
+
23
+ 'LiteSpeed_Cache' => 'includes/litespeed-cache.class.php',
24
+ 'LiteSpeed_Cache_Activation' => 'includes/litespeed-cache-activation.class.php',
25
+ 'LiteSpeed_Cache_API' => 'includes/litespeed-cache-api.class.php',
26
+ 'LiteSpeed_Cache_Config' => 'includes/litespeed-cache-config.class.php',
27
+ 'LiteSpeed_Cache_Control' => 'includes/litespeed-cache-control.class.php',
28
+ 'LiteSpeed_Cache_Crawler' => 'includes/litespeed-cache-crawler.class.php',
29
+ 'LiteSpeed_Cache_Crawler_Sitemap' => 'includes/litespeed-cache-crawler-sitemap.class.php',
30
+ 'LiteSpeed_Cache_ESI' => 'includes/litespeed-cache-esi.class.php',
31
+ 'LiteSpeed_Cache_Log' => 'includes/litespeed-cache-log.class.php',
32
+ 'LiteSpeed_Cache_Purge' => 'includes/litespeed-cache-purge.class.php',
33
+ 'LiteSpeed_Cache_Router' => 'includes/litespeed-cache-router.class.php',
34
+ 'LiteSpeed_Cache_Tag' => 'includes/litespeed-cache-tag.class.php',
35
+ 'LiteSpeed_Cache_Task' => 'includes/litespeed-cache-task.class.php',
36
+ 'LiteSpeed_Cache_Vary' => 'includes/litespeed-cache-vary.class.php',
37
+ 'LiteSpeed_Cache_Utility' => 'includes/litespeed-cache-utility.class.php',
38
+
39
+ 'LiteSpeed_Cache_Admin' => 'admin/litespeed-cache-admin.class.php',
40
+ 'LiteSpeed_Cache_Admin_Display' => 'admin/litespeed-cache-admin-display.class.php',
41
+ 'LiteSpeed_Cache_Admin_Error' => 'admin/litespeed-cache-admin-error.class.php',
42
+ 'LiteSpeed_Cache_Admin_Report' => 'admin/litespeed-cache-admin-report.class.php',
43
+ 'LiteSpeed_Cache_Admin_Rules' => 'admin/litespeed-cache-admin-rules.class.php',
44
+ 'LiteSpeed_Cache_Admin_Settings' => 'admin/litespeed-cache-admin-settings.class.php',
45
+
46
+ 'LiteSpeed_Cache_Cli_Admin' => 'cli/litespeed-cache-cli-admin.class.php',
47
+ 'LiteSpeed_Cache_Cli_Purge' => 'cli/litespeed-cache-cli-purge.class.php',
48
+
49
+ 'LiteSpeed_Cache_Tags' => 'includes/deprecated-litespeed-cache-tags.class.php',
50
+ );
51
+ if( array_key_exists($cls, $class2fileArr) && file_exists(LSWCP_DIR . $class2fileArr[$cls]) ) {
52
+ require_once LSWCP_DIR . $class2fileArr[$cls];
53
+ }
54
+ }
55
+ }
56
+
57
+ spl_autoload_register('_litespeed_autoload');
languages/litespeed-cache.pot ADDED
@@ -0,0 +1,2782 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright (C) 2017 LiteSpeed Cache
2
+ # This file is distributed under the same license as the LiteSpeed Cache package.
3
+ msgid ""
4
+ msgstr ""
5
+ "Project-Id-Version: LiteSpeed Cache 1.1.6\n"
6
+ "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/litespeed-cache\n"
7
+ "POT-Creation-Date: 2017-08-23 21:39:09+00:00\n"
8
+ "MIME-Version: 1.0\n"
9
+ "Content-Type: text/plain; charset=UTF-8\n"
10
+ "Content-Transfer-Encoding: 8bit\n"
11
+ "PO-Revision-Date: 2017-MO-DA HO:MI+ZONE\n"
12
+ "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
13
+ "Language-Team: LANGUAGE <LL@li.org>\n"
14
+
15
+ #: admin/litespeed-cache-admin-display.class.php:137
16
+ msgid "Manage"
17
+ msgstr ""
18
+
19
+ #: admin/litespeed-cache-admin-display.class.php:139
20
+ #: admin/litespeed-cache-admin-display.class.php:222
21
+ msgid "Settings"
22
+ msgstr ""
23
+
24
+ #: admin/litespeed-cache-admin-display.class.php:142
25
+ msgid "Edit .htaccess"
26
+ msgstr ""
27
+
28
+ #: admin/litespeed-cache-admin-display.class.php:145
29
+ msgid "Information"
30
+ msgstr ""
31
+
32
+ #: admin/litespeed-cache-admin-display.class.php:147
33
+ msgid "Environment Report"
34
+ msgstr ""
35
+
36
+ #: admin/litespeed-cache-admin-display.class.php:151 admin/tpl/info.php:10
37
+ #: admin/tpl/settings.php:27
38
+ msgid "Crawler"
39
+ msgstr ""
40
+
41
+ #: admin/litespeed-cache-admin-display.class.php:155
42
+ #: admin/tpl/settings_debug.php:10
43
+ msgid "Debug Log"
44
+ msgstr ""
45
+
46
+ #: admin/litespeed-cache-admin-display.class.php:242
47
+ msgid ""
48
+ "It is recommended that LiteSpeed Cache be purged after updating a plugin."
49
+ msgstr ""
50
+
51
+ #: admin/litespeed-cache-admin-display.class.php:282
52
+ msgid "LiteSpeed Cache Purge All"
53
+ msgstr ""
54
+
55
+ #: admin/litespeed-cache-admin-display.class.php:812 admin/tpl/crawler.php:138
56
+ #: admin/tpl/settings_general.php:25
57
+ msgid "Enable"
58
+ msgstr ""
59
+
60
+ #: admin/litespeed-cache-admin-display.class.php:816 admin/tpl/crawler.php:138
61
+ #: admin/tpl/settings_general.php:31
62
+ msgid "Disable"
63
+ msgstr ""
64
+
65
+ #: admin/litespeed-cache-admin-display.class.php:843
66
+ msgid "Recommended value: %s."
67
+ msgstr ""
68
+
69
+ #: admin/litespeed-cache-admin-error.class.php:87
70
+ msgid "The installed PHP version is too old for the LiteSpeed Cache Plugin."
71
+ msgstr ""
72
+
73
+ #: admin/litespeed-cache-admin-error.class.php:89
74
+ msgid "The LiteSpeed Cache Plugin requires at least PHP %s."
75
+ msgstr ""
76
+
77
+ #: admin/litespeed-cache-admin-error.class.php:91
78
+ msgid ""
79
+ "The currently installed version is PHP %s, which is out-dated and insecure."
80
+ msgstr ""
81
+
82
+ #: admin/litespeed-cache-admin-error.class.php:93
83
+ #: admin/litespeed-cache-admin-error.class.php:102
84
+ msgid ""
85
+ "Please upgrade or go to <a href=\"%s\">active plugins</a> and deactivate the "
86
+ "LiteSpeed Cache plugin to hide this message."
87
+ msgstr ""
88
+
89
+ #: admin/litespeed-cache-admin-error.class.php:98
90
+ msgid ""
91
+ "The installed WordPress version is too old for the LiteSpeed Cache Plugin."
92
+ msgstr ""
93
+
94
+ #: admin/litespeed-cache-admin-error.class.php:100
95
+ msgid "The LiteSpeed Cache Plugin requires at least WordPress %s."
96
+ msgstr ""
97
+
98
+ #: admin/litespeed-cache-admin-error.class.php:107
99
+ msgid "Something went wrong with the form! Please try again."
100
+ msgstr ""
101
+
102
+ #: admin/litespeed-cache-admin-error.class.php:110
103
+ msgid "Tried to purge list with empty list."
104
+ msgstr ""
105
+
106
+ #: admin/litespeed-cache-admin-error.class.php:113
107
+ msgid "Bad Purge By selected value."
108
+ msgstr ""
109
+
110
+ #: admin/litespeed-cache-admin-error.class.php:116
111
+ msgid "Failed to purge by category, invalid category slug."
112
+ msgstr ""
113
+
114
+ #: admin/litespeed-cache-admin-error.class.php:119
115
+ msgid "Failed to purge by tag, invalid tag slug."
116
+ msgstr ""
117
+
118
+ #: admin/litespeed-cache-admin-error.class.php:122
119
+ msgid "Failed to purge by url, contained \"<\"."
120
+ msgstr ""
121
+
122
+ #: admin/litespeed-cache-admin-error.class.php:126
123
+ msgid "Failed to purge by Post ID, given ID is not numeric: %s"
124
+ msgstr ""
125
+
126
+ #: admin/litespeed-cache-admin-error.class.php:129
127
+ msgid ""
128
+ "Failed to purge by Post ID, given ID does not exist or is not published: %s"
129
+ msgstr ""
130
+
131
+ #: admin/litespeed-cache-admin-error.class.php:133
132
+ msgid "Failed to purge by url, invalid input: %s."
133
+ msgstr ""
134
+
135
+ #: admin/litespeed-cache-admin-error.class.php:136
136
+ msgid "Failed to purge by category, does not exist: %s"
137
+ msgstr ""
138
+
139
+ #: admin/litespeed-cache-admin-error.class.php:139
140
+ msgid "Failed to purge by tag, does not exist: %s"
141
+ msgstr ""
142
+
143
+ #: admin/litespeed-cache-admin-error.class.php:143
144
+ msgid "Invalid data in Admin IPs."
145
+ msgstr ""
146
+
147
+ #: admin/litespeed-cache-admin-error.class.php:146
148
+ msgid "Invalid data in Test IPs."
149
+ msgstr ""
150
+
151
+ #: admin/litespeed-cache-admin-error.class.php:149
152
+ msgid "Invalid Site IP: %s"
153
+ msgstr ""
154
+
155
+ #: admin/litespeed-cache-admin-error.class.php:152
156
+ msgid "Can not fetch Custom Sitemap: %s"
157
+ msgstr ""
158
+
159
+ #: admin/litespeed-cache-admin-error.class.php:155
160
+ msgid "Can not parse custom sitemap xml file: %s."
161
+ msgstr ""
162
+
163
+ #: admin/litespeed-cache-admin-error.class.php:156
164
+ msgid ""
165
+ "Please make sure the file is xml format and the %s extension is installed on "
166
+ "the server."
167
+ msgstr ""
168
+
169
+ #: admin/litespeed-cache-admin-error.class.php:161
170
+ msgid "%1$s must be an integer between %2$d and %3$d"
171
+ msgstr ""
172
+
173
+ #: admin/litespeed-cache-admin-error.class.php:166
174
+ msgid "Removed category \"%s\" from list, ID does not exist."
175
+ msgstr ""
176
+
177
+ #: admin/litespeed-cache-admin-error.class.php:171
178
+ msgid "Removed tag \"%s\" from list, ID does not exist."
179
+ msgstr ""
180
+
181
+ #: admin/litespeed-cache-admin-error.class.php:175
182
+ msgid "Invalid login cookie. Invalid characters found: %s"
183
+ msgstr ""
184
+
185
+ #: admin/litespeed-cache-admin-error.class.php:179
186
+ msgid "Invalid Rewrite List."
187
+ msgstr ""
188
+
189
+ #: admin/litespeed-cache-admin-error.class.php:180
190
+ msgid "Empty or invalid rule."
191
+ msgstr ""
192
+
193
+ #: admin/litespeed-cache-admin-error.class.php:181
194
+ msgid "Rule: %1$s, list: %2$s"
195
+ msgstr ""
196
+
197
+ #: admin/litespeed-cache-admin-error.class.php:185
198
+ msgid "Tried to parse for existing login cookie."
199
+ msgstr ""
200
+
201
+ #: admin/litespeed-cache-admin-error.class.php:186
202
+ msgid "%s file not valid. Please verify contents."
203
+ msgstr ""
204
+
205
+ #: admin/litespeed-cache-admin-error.class.php:190
206
+ msgid "Could not find %s."
207
+ msgstr ""
208
+
209
+ #: admin/litespeed-cache-admin-error.class.php:194
210
+ msgid "This site is a subdirectory install."
211
+ msgstr ""
212
+
213
+ #: admin/litespeed-cache-admin-error.class.php:195
214
+ msgid "Login cookies do not match."
215
+ msgstr ""
216
+
217
+ #: admin/litespeed-cache-admin-error.class.php:196
218
+ msgid ""
219
+ "Please remove both and set the login cookie in LiteSpeed Cache advanced "
220
+ "settings."
221
+ msgstr ""
222
+
223
+ #: admin/litespeed-cache-admin-error.class.php:200
224
+ msgid ""
225
+ "Notice: This plugin requires a LiteSpeed Server with the LSCache Module "
226
+ "enabled."
227
+ msgstr ""
228
+
229
+ #: admin/litespeed-cache-admin-error.class.php:201
230
+ msgid ""
231
+ "If you are unable to change your server stack, please contact your hosting "
232
+ "provider to request the required changes."
233
+ msgstr ""
234
+
235
+ #: admin/litespeed-cache-admin-error.class.php:202
236
+ msgid "This plugin will NOT work properly."
237
+ msgstr ""
238
+
239
+ #: admin/litespeed-cache-admin-error.class.php:205
240
+ #: admin/litespeed-cache-admin-error.class.php:243
241
+ msgid "LiteSpeed Cache was unable to write to the wp-config.php file."
242
+ msgstr ""
243
+
244
+ #: admin/litespeed-cache-admin-error.class.php:206
245
+ #: admin/litespeed-cache-admin-error.class.php:244
246
+ msgid "Please add the following to the wp-config.php file: %s"
247
+ msgstr ""
248
+
249
+ #: admin/litespeed-cache-admin-error.class.php:210
250
+ msgid "Failed to back up file, aborted changes."
251
+ msgstr ""
252
+
253
+ #: admin/litespeed-cache-admin-error.class.php:213
254
+ msgid "Failed to put contents into %s"
255
+ msgstr ""
256
+
257
+ #: admin/litespeed-cache-admin-error.class.php:216
258
+ msgid "Failed to get %s file contents."
259
+ msgstr ""
260
+
261
+ #: admin/litespeed-cache-admin-error.class.php:219
262
+ msgid "%s file not readable or not writable."
263
+ msgstr ""
264
+
265
+ #: admin/litespeed-cache-admin-error.class.php:222
266
+ msgid "%s file not readable."
267
+ msgstr ""
268
+
269
+ #: admin/litespeed-cache-admin-error.class.php:225
270
+ msgid "%s file not writable."
271
+ msgstr ""
272
+
273
+ #: admin/litespeed-cache-admin-error.class.php:228
274
+ msgid "Failed to overwrite %s."
275
+ msgstr ""
276
+
277
+ #: admin/litespeed-cache-admin-error.class.php:232
278
+ msgid "The %1$s file not writeable for %2$s"
279
+ msgstr ""
280
+
281
+ #: admin/litespeed-cache-admin-error.class.php:236
282
+ msgid "%s file did not find a place to insert define."
283
+ msgstr ""
284
+
285
+ #: admin/litespeed-cache-admin-rules.class.php:728
286
+ msgid ""
287
+ "<p>Please add/replace the following codes into the beginning of %1$s:</p> "
288
+ "%2$s"
289
+ msgstr ""
290
+
291
+ #: admin/litespeed-cache-admin-rules.class.php:863
292
+ msgid "File Saved."
293
+ msgstr ""
294
+
295
+ #: admin/litespeed-cache-admin-settings.class.php:168
296
+ msgid "Default Public Cache"
297
+ msgstr ""
298
+
299
+ #: admin/litespeed-cache-admin-settings.class.php:176
300
+ msgid "Default Front Page"
301
+ msgstr ""
302
+
303
+ #: admin/litespeed-cache-admin-settings.class.php:184
304
+ msgid "Feed"
305
+ msgstr ""
306
+
307
+ #: admin/litespeed-cache-admin-settings.class.php:195
308
+ msgid "404"
309
+ msgstr ""
310
+
311
+ #: admin/litespeed-cache-admin-settings.class.php:206
312
+ msgid "403"
313
+ msgstr ""
314
+
315
+ #: admin/litespeed-cache-admin-settings.class.php:217
316
+ msgid "500"
317
+ msgstr ""
318
+
319
+ #: admin/litespeed-cache-admin-settings.class.php:490
320
+ #: admin/tpl/settings_debug.php:79
321
+ msgid "Log File Size Limit"
322
+ msgstr ""
323
+
324
+ #: admin/litespeed-cache-admin-settings.class.php:570
325
+ #: admin/tpl/settings_crawler.php:10
326
+ msgid "Delay"
327
+ msgstr ""
328
+
329
+ #: admin/litespeed-cache-admin-settings.class.php:578
330
+ #: admin/tpl/settings_crawler.php:22
331
+ msgid "Run Duration"
332
+ msgstr ""
333
+
334
+ #: admin/litespeed-cache-admin-settings.class.php:586
335
+ msgid "Cron Interval"
336
+ msgstr ""
337
+
338
+ #: admin/litespeed-cache-admin-settings.class.php:594
339
+ msgid "Whole Interval"
340
+ msgstr ""
341
+
342
+ #: admin/litespeed-cache-admin-settings.class.php:602
343
+ #: admin/tpl/settings_crawler.php:58
344
+ msgid "Threads"
345
+ msgstr ""
346
+
347
+ #: admin/litespeed-cache-admin-settings.class.php:703
348
+ msgid "'Use primary site settings' set by Network Administrator."
349
+ msgstr ""
350
+
351
+ #: admin/litespeed-cache-admin-settings.class.php:833
352
+ msgid "File saved."
353
+ msgstr ""
354
+
355
+ #: admin/litespeed-cache-admin.class.php:203
356
+ msgid ""
357
+ "For this scenario only, the network admin may uncheck \"Check Advanced Cache"
358
+ "\" in LiteSpeed Cache settings."
359
+ msgstr ""
360
+
361
+ #: admin/litespeed-cache-admin.class.php:205
362
+ msgid ""
363
+ "For this scenario only, please uncheck \"Check Advanced Cache\" in LiteSpeed "
364
+ "Cache settings."
365
+ msgstr ""
366
+
367
+ #: admin/litespeed-cache-admin.class.php:207
368
+ msgid ""
369
+ "Please disable/deactivate any other Full Page Cache solutions that are "
370
+ "currently being used."
371
+ msgstr ""
372
+
373
+ #: admin/litespeed-cache-admin.class.php:208
374
+ msgid ""
375
+ "LiteSpeed Cache does work with other cache solutions, but only their non-"
376
+ "page caching offerings—such as minifying css/js files."
377
+ msgstr ""
378
+
379
+ #: admin/tpl/admin_footer.php:5
380
+ msgid ""
381
+ "Rate <strong>LiteSpeed Cache</strong> with %s on WordPress.org if you like "
382
+ "us!"
383
+ msgstr ""
384
+
385
+ #: admin/tpl/admin_footer.php:8
386
+ msgid ""
387
+ "If there are any questions that are not answered in the <a %s>FAQs</a>, do "
388
+ "not hesitate to ask them on the <a %s>support forum</a>."
389
+ msgstr ""
390
+
391
+ #: admin/tpl/crawler.php:14 admin/tpl/crawler.php:80
392
+ msgid "LiteSpeed Cache Crawler"
393
+ msgstr ""
394
+
395
+ #: admin/tpl/crawler.php:22
396
+ msgid "Crawler File"
397
+ msgstr ""
398
+
399
+ #: admin/tpl/crawler.php:24
400
+ msgid "Generate Crawler File"
401
+ msgstr ""
402
+
403
+ #: admin/tpl/crawler.php:29
404
+ msgid "Generated at %s"
405
+ msgstr ""
406
+
407
+ #: admin/tpl/crawler.php:33
408
+ msgid ""
409
+ "On click, this will create a crawler sitemap file in plugin directory %s."
410
+ msgstr ""
411
+
412
+ #: admin/tpl/crawler.php:43
413
+ msgid "%d hours"
414
+ msgstr ""
415
+
416
+ #: admin/tpl/crawler.php:46
417
+ msgid "%d hour"
418
+ msgstr ""
419
+
420
+ #: admin/tpl/crawler.php:53
421
+ msgid "%d minutes"
422
+ msgstr ""
423
+
424
+ #: admin/tpl/crawler.php:56
425
+ msgid "%d minute"
426
+ msgstr ""
427
+
428
+ #: admin/tpl/crawler.php:60
429
+ msgid "Crawler Cron"
430
+ msgstr ""
431
+
432
+ #: admin/tpl/crawler.php:63
433
+ msgid "WARNING"
434
+ msgstr ""
435
+
436
+ #: admin/tpl/crawler.php:64
437
+ msgid ""
438
+ "The crawler feature is not enabled on the LiteSpeed server. Please consult "
439
+ "your server admin."
440
+ msgstr ""
441
+
442
+ #: admin/tpl/crawler.php:65
443
+ msgid ""
444
+ "See <a %s>Introduction for Enabling the Crawler</a> for detailed infomation."
445
+ msgstr ""
446
+
447
+ #: admin/tpl/crawler.php:70
448
+ msgid "Cron Name"
449
+ msgstr ""
450
+
451
+ #: admin/tpl/crawler.php:71
452
+ msgid "Run Frequency"
453
+ msgstr ""
454
+
455
+ #: admin/tpl/crawler.php:72
456
+ msgid "Last Status"
457
+ msgstr ""
458
+
459
+ #: admin/tpl/crawler.php:73
460
+ msgid "Activation"
461
+ msgstr ""
462
+
463
+ #: admin/tpl/crawler.php:74
464
+ msgid "Actions"
465
+ msgstr ""
466
+
467
+ #: admin/tpl/crawler.php:88 admin/tpl/crawler.php:93
468
+ msgid "The current sitemap crawl started at %s"
469
+ msgstr ""
470
+
471
+ #: admin/tpl/crawler.php:96
472
+ msgid "The next complete sitemap crawl will start at %s"
473
+ msgstr ""
474
+
475
+ #: admin/tpl/crawler.php:110
476
+ msgid "The last complete run cost %s seconds"
477
+ msgstr ""
478
+
479
+ #: admin/tpl/crawler.php:120
480
+ msgid "Is running"
481
+ msgstr ""
482
+
483
+ #: admin/tpl/crawler.php:144
484
+ msgid "Reset position"
485
+ msgstr ""
486
+
487
+ #: admin/tpl/crawler.php:147
488
+ msgid "Manually run"
489
+ msgstr ""
490
+
491
+ #: admin/tpl/crawler.php:151
492
+ msgid "<b>Last interval:</b> %s"
493
+ msgstr ""
494
+
495
+ #: admin/tpl/crawler.php:157
496
+ msgid "<b>Ended reason:</b> %s"
497
+ msgstr ""
498
+
499
+ #: admin/tpl/crawler.php:163
500
+ msgid "<b>Last crawled:</b> %s item(s)"
501
+ msgstr ""
502
+
503
+ #: admin/tpl/crawler.php:171
504
+ msgid "Run frequency is set by the Interval Between Runs setting."
505
+ msgstr ""
506
+
507
+ #: admin/tpl/crawler.php:172
508
+ msgid "Only one crawler can run concurrently."
509
+ msgstr ""
510
+
511
+ #: admin/tpl/crawler.php:173
512
+ msgid ""
513
+ "If both the cron and manual run start at a similar time, the first one to "
514
+ "start will run."
515
+ msgstr ""
516
+
517
+ #: admin/tpl/crawler.php:174
518
+ msgid ""
519
+ "Please follow <a %s>Hooking WP-Cron Into the System Task Scheduler</a> to "
520
+ "create the system cron task."
521
+ msgstr ""
522
+
523
+ #: admin/tpl/crawler.php:179
524
+ msgid "Watch Crawler Status"
525
+ msgstr ""
526
+
527
+ #: admin/tpl/crawler.php:186
528
+ msgid "Show crawler status"
529
+ msgstr ""
530
+
531
+ #: admin/tpl/crawler.php:204
532
+ msgid "No crawler meta file generated yet"
533
+ msgstr ""
534
+
535
+ #: admin/tpl/crawler.php:209
536
+ msgid "Sitemap Generation Blacklist"
537
+ msgstr ""
538
+
539
+ #: admin/tpl/crawler.php:218 admin/tpl/edit_htaccess.php:66
540
+ msgid "Save"
541
+ msgstr ""
542
+
543
+ #: admin/tpl/crawler.php:222
544
+ msgid "Current blacklist has %s item(s)."
545
+ msgstr ""
546
+
547
+ #: admin/tpl/crawler.php:223
548
+ msgid ""
549
+ "All Urls which returned no-cache tags will be added here, after the initial "
550
+ "crawling."
551
+ msgstr ""
552
+
553
+ #: admin/tpl/debug_log.php:9
554
+ msgid "LiteSpeed Cache Debug Log Viewer"
555
+ msgstr ""
556
+
557
+ #: admin/tpl/edit_htaccess.php:31
558
+ msgid "LiteSpeed Cache Edit .htaccess"
559
+ msgstr ""
560
+
561
+ #: admin/tpl/edit_htaccess.php:40
562
+ msgid "WARNING: This page is meant for advanced users."
563
+ msgstr ""
564
+
565
+ #: admin/tpl/edit_htaccess.php:41
566
+ msgid "Any changes made to the .htaccess file may break the site."
567
+ msgstr ""
568
+
569
+ #: admin/tpl/edit_htaccess.php:42
570
+ msgid "Please consult the host/server admin before making any changes."
571
+ msgstr ""
572
+
573
+ #: admin/tpl/edit_htaccess.php:46
574
+ msgid "File editing is disabled in configuration."
575
+ msgstr ""
576
+
577
+ #: admin/tpl/edit_htaccess.php:56
578
+ msgid "Current %s contents:"
579
+ msgstr ""
580
+
581
+ #: admin/tpl/edit_htaccess.php:58
582
+ msgid "DO NOT EDIT ANYTHING WITHIN %s"
583
+ msgstr ""
584
+
585
+ #: admin/tpl/edit_htaccess.php:60
586
+ msgid ""
587
+ "These are added by the LS Cache plugin and may cause problems if they are "
588
+ "changed."
589
+ msgstr ""
590
+
591
+ #: admin/tpl/esi_widget_edit.php:28 admin/tpl/settings_esi.php:17
592
+ msgid "Enable ESI"
593
+ msgstr ""
594
+
595
+ #: admin/tpl/esi_widget_edit.php:35
596
+ msgid "Widget Cache TTL:"
597
+ msgstr ""
598
+
599
+ #: admin/tpl/esi_widget_edit.php:38 admin/tpl/settings_crawler.php:25
600
+ #: admin/tpl/settings_crawler.php:37 admin/tpl/settings_crawler.php:49
601
+ #: admin/tpl/settings_general.php:61 admin/tpl/settings_general.php:73
602
+ #: admin/tpl/settings_general.php:85 admin/tpl/settings_general.php:98
603
+ #: admin/tpl/settings_general.php:111 admin/tpl/settings_general.php:124
604
+ msgid "seconds"
605
+ msgstr ""
606
+
607
+ #: admin/tpl/esi_widget_edit.php:41
608
+ msgid "Recommended value: 28800 seconds (8 hours)."
609
+ msgstr ""
610
+
611
+ #: admin/tpl/esi_widget_edit.php:42
612
+ msgid "A TTL of 0 indicates do not cache."
613
+ msgstr ""
614
+
615
+ #: admin/tpl/help_tabs.php:7
616
+ msgid "Overview"
617
+ msgstr ""
618
+
619
+ #: admin/tpl/help_tabs.php:9
620
+ msgid "LiteSpeed Cache is a page cache built into LiteSpeed Web Server."
621
+ msgstr ""
622
+
623
+ #: admin/tpl/help_tabs.php:10
624
+ msgid ""
625
+ "This plugin communicates with LiteSpeed Web Server to let it know which "
626
+ "pages are cacheable and when to purge them."
627
+ msgstr ""
628
+
629
+ #: admin/tpl/help_tabs.php:11
630
+ msgid ""
631
+ "A LiteSpeed server (OLS, LSWS, WebADC) and its LSCache module must be "
632
+ "installed and enabled."
633
+ msgstr ""
634
+
635
+ #: admin/tpl/help_tabs.php:22
636
+ msgid "For more information:"
637
+ msgstr ""
638
+
639
+ #: admin/tpl/help_tabs.php:24
640
+ msgid "Support Forum"
641
+ msgstr ""
642
+
643
+ #: admin/tpl/info.php:5
644
+ msgid "FAQs"
645
+ msgstr ""
646
+
647
+ #: admin/tpl/info.php:6
648
+ msgid "Configuration"
649
+ msgstr ""
650
+
651
+ #: admin/tpl/info.php:7
652
+ msgid "Plugin Compatibilities"
653
+ msgstr ""
654
+
655
+ #: admin/tpl/info.php:8
656
+ msgid "Common Rewrite Rules"
657
+ msgstr ""
658
+
659
+ #: admin/tpl/info.php:9
660
+ msgid "Admin IP Commands"
661
+ msgstr ""
662
+
663
+ #: admin/tpl/info.php:16
664
+ msgid "LiteSpeed Cache Information"
665
+ msgstr ""
666
+
667
+ #: admin/tpl/info_admin_ip.php:5
668
+ msgid "This is used to display a page without caching it."
669
+ msgstr ""
670
+
671
+ #: admin/tpl/info_admin_ip.php:6
672
+ msgid ""
673
+ "An example use case is to compare a cached version of a page with an "
674
+ "uncached version."
675
+ msgstr ""
676
+
677
+ #: admin/tpl/info_admin_ip.php:9
678
+ msgid "This is used to purge most cache tags associated with the page."
679
+ msgstr ""
680
+
681
+ #: admin/tpl/info_admin_ip.php:10
682
+ msgid "The lone exception is the blog ID tag."
683
+ msgstr ""
684
+
685
+ #: admin/tpl/info_admin_ip.php:11
686
+ msgid ""
687
+ "Note that this means that pages with the same cache tag will be purged as "
688
+ "well."
689
+ msgstr ""
690
+
691
+ #: admin/tpl/info_admin_ip.php:14
692
+ msgid "This is used to show all the cache headers associated with a page."
693
+ msgstr ""
694
+
695
+ #: admin/tpl/info_admin_ip.php:15
696
+ msgid "This may be useful for debugging purposes."
697
+ msgstr ""
698
+
699
+ #: admin/tpl/info_admin_ip.php:19
700
+ msgid "Admin IP Query String Actions"
701
+ msgstr ""
702
+
703
+ #: admin/tpl/info_admin_ip.php:21
704
+ msgid ""
705
+ "The following commands are available to the admin and do not require log-in, "
706
+ "providing quick access to actions on the various pages."
707
+ msgstr ""
708
+
709
+ #: admin/tpl/info_admin_ip.php:23
710
+ msgid "Action List:"
711
+ msgstr ""
712
+
713
+ #: admin/tpl/info_admin_ip.php:28
714
+ msgid "This is used to purge the first cache tag associated with the page."
715
+ msgstr ""
716
+
717
+ #: admin/tpl/info_admin_ip.php:32
718
+ msgid ""
719
+ "To trigger the action for a page, access the page with the query string %s"
720
+ msgstr ""
721
+
722
+ #: admin/tpl/info_common_rewrite.php:8 admin/tpl/settings_excludes.php:14
723
+ #: admin/tpl/settings_excludes.php:40 admin/tpl/settings_excludes.php:70
724
+ #: admin/tpl/settings_inc.exclude_cookies.php:5
725
+ #: admin/tpl/settings_inc.exclude_useragent.php:10
726
+ msgid "NOTE:"
727
+ msgstr ""
728
+
729
+ #: admin/tpl/info_common_rewrite.php:10
730
+ msgid "The following configuration can only be changed by the network admin."
731
+ msgstr ""
732
+
733
+ #: admin/tpl/info_common_rewrite.php:11
734
+ msgid "Please contact the network admin to make any changes."
735
+ msgstr ""
736
+
737
+ #: admin/tpl/info_common_rewrite.php:14 admin/tpl/settings_advanced.php:6
738
+ #: admin/tpl/settings_inc.cache_mobile.php:64
739
+ msgid "NOTICE:"
740
+ msgstr ""
741
+
742
+ #: admin/tpl/info_common_rewrite.php:17
743
+ msgid ""
744
+ "The following rewrite rules can be configured in the LiteSpeed Cache "
745
+ "settings page."
746
+ msgstr ""
747
+
748
+ #: admin/tpl/info_common_rewrite.php:18
749
+ msgid "Please make any needed changes on that page."
750
+ msgstr ""
751
+
752
+ #: admin/tpl/info_common_rewrite.php:19
753
+ msgid "It will automatically generate the correct rules in the htaccess file."
754
+ msgstr ""
755
+
756
+ #: admin/tpl/info_common_rewrite.php:24
757
+ msgid "LiteSpeed Cache Common Rewrite Rules"
758
+ msgstr ""
759
+
760
+ #: admin/tpl/info_common_rewrite.php:31
761
+ msgid "Mobile Views:"
762
+ msgstr ""
763
+
764
+ #: admin/tpl/info_common_rewrite.php:34
765
+ msgid ""
766
+ "Some sites have adaptive views, meaning the page sent will adapt to the "
767
+ "browser type (desktop vs mobile)."
768
+ msgstr ""
769
+
770
+ #: admin/tpl/info_common_rewrite.php:35
771
+ msgid ""
772
+ "This rewrite rule is used for sites that load a different page for each type."
773
+ msgstr ""
774
+
775
+ #: admin/tpl/info_common_rewrite.php:38
776
+ msgid ""
777
+ "This configuration can be added on the settings page in the General tab."
778
+ msgstr ""
779
+
780
+ #: admin/tpl/info_common_rewrite.php:44
781
+ msgid "Do Not Cache Cookies:"
782
+ msgstr ""
783
+
784
+ #: admin/tpl/info_common_rewrite.php:46
785
+ msgid ""
786
+ "Another common rewrite rule is to notify the cache not to cache when it sees "
787
+ "a specified cookie name."
788
+ msgstr ""
789
+
790
+ #: admin/tpl/info_common_rewrite.php:47 admin/tpl/info_common_rewrite.php:55
791
+ msgid ""
792
+ "This configuration can be added on the settings page in the Do Not Cache tab."
793
+ msgstr ""
794
+
795
+ #: admin/tpl/info_common_rewrite.php:52
796
+ msgid "Do Not Cache User Agent:"
797
+ msgstr ""
798
+
799
+ #: admin/tpl/info_common_rewrite.php:54
800
+ msgid ""
801
+ "A not so commonly used rewrite rule is to notify the cache not to cache when "
802
+ "it sees a specified User Agent."
803
+ msgstr ""
804
+
805
+ #: admin/tpl/info_compatibility.php:27
806
+ msgid "LiteSpeed Cache Plugin Compatibility"
807
+ msgstr ""
808
+
809
+ #: admin/tpl/info_compatibility.php:29
810
+ msgid "Link Here"
811
+ msgstr ""
812
+
813
+ #: admin/tpl/info_compatibility.php:31
814
+ msgid ""
815
+ "Please add a comment listing the plugins that you are using and how they are "
816
+ "functioning on the support thread."
817
+ msgstr ""
818
+
819
+ #: admin/tpl/info_compatibility.php:32
820
+ msgid "With your help, we can provide the best WordPress caching solution."
821
+ msgstr ""
822
+
823
+ #: admin/tpl/info_compatibility.php:35
824
+ msgid ""
825
+ "This is a list of plugins that are confirmed to be compatible with LiteSpeed "
826
+ "Cache Plugin:"
827
+ msgstr ""
828
+
829
+ #: admin/tpl/info_compatibility.php:44
830
+ msgid "This is a list of known UNSUPPORTED plugins:"
831
+ msgstr ""
832
+
833
+ #: admin/tpl/info_config.php:4
834
+ msgid "LiteSpeed Cache Configuration"
835
+ msgstr ""
836
+
837
+ #: admin/tpl/info_config.php:7
838
+ msgid "Instructions for LiteSpeed Web Server Enterprise"
839
+ msgstr ""
840
+
841
+ #: admin/tpl/info_config.php:9
842
+ msgid "Make sure that the server license has the LSCache module enabled."
843
+ msgstr ""
844
+
845
+ #: admin/tpl/info_config.php:10
846
+ msgid ""
847
+ "A <a %s>2-CPU trial license with LSCache module</a> is available for free "
848
+ "for %d days."
849
+ msgstr ""
850
+
851
+ #: admin/tpl/info_config.php:14
852
+ msgid "The server must be configured to have caching enabled."
853
+ msgstr ""
854
+
855
+ #: admin/tpl/info_config.php:15
856
+ msgid "If you are the server admin, <a %s>click here.</a>"
857
+ msgstr ""
858
+
859
+ #: admin/tpl/info_config.php:17
860
+ msgid ""
861
+ "Otherwise request that the server admin configure the cache root for the "
862
+ "server."
863
+ msgstr ""
864
+
865
+ #: admin/tpl/info_config.php:20
866
+ msgid ""
867
+ "In the .htaccess file for the WordPress installation, add the following:"
868
+ msgstr ""
869
+
870
+ #: admin/tpl/info_config.php:27
871
+ msgid "Instructions for OpenLiteSpeed"
872
+ msgstr ""
873
+
874
+ #: admin/tpl/info_config.php:28
875
+ msgid "This integration utilizes OLS's cache module."
876
+ msgstr ""
877
+
878
+ #: admin/tpl/info_config.php:30
879
+ msgid ""
880
+ "If it is a fresh OLS installation, the easiest way to integrate is to use <a "
881
+ "%s>ols1clk.</a>"
882
+ msgstr ""
883
+
884
+ #: admin/tpl/info_config.php:32
885
+ msgid "If using an existing WordPress installation, use the %s parameter."
886
+ msgstr ""
887
+
888
+ #: admin/tpl/info_config.php:33
889
+ msgid ""
890
+ "Else if OLS and WordPress are already installed, please follow the "
891
+ "instructions <a %s>here.</a>"
892
+ msgstr ""
893
+
894
+ #: admin/tpl/info_config.php:38
895
+ msgid "How to test the plugin"
896
+ msgstr ""
897
+
898
+ #: admin/tpl/info_config.php:39
899
+ msgid ""
900
+ "The LiteSpeed Cache Plugin utilizes LiteSpeed specific response headers."
901
+ msgstr ""
902
+
903
+ #: admin/tpl/info_config.php:41
904
+ msgid ""
905
+ "Visiting a page for the first time should result in a %s or %s response "
906
+ "header for the page."
907
+ msgstr ""
908
+
909
+ #: admin/tpl/info_config.php:46
910
+ msgid ""
911
+ "Subsequent requests should have the %s response header until the page is "
912
+ "updated, expired, or purged."
913
+ msgstr ""
914
+
915
+ #: admin/tpl/info_config.php:49
916
+ msgid "Please visit <a %s>this page</a> for more information."
917
+ msgstr ""
918
+
919
+ #: admin/tpl/info_config.php:53
920
+ msgid "Cache tag prefix setting"
921
+ msgstr ""
922
+
923
+ #: admin/tpl/info_config.php:56
924
+ msgid ""
925
+ "The value of this wordpress cache tag prefix is %1$s. If you want to change "
926
+ "the value to avoid conflicts with multiple sites, please add %2$s to %3$s."
927
+ msgstr ""
928
+
929
+ #: admin/tpl/info_crawler.php:7
930
+ msgid "Crawler Introduction"
931
+ msgstr ""
932
+
933
+ #: admin/tpl/info_crawler.php:11
934
+ msgid "How Does the Crawler Work?"
935
+ msgstr ""
936
+
937
+ #: admin/tpl/info_crawler.php:13
938
+ msgid ""
939
+ "Using a sitemap as a guide, LSCache’s crawler, travels its way throughout "
940
+ "the backend, refreshing pages that have expired in the cache. The purpose is "
941
+ "to keep the cache as fresh as possible while minimizing visitor exposure to "
942
+ "uncached content."
943
+ msgstr ""
944
+
945
+ #: admin/tpl/info_crawler.php:15
946
+ msgid ""
947
+ "The sitemap can be generated by the crawler, or you can provide your own "
948
+ "custom map."
949
+ msgstr ""
950
+
951
+ #: admin/tpl/info_crawler.php:17
952
+ msgid ""
953
+ "To learn more about each of the crawler settings, see <a %s>our wiki - "
954
+ "Crawler Settings</a>."
955
+ msgstr ""
956
+
957
+ #: admin/tpl/info_crawler.php:21
958
+ msgid "Should I Enable the Crawler?"
959
+ msgstr ""
960
+
961
+ #: admin/tpl/info_crawler.php:23
962
+ msgid "Not every site needs a crawler."
963
+ msgstr ""
964
+
965
+ #: admin/tpl/info_crawler.php:25
966
+ msgid ""
967
+ "In WordPress, the first visitor to an uncached page waits for the page to "
968
+ "be dynamically-generated and served, and the page is then cached for "
969
+ "subsequent visitors."
970
+ msgstr ""
971
+
972
+ #: admin/tpl/info_crawler.php:27
973
+ msgid ""
974
+ "The LSCache crawler makes the first visitor’s experience better by "
975
+ "essentially becoming the first visitor. The crawler caches the page, and the "
976
+ "visitor who would have been first is spared the wait. As such, the crawler "
977
+ "realistically only benefits the first out of the many users who visit that "
978
+ "page before it expires. If you have a small user base, then crawling impacts "
979
+ "a greater percentage of your visitors than it would on a site that draws a "
980
+ "large crowd."
981
+ msgstr ""
982
+
983
+ #: admin/tpl/info_crawler.php:29
984
+ msgid ""
985
+ "You should weigh this benefit against your server’s resources. If resources "
986
+ "are plentiful, then the crawler is a nice thing to have."
987
+ msgstr ""
988
+
989
+ #: admin/tpl/info_crawler.php:31
990
+ msgid ""
991
+ "If your site is busy, you’ll find that commonly-visited pages are quickly re-"
992
+ "cached by new visitors, without the aid of a crawler. An extra crawler task "
993
+ "would compete for server resources while delivering minimal benefits."
994
+ msgstr ""
995
+
996
+ #: admin/tpl/info_crawler.php:33
997
+ msgid ""
998
+ "The decision to use a crawler depends on the busy-ness of the site and the "
999
+ "availability of server resources. Ultimately, it is the hosting provider who "
1000
+ "can best make this call."
1001
+ msgstr ""
1002
+
1003
+ #: admin/tpl/info_crawler.php:38
1004
+ msgid "Enabling the Crawler"
1005
+ msgstr ""
1006
+
1007
+ #: admin/tpl/info_crawler.php:40
1008
+ msgid ""
1009
+ "Due to the potential of the crawler to consume considerable resources, we "
1010
+ "have put the on/off switch in the hands of the server administrators. The "
1011
+ "crawler is disabled by default and can only be enabled by an admin."
1012
+ msgstr ""
1013
+
1014
+ #: admin/tpl/info_crawler.php:42
1015
+ msgid ""
1016
+ "Instructions for enabling the crawler can be found in <a %s>our wiki - "
1017
+ "Enabling the Crawler</a>. If you do not have access to server configuration "
1018
+ "files or virtual host include files, you will need to ask your web host for "
1019
+ "assistance."
1020
+ msgstr ""
1021
+
1022
+ #: admin/tpl/info_crawler.php:47
1023
+ msgid "Testing the Crawler"
1024
+ msgstr ""
1025
+
1026
+ #: admin/tpl/info_crawler.php:49
1027
+ msgid ""
1028
+ "To determine whether the crawler is working as expected, you can test it "
1029
+ "with a single URL."
1030
+ msgstr ""
1031
+
1032
+ #: admin/tpl/info_crawler.php:53
1033
+ msgid "Pick a URL from your sitemap and purge it:"
1034
+ msgstr ""
1035
+
1036
+ #: admin/tpl/info_crawler.php:54
1037
+ msgid ""
1038
+ "Navigate to <b>LiteSpeed Cache > Manage > Purge By… > URL</b> and enter the "
1039
+ "full URL in the text box."
1040
+ msgstr ""
1041
+
1042
+ #: admin/tpl/info_crawler.php:57
1043
+ msgid "Manually run the crawler:"
1044
+ msgstr ""
1045
+
1046
+ #: admin/tpl/info_crawler.php:58
1047
+ msgid ""
1048
+ "Navigate to <b>LiteSpeed Cache > Crawler</b>, make sure <b>Activation</b> is "
1049
+ "set to Enable, and press the <b>Manually run</b> button. Wait for it to "
1050
+ "finish."
1051
+ msgstr ""
1052
+
1053
+ #: admin/tpl/info_crawler.php:61
1054
+ msgid "See if the purged URL was cached during the crawl:"
1055
+ msgstr ""
1056
+
1057
+ #: admin/tpl/info_crawler.php:62
1058
+ msgid ""
1059
+ "Turn on your browser’s Developer Tool/Inspector. Visit the URL that should "
1060
+ "have been crawled. Select the <b>Network</b> tab in the inspector, select "
1061
+ "the page request (the URL we just visited - it should be the first entry in "
1062
+ "the list), and select the <b>Header</b> tab. If the URL was crawled "
1063
+ "correctly, you will see the response header X-LiteSpeed-Cache: hit."
1064
+ msgstr ""
1065
+
1066
+ #: admin/tpl/info_crawler.php:67
1067
+ msgid ""
1068
+ "If you don’t see X-LiteSpeed-Cache: hit, and you can’t figure out why the "
1069
+ "crawler didn’t cache the purged URL, you can visit <a %s>our support forum</"
1070
+ "a> for help."
1071
+ msgstr ""
1072
+
1073
+ #: admin/tpl/info_faqs.php:5
1074
+ msgid "LiteSpeed Cache FAQs"
1075
+ msgstr ""
1076
+
1077
+ #: admin/tpl/info_faqs.php:9
1078
+ msgid "Is the LiteSpeed Cache Plugin for WordPress free?"
1079
+ msgstr ""
1080
+
1081
+ #: admin/tpl/info_faqs.php:12
1082
+ msgid "Yes, the plugin itself will remain free and open source."
1083
+ msgstr ""
1084
+
1085
+ #: admin/tpl/info_faqs.php:13
1086
+ msgid "That said, a LiteSpeed server is required (see question 2)"
1087
+ msgstr ""
1088
+
1089
+ #: admin/tpl/info_faqs.php:17
1090
+ msgid "What server software is required for this plugin?"
1091
+ msgstr ""
1092
+
1093
+ #: admin/tpl/info_faqs.php:19
1094
+ msgid "A LiteSpeed server is required in order to use this plugin."
1095
+ msgstr ""
1096
+
1097
+ #: admin/tpl/info_faqs.php:25
1098
+ msgid "Any single server or cluster including a LiteSpeed server will work."
1099
+ msgstr ""
1100
+
1101
+ #: admin/tpl/info_faqs.php:28
1102
+ msgid "Does this plugin work in a clustered environment?"
1103
+ msgstr ""
1104
+
1105
+ #: admin/tpl/info_faqs.php:31
1106
+ msgid "The cache entries are stored at the litespeed server level."
1107
+ msgstr ""
1108
+
1109
+ #: admin/tpl/info_faqs.php:32
1110
+ msgid ""
1111
+ "The simplest solution is to use LiteSpeed WebADC, as the cache entries will "
1112
+ "be cached at that level."
1113
+ msgstr ""
1114
+
1115
+ #: admin/tpl/info_faqs.php:35
1116
+ msgid ""
1117
+ "If using another load balancer, the cache entries will only be stored at the "
1118
+ "backend nodes, not at the load balancer."
1119
+ msgstr ""
1120
+
1121
+ #: admin/tpl/info_faqs.php:36
1122
+ msgid ""
1123
+ "The purges will also not be synchronized across the nodes, so this is not "
1124
+ "recommended."
1125
+ msgstr ""
1126
+
1127
+ #: admin/tpl/info_faqs.php:39
1128
+ msgid "If a customized solution is required, please contact %s at %s"
1129
+ msgstr ""
1130
+
1131
+ #: admin/tpl/info_faqs.php:42
1132
+ msgid ""
1133
+ "NOTICE: The rewrite rules created by this plugin must be copied to the WebADC"
1134
+ msgstr ""
1135
+
1136
+ #: admin/tpl/info_faqs.php:45
1137
+ msgid "Where are the cache entries stored?"
1138
+ msgstr ""
1139
+
1140
+ #: admin/tpl/info_faqs.php:47
1141
+ msgid ""
1142
+ "The actual cached pages are stored and managed by LiteSpeed Servers. Nothing "
1143
+ "is stored on the PHP side."
1144
+ msgstr ""
1145
+
1146
+ #: admin/tpl/info_faqs.php:50
1147
+ msgid "Is WooCommerce supported?"
1148
+ msgstr ""
1149
+
1150
+ #: admin/tpl/info_faqs.php:53
1151
+ msgid "In short, yes."
1152
+ msgstr ""
1153
+
1154
+ #: admin/tpl/info_faqs.php:54
1155
+ msgid ""
1156
+ "However, for some woocommerce themes, the cart may not be updated correctly."
1157
+ msgstr ""
1158
+
1159
+ #: admin/tpl/info_faqs.php:56
1160
+ msgid "To test the cart:"
1161
+ msgstr ""
1162
+
1163
+ #: admin/tpl/info_faqs.php:58
1164
+ msgid ""
1165
+ "On a non-logged-in browser, visit and cache a page, then visit and cache a "
1166
+ "product page."
1167
+ msgstr ""
1168
+
1169
+ #: admin/tpl/info_faqs.php:59
1170
+ msgid ""
1171
+ "The first page should be accessible from the product page (e.g. the shop)."
1172
+ msgstr ""
1173
+
1174
+ #: admin/tpl/info_faqs.php:60
1175
+ msgid "Once both pages are confirmed cached, add the product to the cart."
1176
+ msgstr ""
1177
+
1178
+ #: admin/tpl/info_faqs.php:61
1179
+ msgid "After adding to the cart, visit the first page."
1180
+ msgstr ""
1181
+
1182
+ #: admin/tpl/info_faqs.php:62
1183
+ msgid "The page should still be cached, and the cart should be up to date."
1184
+ msgstr ""
1185
+
1186
+ #: admin/tpl/info_faqs.php:63
1187
+ msgid ""
1188
+ "If that is not the case, please add woocommerce_items_in_cart to the do not "
1189
+ "cache cookie list."
1190
+ msgstr ""
1191
+
1192
+ #: admin/tpl/info_faqs.php:66
1193
+ msgid ""
1194
+ "Some themes like Storefront and Shop Isle are built such that the cart works "
1195
+ "without the rule."
1196
+ msgstr ""
1197
+
1198
+ #: admin/tpl/info_faqs.php:67
1199
+ msgid ""
1200
+ "However, other themes like the E-Commerce theme, do not, so please verify "
1201
+ "the theme used."
1202
+ msgstr ""
1203
+
1204
+ #: admin/tpl/info_faqs.php:71
1205
+ msgid "Are my images optimized?"
1206
+ msgstr ""
1207
+
1208
+ #: admin/tpl/info_faqs.php:74
1209
+ msgid "The cache plugin does not do anything with the images themselves."
1210
+ msgstr ""
1211
+
1212
+ #: admin/tpl/info_faqs.php:75
1213
+ msgid ""
1214
+ "We recommend you trying an image optimization plugin like %s to optimize "
1215
+ "your images."
1216
+ msgstr ""
1217
+
1218
+ #: admin/tpl/info_faqs.php:77
1219
+ msgid "It can reduce your site's images up to 90%."
1220
+ msgstr ""
1221
+
1222
+ #: admin/tpl/info_faqs.php:81
1223
+ msgid "How do I get WP-PostViews to display an updating view count?"
1224
+ msgstr ""
1225
+
1226
+ #: admin/tpl/info_faqs.php:84
1227
+ msgid "Use %1$s to replace %2$s"
1228
+ msgstr ""
1229
+
1230
+ #: admin/tpl/info_faqs.php:88
1231
+ msgid ""
1232
+ "NOTE: The id can be changed, but the div id and the ajax function must match."
1233
+ msgstr ""
1234
+
1235
+ #: admin/tpl/info_faqs.php:91
1236
+ msgid "Replace the ajax query in %1$s with %2$s"
1237
+ msgstr ""
1238
+
1239
+ #: admin/tpl/info_faqs.php:106
1240
+ msgid "Purge the cache to use the updated pages."
1241
+ msgstr ""
1242
+
1243
+ #: admin/tpl/manage.php:10
1244
+ msgid "LiteSpeed Cache Management"
1245
+ msgstr ""
1246
+
1247
+ #: admin/tpl/manage.php:18
1248
+ msgid ""
1249
+ "From this screen, one can inform the server to purge the selected cached "
1250
+ "pages or empty the entire cache."
1251
+ msgstr ""
1252
+
1253
+ #: admin/tpl/manage.php:23
1254
+ msgid "Purge the Front Page."
1255
+ msgstr ""
1256
+
1257
+ #: admin/tpl/manage.php:26
1258
+ msgid "Purge Front Page"
1259
+ msgstr ""
1260
+
1261
+ #: admin/tpl/manage.php:29
1262
+ msgid "This will Purge Front Page only"
1263
+ msgstr ""
1264
+
1265
+ #: admin/tpl/manage.php:35
1266
+ msgid "Purge Pages."
1267
+ msgstr ""
1268
+
1269
+ #: admin/tpl/manage.php:38
1270
+ msgid "Purge Pages"
1271
+ msgstr ""
1272
+
1273
+ #: admin/tpl/manage.php:41
1274
+ msgid "This will Purge Pages only"
1275
+ msgstr ""
1276
+
1277
+ #: admin/tpl/manage.php:47
1278
+ msgid "Purge the error pages."
1279
+ msgstr ""
1280
+
1281
+ #: admin/tpl/manage.php:53
1282
+ msgid "Include 403"
1283
+ msgstr ""
1284
+
1285
+ #: admin/tpl/manage.php:54
1286
+ msgid "Include 404"
1287
+ msgstr ""
1288
+
1289
+ #: admin/tpl/manage.php:55
1290
+ msgid "Include 500s"
1291
+ msgstr ""
1292
+
1293
+ #: admin/tpl/manage.php:60
1294
+ msgid "Purge Error Pages"
1295
+ msgstr ""
1296
+
1297
+ #: admin/tpl/manage.php:65
1298
+ msgid "Purges the error page cache entries created by this plugin."
1299
+ msgstr ""
1300
+
1301
+ #: admin/tpl/manage.php:72
1302
+ msgid "Purge all WordPress pages."
1303
+ msgstr ""
1304
+
1305
+ #: admin/tpl/manage.php:76
1306
+ msgid "This will purge everything for all blogs."
1307
+ msgstr ""
1308
+
1309
+ #: admin/tpl/manage.php:76 admin/tpl/manage.php:78
1310
+ msgid "Are you sure you want to purge all?"
1311
+ msgstr ""
1312
+
1313
+ #: admin/tpl/manage.php:81
1314
+ msgid "Purge All"
1315
+ msgstr ""
1316
+
1317
+ #: admin/tpl/manage.php:84
1318
+ msgid "Purge the cache entries created by this plugin."
1319
+ msgstr ""
1320
+
1321
+ #: admin/tpl/manage.php:91
1322
+ msgid "Clear all cache entries."
1323
+ msgstr ""
1324
+
1325
+ #: admin/tpl/manage.php:94
1326
+ msgid "This will clear EVERYTHING inside the cache."
1327
+ msgstr ""
1328
+
1329
+ #: admin/tpl/manage.php:95
1330
+ msgid "This may cause heavy load on the server."
1331
+ msgstr ""
1332
+
1333
+ #: admin/tpl/manage.php:96
1334
+ msgid "If only the WordPress site should be purged, use purge all."
1335
+ msgstr ""
1336
+
1337
+ #: admin/tpl/manage.php:98
1338
+ msgid "Empty Entire Cache"
1339
+ msgstr ""
1340
+
1341
+ #: admin/tpl/manage.php:101
1342
+ msgid ""
1343
+ "Clears all cache entries related to this site, <i>including other web "
1344
+ "applications</i>."
1345
+ msgstr ""
1346
+
1347
+ #: admin/tpl/manage.php:102
1348
+ msgid ""
1349
+ "<b>This action should only be used if things are cached incorrectly.</b>"
1350
+ msgstr ""
1351
+
1352
+ #: admin/tpl/manage.php:111
1353
+ msgid "Purge By..."
1354
+ msgstr ""
1355
+
1356
+ #: admin/tpl/manage.php:114
1357
+ msgid "Select below for \"Purge by\" options."
1358
+ msgstr ""
1359
+
1360
+ #: admin/tpl/manage.php:115
1361
+ msgid "Please enter one per line."
1362
+ msgstr ""
1363
+
1364
+ #: admin/tpl/manage.php:142
1365
+ msgid "Category"
1366
+ msgstr ""
1367
+
1368
+ #: admin/tpl/manage.php:148
1369
+ msgid "Post ID"
1370
+ msgstr ""
1371
+
1372
+ #: admin/tpl/manage.php:154
1373
+ msgid "Tag"
1374
+ msgstr ""
1375
+
1376
+ #: admin/tpl/manage.php:160
1377
+ msgid "URL"
1378
+ msgstr ""
1379
+
1380
+ #: admin/tpl/manage.php:166
1381
+ msgid ""
1382
+ "Purge pages by category name - e.g. %2$s should be used for the URL %1$s."
1383
+ msgstr ""
1384
+
1385
+ #: admin/tpl/manage.php:171
1386
+ msgid "Purge pages by post ID."
1387
+ msgstr ""
1388
+
1389
+ #: admin/tpl/manage.php:175
1390
+ msgid "Purge pages by tag name - e.g. %2$s should be used for the URL %1$s."
1391
+ msgstr ""
1392
+
1393
+ #: admin/tpl/manage.php:180
1394
+ msgid "Purge pages by relative or full URL."
1395
+ msgstr ""
1396
+
1397
+ #: admin/tpl/manage.php:181
1398
+ msgid "e.g. Use %s or %s."
1399
+ msgstr ""
1400
+
1401
+ #: admin/tpl/manage.php:194
1402
+ msgid "Purge List"
1403
+ msgstr ""
1404
+
1405
+ #: admin/tpl/network_settings.php:5 admin/tpl/settings.php:7
1406
+ #: admin/tpl/settings_general.php:5
1407
+ msgid "General"
1408
+ msgstr ""
1409
+
1410
+ #: admin/tpl/network_settings.php:6 admin/tpl/settings.php:8
1411
+ msgid "Cache"
1412
+ msgstr ""
1413
+
1414
+ #: admin/tpl/network_settings.php:7 admin/tpl/settings.php:9
1415
+ msgid "Purge"
1416
+ msgstr ""
1417
+
1418
+ #: admin/tpl/network_settings.php:8 admin/tpl/settings.php:10
1419
+ msgid "Excludes"
1420
+ msgstr ""
1421
+
1422
+ #: admin/tpl/network_settings.php:9 admin/tpl/settings.php:18
1423
+ #: admin/tpl/settings_debug.php:68
1424
+ msgid "Advanced"
1425
+ msgstr ""
1426
+
1427
+ #: admin/tpl/network_settings.php:19
1428
+ msgid "LiteSpeed Cache Network Settings"
1429
+ msgstr ""
1430
+
1431
+ #: admin/tpl/network_settings_cache.php:4
1432
+ msgid "Cache Control Network Settings"
1433
+ msgstr ""
1434
+
1435
+ #: admin/tpl/network_settings_cache.php:7
1436
+ msgid ""
1437
+ "Separate Mobile Views should be enabled if any of the network enabled themes "
1438
+ "require a different view for mobile devices."
1439
+ msgstr ""
1440
+
1441
+ #: admin/tpl/network_settings_cache.php:8
1442
+ msgid "Responsive themes can handle this part automatically."
1443
+ msgstr ""
1444
+
1445
+ #: admin/tpl/network_settings_excludes.php:5
1446
+ msgid "Network Do Not Cache Rules"
1447
+ msgstr ""
1448
+
1449
+ #: admin/tpl/network_settings_general.php:5
1450
+ msgid "General Network Configuration"
1451
+ msgstr ""
1452
+
1453
+ #: admin/tpl/network_settings_general.php:7
1454
+ msgid "These configuration are only available network wide."
1455
+ msgstr ""
1456
+
1457
+ #: admin/tpl/network_settings_general.php:11
1458
+ msgid "Network Enable Cache"
1459
+ msgstr ""
1460
+
1461
+ #: admin/tpl/network_settings_general.php:15
1462
+ msgid ""
1463
+ "Enabling LiteSpeed Cache for WordPress here enables the cache for the "
1464
+ "network."
1465
+ msgstr ""
1466
+
1467
+ #: admin/tpl/network_settings_general.php:16
1468
+ msgid ""
1469
+ "It is <b>STRONGLY</b> recommend that the compatibility with other plugins on "
1470
+ "a single/few sites is tested first."
1471
+ msgstr ""
1472
+
1473
+ #: admin/tpl/network_settings_general.php:17
1474
+ msgid ""
1475
+ "This is to ensure compatibility prior to enabling the cache for all sites."
1476
+ msgstr ""
1477
+
1478
+ #: admin/tpl/network_settings_general.php:23
1479
+ msgid "Use Primary Site Configuration"
1480
+ msgstr ""
1481
+
1482
+ #: admin/tpl/network_settings_general.php:27
1483
+ msgid ""
1484
+ "Check this option to use the primary site's configuration for all subsites."
1485
+ msgstr ""
1486
+
1487
+ #: admin/tpl/network_settings_general.php:28
1488
+ msgid "This will disable the settings page on all subsites."
1489
+ msgstr ""
1490
+
1491
+ #: admin/tpl/network_settings_purge.php:4
1492
+ msgid "Purge Network Settings"
1493
+ msgstr ""
1494
+
1495
+ #: admin/tpl/report.php:9
1496
+ msgid "LiteSpeed Cache Report"
1497
+ msgstr ""
1498
+
1499
+ #: admin/tpl/report.php:18
1500
+ msgid ""
1501
+ "The environment report contains detailed information about the WordPress "
1502
+ "configuration."
1503
+ msgstr ""
1504
+
1505
+ #: admin/tpl/report.php:19
1506
+ msgid ""
1507
+ "If you run into any issues, please include the contents of this text area in "
1508
+ "your support message."
1509
+ msgstr ""
1510
+
1511
+ #: admin/tpl/report.php:20
1512
+ msgid ""
1513
+ "To easily grab the content, click the <b>Select All and Copy to Clipboard</"
1514
+ "b> button, to select and copy to clipboard."
1515
+ msgstr ""
1516
+
1517
+ #: admin/tpl/report.php:22
1518
+ msgid "Alternatively, this information is also saved in %s."
1519
+ msgstr ""
1520
+
1521
+ #: admin/tpl/report.php:27
1522
+ msgid "The text area below contains the following content:"
1523
+ msgstr ""
1524
+
1525
+ #: admin/tpl/report.php:31
1526
+ msgid ""
1527
+ "Server Variables, Plugin Options, WordPress information (version, locale, "
1528
+ "active plugins, etc.), and .htaccess file content."
1529
+ msgstr ""
1530
+
1531
+ #: admin/tpl/report.php:36
1532
+ msgid "Select All and Copy to Clipboard"
1533
+ msgstr ""
1534
+
1535
+ #: admin/tpl/report.php:39
1536
+ msgid "Environment Report copied to Clipboard!"
1537
+ msgstr ""
1538
+
1539
+ #: admin/tpl/settings.php:14
1540
+ msgid "ESI"
1541
+ msgstr ""
1542
+
1543
+ #: admin/tpl/settings.php:21
1544
+ msgid "Debug"
1545
+ msgstr ""
1546
+
1547
+ #: admin/tpl/settings.php:24
1548
+ msgid "Compatibilities"
1549
+ msgstr ""
1550
+
1551
+ #: admin/tpl/settings.php:65
1552
+ msgid "WARNING: Third party tab input invalid."
1553
+ msgstr ""
1554
+
1555
+ #: admin/tpl/settings.php:72
1556
+ msgid "WARNING: Third party config slug contains invalid characters."
1557
+ msgstr ""
1558
+
1559
+ #: admin/tpl/settings.php:87
1560
+ msgid "LiteSpeed Cache Settings"
1561
+ msgstr ""
1562
+
1563
+ #: admin/tpl/settings.php:110
1564
+ msgid "The network admin selected use primary site configs for all subsites."
1565
+ msgstr ""
1566
+
1567
+ #: admin/tpl/settings.php:111
1568
+ msgid ""
1569
+ "The following options are selected, but are not editable in this settings "
1570
+ "page."
1571
+ msgstr ""
1572
+
1573
+ #: admin/tpl/settings.php:132 admin/tpl/settings.php:135
1574
+ msgid "Save Changes"
1575
+ msgstr ""
1576
+
1577
+ #: admin/tpl/settings_advanced.php:8
1578
+ msgid "These settings are meant for ADVANCED USERS ONLY."
1579
+ msgstr ""
1580
+
1581
+ #: admin/tpl/settings_advanced.php:9
1582
+ msgid "Please take great care when changing any of these settings."
1583
+ msgstr ""
1584
+
1585
+ #: admin/tpl/settings_advanced.php:10
1586
+ msgid "If there are any questions, do not hesitate to submit a support thread."
1587
+ msgstr ""
1588
+
1589
+ #: admin/tpl/settings_advanced.php:14
1590
+ msgid "Check Advanced Cache"
1591
+ msgstr ""
1592
+
1593
+ #: admin/tpl/settings_advanced.php:17
1594
+ msgid "Include advanced-cache.php"
1595
+ msgstr ""
1596
+
1597
+ #: admin/tpl/settings_advanced.php:20
1598
+ msgid ""
1599
+ "The advanced-cache.php file is used by many caching plugins to signal that a "
1600
+ "cache is active."
1601
+ msgstr ""
1602
+
1603
+ #: admin/tpl/settings_advanced.php:21
1604
+ msgid ""
1605
+ "When this option is checked and this file is detected as belonging to "
1606
+ "another plugin, LiteSpeed Cache will not cache."
1607
+ msgstr ""
1608
+
1609
+ #: admin/tpl/settings_advanced.php:24
1610
+ msgid ""
1611
+ "Uncheck this option only if the other plugin is used for non-caching "
1612
+ "purposes, such as minifying css/js files."
1613
+ msgstr ""
1614
+
1615
+ #: admin/tpl/settings_advanced.php:27
1616
+ msgid "Login Cookie"
1617
+ msgstr ""
1618
+
1619
+ #: admin/tpl/settings_advanced.php:30
1620
+ msgid "SYNTAX: alphanumeric and \"_\"."
1621
+ msgstr ""
1622
+
1623
+ #: admin/tpl/settings_advanced.php:31
1624
+ msgid "No spaces and case sensitive."
1625
+ msgstr ""
1626
+
1627
+ #: admin/tpl/settings_advanced.php:32
1628
+ msgid "MUST BE UNIQUE FROM OTHER WEB APPLICATIONS."
1629
+ msgstr ""
1630
+
1631
+ #: admin/tpl/settings_advanced.php:34
1632
+ msgid "The default login cookie is %s."
1633
+ msgstr ""
1634
+
1635
+ #: admin/tpl/settings_advanced.php:35
1636
+ msgid ""
1637
+ "The server will determine if the user is logged in based on the existance of "
1638
+ "this cookie."
1639
+ msgstr ""
1640
+
1641
+ #: admin/tpl/settings_advanced.php:36
1642
+ msgid ""
1643
+ "This setting is useful for those that have multiple web applications for the "
1644
+ "same domain."
1645
+ msgstr ""
1646
+
1647
+ #: admin/tpl/settings_advanced.php:37
1648
+ msgid ""
1649
+ "If every web application uses the same cookie, the server may confuse "
1650
+ "whether a user is logged in or not."
1651
+ msgstr ""
1652
+
1653
+ #: admin/tpl/settings_advanced.php:38
1654
+ msgid "The cookie set here will be used for this WordPress installation."
1655
+ msgstr ""
1656
+
1657
+ #: admin/tpl/settings_advanced.php:41
1658
+ msgid "Example use case:"
1659
+ msgstr ""
1660
+
1661
+ #: admin/tpl/settings_advanced.php:43
1662
+ msgid "There is a WordPress installed for %s."
1663
+ msgstr ""
1664
+
1665
+ #: admin/tpl/settings_advanced.php:45
1666
+ msgid "Then another WordPress is installed (NOT MULTISITE) at %s"
1667
+ msgstr ""
1668
+
1669
+ #: admin/tpl/settings_advanced.php:46
1670
+ msgid ""
1671
+ "The cache needs to distinguish who is logged into which WordPress site in "
1672
+ "order to cache correctly."
1673
+ msgstr ""
1674
+
1675
+ #: admin/tpl/settings_advanced.php:52
1676
+ msgid "Error: invalid login cookie. Please check the %s file"
1677
+ msgstr ""
1678
+
1679
+ #: admin/tpl/settings_advanced.php:61
1680
+ msgid "Error getting current rules from %s: %s"
1681
+ msgstr ""
1682
+
1683
+ #: admin/tpl/settings_advanced.php:69
1684
+ msgid ""
1685
+ "WARNING: The .htaccess login cookie and Database login cookie do not match."
1686
+ msgstr ""
1687
+
1688
+ #: admin/tpl/settings_cache.php:4
1689
+ msgid "Cache Control Settings"
1690
+ msgstr ""
1691
+
1692
+ #: admin/tpl/settings_cache.php:8
1693
+ msgid "Cache Logged-in Users"
1694
+ msgstr ""
1695
+
1696
+ #: admin/tpl/settings_cache.php:12
1697
+ msgid "Privately cache frontend pages for logged-in users. (LSWS %s required)"
1698
+ msgstr ""
1699
+
1700
+ #: admin/tpl/settings_cache.php:18
1701
+ msgid "Cache Commenters"
1702
+ msgstr ""
1703
+
1704
+ #: admin/tpl/settings_cache.php:22
1705
+ msgid ""
1706
+ "Privately cache commenters that have pending comments. Disabling this option "
1707
+ "will serve non-cacheable pages to commenters. (LSWS %s required)"
1708
+ msgstr ""
1709
+
1710
+ #: admin/tpl/settings_cache.php:28
1711
+ msgid "Cache REST API"
1712
+ msgstr ""
1713
+
1714
+ #: admin/tpl/settings_cache.php:32
1715
+ msgid "Cache requests made by WordPress REST API calls."
1716
+ msgstr ""
1717
+
1718
+ #: admin/tpl/settings_cache.php:38
1719
+ msgid "Cache Login Page"
1720
+ msgstr ""
1721
+
1722
+ #: admin/tpl/settings_cache.php:42
1723
+ msgid "Disabling this option may negatively affect performance."
1724
+ msgstr ""
1725
+
1726
+ #: admin/tpl/settings_compatibilities.php:7
1727
+ msgid "Compatibility with WP-PostViews"
1728
+ msgstr ""
1729
+
1730
+ #: admin/tpl/settings_compatibilities.php:9
1731
+ msgid "To make LiteSpeed Cache compatible with WP-PostViews:"
1732
+ msgstr ""
1733
+
1734
+ #: admin/tpl/settings_compatibilities.php:13
1735
+ msgid ""
1736
+ "Replace the following calls in the active theme's template files with a div "
1737
+ "or span with a unique ID."
1738
+ msgstr ""
1739
+
1740
+ #: admin/tpl/settings_compatibilities.php:14
1741
+ msgid "e.g. Replace <br> <pre>%1$s</pre> with<br> <pre>%2$s</pre>"
1742
+ msgstr ""
1743
+
1744
+ #: admin/tpl/settings_compatibilities.php:21
1745
+ msgid "Update the ajax request to output the results to that div."
1746
+ msgstr ""
1747
+
1748
+ #: admin/tpl/settings_compatibilities.php:22
1749
+ msgid "Example:"
1750
+ msgstr ""
1751
+
1752
+ #: admin/tpl/settings_compatibilities.php:34
1753
+ msgid "The ajax code can be found at"
1754
+ msgstr ""
1755
+
1756
+ #: admin/tpl/settings_compatibilities.php:37
1757
+ msgid "After purging the cache, the view count should be updating."
1758
+ msgstr ""
1759
+
1760
+ #: admin/tpl/settings_crawler.php:6
1761
+ msgid "Crawler Settings"
1762
+ msgstr ""
1763
+
1764
+ #: admin/tpl/settings_crawler.php:13
1765
+ msgid "microseconds"
1766
+ msgstr ""
1767
+
1768
+ #: admin/tpl/settings_crawler.php:15
1769
+ msgid ""
1770
+ "Specify time in microseconds for the delay between requests during a crawl."
1771
+ msgstr ""
1772
+
1773
+ #: admin/tpl/settings_crawler.php:27
1774
+ msgid "Specify time in seconds for the duration of the crawl interval."
1775
+ msgstr ""
1776
+
1777
+ #: admin/tpl/settings_crawler.php:34
1778
+ msgid "Interval Between Runs"
1779
+ msgstr ""
1780
+
1781
+ #: admin/tpl/settings_crawler.php:39
1782
+ msgid ""
1783
+ "Specify time in seconds for the time between each run interval. Must be "
1784
+ "greater than 60."
1785
+ msgstr ""
1786
+
1787
+ #: admin/tpl/settings_crawler.php:46
1788
+ msgid "Crawl Interval"
1789
+ msgstr ""
1790
+
1791
+ #: admin/tpl/settings_crawler.php:51
1792
+ msgid ""
1793
+ "Specify how long in seconds before the crawler should initiate crawling the "
1794
+ "entire sitemap again."
1795
+ msgstr ""
1796
+
1797
+ #: admin/tpl/settings_crawler.php:63
1798
+ msgid "Specify Number of Threads to use while crawling."
1799
+ msgstr ""
1800
+
1801
+ #: admin/tpl/settings_crawler.php:70
1802
+ msgid "Server Load Limit"
1803
+ msgstr ""
1804
+
1805
+ #: admin/tpl/settings_crawler.php:75
1806
+ msgid ""
1807
+ "The maximum average server load allowed while crawling. The number of "
1808
+ "crawler threads in use will be actively reduced until average server load "
1809
+ "falls under this limit. If this cannot be achieved with a single thread, the "
1810
+ "current crawler run will be terminated."
1811
+ msgstr ""
1812
+
1813
+ #: admin/tpl/settings_crawler.php:83
1814
+ msgid "Site IP"
1815
+ msgstr ""
1816
+
1817
+ #: admin/tpl/settings_crawler.php:88
1818
+ msgid ""
1819
+ "Enter this site's IP address to crawl by IP instead of domain name. This "
1820
+ "eliminates the overhead of DNS and CDN lookups. (optional)"
1821
+ msgstr ""
1822
+
1823
+ #: admin/tpl/settings_crawler.php:94
1824
+ msgid "Custom Sitemap"
1825
+ msgstr ""
1826
+
1827
+ #: admin/tpl/settings_crawler.php:99
1828
+ msgid ""
1829
+ "The crawler can use your Google XML Sitemap instead of its own. Enter the "
1830
+ "full URL to your sitemap here."
1831
+ msgstr ""
1832
+
1833
+ #: admin/tpl/settings_crawler.php:105
1834
+ msgid "Include Posts"
1835
+ msgstr ""
1836
+
1837
+ #: admin/tpl/settings_crawler.php:109
1838
+ msgid "Include Posts in crawler sitemap generation."
1839
+ msgstr ""
1840
+
1841
+ #: admin/tpl/settings_crawler.php:115
1842
+ msgid "Include Pages"
1843
+ msgstr ""
1844
+
1845
+ #: admin/tpl/settings_crawler.php:119
1846
+ msgid "Include Pages in crawler sitemap generation."
1847
+ msgstr ""
1848
+
1849
+ #: admin/tpl/settings_crawler.php:125
1850
+ msgid "Include Categories"
1851
+ msgstr ""
1852
+
1853
+ #: admin/tpl/settings_crawler.php:129
1854
+ msgid "Include Categories pages in crawler sitemap generation."
1855
+ msgstr ""
1856
+
1857
+ #: admin/tpl/settings_crawler.php:135
1858
+ msgid "Include Tags"
1859
+ msgstr ""
1860
+
1861
+ #: admin/tpl/settings_crawler.php:139
1862
+ msgid "Include Tags pages in crawler sitemap generation."
1863
+ msgstr ""
1864
+
1865
+ #: admin/tpl/settings_crawler.php:145
1866
+ msgid "Exclude Custom Post Types"
1867
+ msgstr ""
1868
+
1869
+ #: admin/tpl/settings_crawler.php:150
1870
+ msgid ""
1871
+ "If you want to exclude certain Custom Post Types in sitemap, add the Custom "
1872
+ "Post Types in the box, one per line."
1873
+ msgstr ""
1874
+
1875
+ #: admin/tpl/settings_crawler.php:154
1876
+ msgid "Available Custom Post Type"
1877
+ msgstr ""
1878
+
1879
+ #: admin/tpl/settings_crawler.php:161
1880
+ msgid "Order links by"
1881
+ msgstr ""
1882
+
1883
+ #: admin/tpl/settings_crawler.php:168
1884
+ msgid "Date, descending (Default)"
1885
+ msgstr ""
1886
+
1887
+ #: admin/tpl/settings_crawler.php:174
1888
+ msgid "Date, ascending"
1889
+ msgstr ""
1890
+
1891
+ #: admin/tpl/settings_crawler.php:180
1892
+ msgid "Alphabetical, descending"
1893
+ msgstr ""
1894
+
1895
+ #: admin/tpl/settings_crawler.php:186
1896
+ msgid "Alphabetical, ascending"
1897
+ msgstr ""
1898
+
1899
+ #: admin/tpl/settings_crawler.php:191
1900
+ msgid ""
1901
+ "Please choose one of the above options to set the order in which the sitemap "
1902
+ "will be parsed."
1903
+ msgstr ""
1904
+
1905
+ #: admin/tpl/settings_debug.php:6
1906
+ msgid "Developer Testing"
1907
+ msgstr ""
1908
+
1909
+ #: admin/tpl/settings_debug.php:17
1910
+ msgid "Off"
1911
+ msgstr ""
1912
+
1913
+ #: admin/tpl/settings_debug.php:23
1914
+ msgid "On"
1915
+ msgstr ""
1916
+
1917
+ #: admin/tpl/settings_debug.php:29
1918
+ msgid "Admin IP only"
1919
+ msgstr ""
1920
+
1921
+ #: admin/tpl/settings_debug.php:34
1922
+ msgid "Outputs to WordPress debug log."
1923
+ msgstr ""
1924
+
1925
+ #: admin/tpl/settings_debug.php:35
1926
+ msgid ""
1927
+ "This should be set to off once everything is working to prevent filling the "
1928
+ "disk."
1929
+ msgstr ""
1930
+
1931
+ #: admin/tpl/settings_debug.php:36
1932
+ msgid ""
1933
+ "The Admin IP option will only output log messages on requests from admin IPs."
1934
+ msgstr ""
1935
+
1936
+ #: admin/tpl/settings_debug.php:37
1937
+ msgid ""
1938
+ "The logs will be outputted to the debug.log in the wp-content directory."
1939
+ msgstr ""
1940
+
1941
+ #: admin/tpl/settings_debug.php:43
1942
+ msgid "Admin IPs"
1943
+ msgstr ""
1944
+
1945
+ #: admin/tpl/settings_debug.php:47
1946
+ msgid ""
1947
+ "Allows listed IPs (one per line) to perform certain actions from their "
1948
+ "browsers."
1949
+ msgstr ""
1950
+
1951
+ #: admin/tpl/settings_debug.php:48
1952
+ msgid ""
1953
+ "More information about the available commands can be found <a href=\"%s"
1954
+ "\">here</a>."
1955
+ msgstr ""
1956
+
1957
+ #: admin/tpl/settings_debug.php:55
1958
+ msgid "Debug Level"
1959
+ msgstr ""
1960
+
1961
+ #: admin/tpl/settings_debug.php:62
1962
+ msgid "Basic"
1963
+ msgstr ""
1964
+
1965
+ #: admin/tpl/settings_debug.php:73
1966
+ msgid "Advanced level will log more details."
1967
+ msgstr ""
1968
+
1969
+ #: admin/tpl/settings_debug.php:82
1970
+ msgid "MB"
1971
+ msgstr ""
1972
+
1973
+ #: admin/tpl/settings_debug.php:84
1974
+ msgid ""
1975
+ "Specify the maximum size of the log file. Minimum is 3MB. Maximum is 3000MB."
1976
+ msgstr ""
1977
+
1978
+ #: admin/tpl/settings_debug.php:91
1979
+ msgid "Heartbeat"
1980
+ msgstr ""
1981
+
1982
+ #: admin/tpl/settings_debug.php:95
1983
+ msgid ""
1984
+ "Disable WordPress heartbeat to prevent AJAX calls from breaking debug "
1985
+ "logging. WARNING: Disabling this may cause WordPress tasks triggered by AJAX "
1986
+ "to stop working."
1987
+ msgstr ""
1988
+
1989
+ #: admin/tpl/settings_debug.php:101
1990
+ msgid "Log Cookies"
1991
+ msgstr ""
1992
+
1993
+ #: admin/tpl/settings_debug.php:105
1994
+ msgid "Log request cookie values."
1995
+ msgstr ""
1996
+
1997
+ #: admin/tpl/settings_debug.php:111
1998
+ msgid "Collapse Query Strings"
1999
+ msgstr ""
2000
+
2001
+ #: admin/tpl/settings_debug.php:115
2002
+ msgid "Shorten query strings in the debug log to improve readability."
2003
+ msgstr ""
2004
+
2005
+ #: admin/tpl/settings_debug.php:121
2006
+ msgid "Log Filters"
2007
+ msgstr ""
2008
+
2009
+ #: admin/tpl/settings_debug.php:125
2010
+ msgid ""
2011
+ "Log all WordPress filter hooks. WARNING: Enabling this option will cause log "
2012
+ "file size to grow quickly."
2013
+ msgstr ""
2014
+
2015
+ #: admin/tpl/settings_debug.php:131
2016
+ msgid "Exclude Filters"
2017
+ msgstr ""
2018
+
2019
+ #: admin/tpl/settings_debug.php:135
2020
+ msgid "Listed filters (one per line) will not be logged."
2021
+ msgstr ""
2022
+
2023
+ #: admin/tpl/settings_debug.php:141
2024
+ msgid "Exclude Part Filters"
2025
+ msgstr ""
2026
+
2027
+ #: admin/tpl/settings_debug.php:145
2028
+ msgid "Filters containing these strings (one per line) will not be logged."
2029
+ msgstr ""
2030
+
2031
+ #: admin/tpl/settings_esi.php:9
2032
+ msgid "ESI Settings"
2033
+ msgstr ""
2034
+
2035
+ #: admin/tpl/settings_esi.php:11
2036
+ msgid ""
2037
+ "ESI enables the capability to cache pages for logged in users/commenters."
2038
+ msgstr ""
2039
+
2040
+ #: admin/tpl/settings_esi.php:12
2041
+ msgid ""
2042
+ "ESI functions by replacing the private information blocks with an ESI "
2043
+ "include."
2044
+ msgstr ""
2045
+
2046
+ #: admin/tpl/settings_esi.php:13
2047
+ msgid ""
2048
+ "When the server sees an ESI include, a sub request is created, containing "
2049
+ "the private information."
2050
+ msgstr ""
2051
+
2052
+ #: admin/tpl/settings_esi.php:21
2053
+ msgid "Enabling ESI will cache the public page for logged in users."
2054
+ msgstr ""
2055
+
2056
+ #: admin/tpl/settings_esi.php:22
2057
+ msgid ""
2058
+ "The Admin Bar, comments, and comment form will be served via ESI blocks."
2059
+ msgstr ""
2060
+
2061
+ #: admin/tpl/settings_esi.php:23
2062
+ msgid "The ESI blocks will not be cached until Cache ESI is checked."
2063
+ msgstr ""
2064
+
2065
+ #: admin/tpl/settings_esi.php:29
2066
+ msgid "Cache ESI"
2067
+ msgstr ""
2068
+
2069
+ #: admin/tpl/settings_esi.php:33
2070
+ msgid "Cache the ESI blocks."
2071
+ msgstr ""
2072
+
2073
+ #: admin/tpl/settings_excludes.php:7
2074
+ msgid "URI List"
2075
+ msgstr ""
2076
+
2077
+ #: admin/tpl/settings_excludes.php:9
2078
+ msgid "Enter a list of urls that should not be cached."
2079
+ msgstr ""
2080
+
2081
+ #: admin/tpl/settings_excludes.php:10
2082
+ msgid "The urls will be compared to the REQUEST_URI server variable."
2083
+ msgstr ""
2084
+
2085
+ #: admin/tpl/settings_excludes.php:11
2086
+ msgid "There should only be one url per line."
2087
+ msgstr ""
2088
+
2089
+ #: admin/tpl/settings_excludes.php:16
2090
+ msgid "URLs must start with a '/' to be correctly matched."
2091
+ msgstr ""
2092
+
2093
+ #: admin/tpl/settings_excludes.php:17
2094
+ msgid "To do an exact match, add '$' to the end of the URL."
2095
+ msgstr ""
2096
+
2097
+ #: admin/tpl/settings_excludes.php:18
2098
+ msgid "Any surrounding whitespaces will be trimmed."
2099
+ msgstr ""
2100
+
2101
+ #: admin/tpl/settings_excludes.php:19 admin/tpl/settings_excludes.php:43
2102
+ #: admin/tpl/settings_excludes.php:73
2103
+ msgid "e.g. to exclude %1$s, insert %2$s"
2104
+ msgstr ""
2105
+
2106
+ #: admin/tpl/settings_excludes.php:21
2107
+ msgid "Similarly, to exclude %1$s(accessed with the /blog), insert %2$s"
2108
+ msgstr ""
2109
+
2110
+ #: admin/tpl/settings_excludes.php:27
2111
+ msgid "SYNTAX: URLs must start with a '/' to be correctly matched."
2112
+ msgstr ""
2113
+
2114
+ #: admin/tpl/settings_excludes.php:28
2115
+ msgid "To do an exact match, add '$' to the end of the URL. One URL per line."
2116
+ msgstr ""
2117
+
2118
+ #: admin/tpl/settings_excludes.php:34
2119
+ msgid "Category List"
2120
+ msgstr ""
2121
+
2122
+ #: admin/tpl/settings_excludes.php:36
2123
+ msgid "All categories are cached by default."
2124
+ msgstr ""
2125
+
2126
+ #: admin/tpl/settings_excludes.php:37
2127
+ msgid ""
2128
+ "To prevent a category from being cached, enter it in the text area below, "
2129
+ "one per line."
2130
+ msgstr ""
2131
+
2132
+ #: admin/tpl/settings_excludes.php:42
2133
+ msgid "If the Category ID is not found, the name will be removed on save."
2134
+ msgstr ""
2135
+
2136
+ #: admin/tpl/settings_excludes.php:49
2137
+ msgid "SYNTAX: One category id per line."
2138
+ msgstr ""
2139
+
2140
+ #: admin/tpl/settings_excludes.php:64
2141
+ msgid "Tag List"
2142
+ msgstr ""
2143
+
2144
+ #: admin/tpl/settings_excludes.php:66
2145
+ msgid "All tags are cached by default."
2146
+ msgstr ""
2147
+
2148
+ #: admin/tpl/settings_excludes.php:67
2149
+ msgid ""
2150
+ "To prevent tags from being cached, enter the tag in the text area below, one "
2151
+ "per line."
2152
+ msgstr ""
2153
+
2154
+ #: admin/tpl/settings_excludes.php:72
2155
+ msgid "If the Tag ID is not found, the name will be removed on save."
2156
+ msgstr ""
2157
+
2158
+ #: admin/tpl/settings_excludes.php:79
2159
+ msgid "SYNTAX: One tag id per line."
2160
+ msgstr ""
2161
+
2162
+ #: admin/tpl/settings_general.php:9
2163
+ msgid "Enable LiteSpeed Cache"
2164
+ msgstr ""
2165
+
2166
+ #: admin/tpl/settings_general.php:39
2167
+ msgid "Use Network Admin Setting"
2168
+ msgstr ""
2169
+
2170
+ #: admin/tpl/settings_general.php:46
2171
+ msgid "Please visit the <a %s>Information</a> page on how to test the cache."
2172
+ msgstr ""
2173
+
2174
+ #: admin/tpl/settings_general.php:49
2175
+ msgid "NOTICE"
2176
+ msgstr ""
2177
+
2178
+ #: admin/tpl/settings_general.php:49
2179
+ msgid ""
2180
+ "When disabling the cache, all cached entries for this blog will be purged."
2181
+ msgstr ""
2182
+
2183
+ #: admin/tpl/settings_general.php:51
2184
+ msgid "The network admin setting can be overridden here."
2185
+ msgstr ""
2186
+
2187
+ #: admin/tpl/settings_general.php:58
2188
+ msgid "Default Public Cache TTL"
2189
+ msgstr ""
2190
+
2191
+ #: admin/tpl/settings_general.php:63
2192
+ msgid ""
2193
+ "Specify how long, in seconds, public pages are cached. Minimum is 30 seconds."
2194
+ msgstr ""
2195
+
2196
+ #: admin/tpl/settings_general.php:70
2197
+ msgid "Default Front Page TTL"
2198
+ msgstr ""
2199
+
2200
+ #: admin/tpl/settings_general.php:75
2201
+ msgid ""
2202
+ "Specify how long, in seconds, the front page is cached. Minimum is 30 "
2203
+ "seconds."
2204
+ msgstr ""
2205
+
2206
+ #: admin/tpl/settings_general.php:82
2207
+ msgid "Default Feed TTL"
2208
+ msgstr ""
2209
+
2210
+ #: admin/tpl/settings_general.php:87
2211
+ msgid "Specify how long, in seconds, feeds are cached."
2212
+ msgstr ""
2213
+
2214
+ #: admin/tpl/settings_general.php:88
2215
+ msgid "If this is set to a number less than 30, feeds will not be cached."
2216
+ msgstr ""
2217
+
2218
+ #: admin/tpl/settings_general.php:95
2219
+ msgid "Default 404 Page TTL"
2220
+ msgstr ""
2221
+
2222
+ #: admin/tpl/settings_general.php:100
2223
+ msgid "Specify how long, in seconds, 404 pages are cached."
2224
+ msgstr ""
2225
+
2226
+ #: admin/tpl/settings_general.php:101
2227
+ msgid "If this is set to a number less than 30, 404 pages will not be cached."
2228
+ msgstr ""
2229
+
2230
+ #: admin/tpl/settings_general.php:108
2231
+ msgid "Default 403 Page TTL"
2232
+ msgstr ""
2233
+
2234
+ #: admin/tpl/settings_general.php:113
2235
+ msgid "Specify how long, in seconds, 403 pages are cached."
2236
+ msgstr ""
2237
+
2238
+ #: admin/tpl/settings_general.php:114
2239
+ msgid "If this is set to a number less than 30, 403 pages will not be cached."
2240
+ msgstr ""
2241
+
2242
+ #: admin/tpl/settings_general.php:121
2243
+ msgid "Default 500 Page TTL"
2244
+ msgstr ""
2245
+
2246
+ #: admin/tpl/settings_general.php:126
2247
+ msgid "Specify how long, in seconds, 500 pages are cached."
2248
+ msgstr ""
2249
+
2250
+ #: admin/tpl/settings_general.php:127
2251
+ msgid "If this is set to a number less than 30, 500 pages will not be cached."
2252
+ msgstr ""
2253
+
2254
+ #: admin/tpl/settings_inc.cache_favicon.php:7
2255
+ msgid "Cache favicon.ico"
2256
+ msgstr ""
2257
+
2258
+ #: admin/tpl/settings_inc.cache_favicon.php:11
2259
+ msgid "favicon.ico is requested on most pages."
2260
+ msgstr ""
2261
+
2262
+ #: admin/tpl/settings_inc.cache_favicon.php:12
2263
+ msgid ""
2264
+ "Caching this recource may improve server performance by avoiding unnecessary "
2265
+ "PHP calls."
2266
+ msgstr ""
2267
+
2268
+ #: admin/tpl/settings_inc.cache_mobile.php:8
2269
+ msgid "Cache Mobile"
2270
+ msgstr ""
2271
+
2272
+ #: admin/tpl/settings_inc.cache_mobile.php:15
2273
+ msgid "When enabled, mobile views will be cached separately."
2274
+ msgstr ""
2275
+
2276
+ #: admin/tpl/settings_inc.cache_mobile.php:16
2277
+ msgid "A site built with responsive design does not need to check this."
2278
+ msgstr ""
2279
+
2280
+ #: admin/tpl/settings_inc.cache_mobile.php:22
2281
+ msgid "List of Mobile User Agents"
2282
+ msgstr ""
2283
+
2284
+ #: admin/tpl/settings_inc.cache_mobile.php:47
2285
+ msgid "Htaccess did not match configuration option."
2286
+ msgstr ""
2287
+
2288
+ #: admin/tpl/settings_inc.cache_mobile.php:48
2289
+ msgid "Please re-enter the mobile view setting."
2290
+ msgstr ""
2291
+
2292
+ #: admin/tpl/settings_inc.cache_mobile.php:49
2293
+ msgid "List in WordPress database is: %s"
2294
+ msgstr ""
2295
+
2296
+ #: admin/tpl/settings_inc.cache_mobile.php:65
2297
+ #: admin/tpl/settings_inc.exclude_cookies.php:7
2298
+ #: admin/tpl/settings_inc.exclude_useragent.php:12
2299
+ msgid "This setting will edit the .htaccess file."
2300
+ msgstr ""
2301
+
2302
+ #: admin/tpl/settings_inc.cache_mobile.php:69
2303
+ msgid "SYNTAX: Each entry should be separated with a bar, %s"
2304
+ msgstr ""
2305
+
2306
+ #: admin/tpl/settings_inc.cache_mobile.php:70
2307
+ msgid "Any spaces should be escaped with a backslash before the space, %s"
2308
+ msgstr ""
2309
+
2310
+ #: admin/tpl/settings_inc.cache_mobile.php:72
2311
+ msgid "The default list WordPress uses is %s"
2312
+ msgstr ""
2313
+
2314
+ #: admin/tpl/settings_inc.cache_resources.php:8
2315
+ msgid "Cache PHP Resources"
2316
+ msgstr ""
2317
+
2318
+ #: admin/tpl/settings_inc.cache_resources.php:12
2319
+ msgid "Some themes and plugins add resources via a PHP request."
2320
+ msgstr ""
2321
+
2322
+ #: admin/tpl/settings_inc.cache_resources.php:13
2323
+ msgid ""
2324
+ "Caching these pages may improve server performance by avoiding unnecessary "
2325
+ "PHP calls."
2326
+ msgstr ""
2327
+
2328
+ #: admin/tpl/settings_inc.exclude_cookies.php:2
2329
+ msgid "Cookie List"
2330
+ msgstr ""
2331
+
2332
+ #: admin/tpl/settings_inc.exclude_cookies.php:3
2333
+ msgid "To prevent cookies from being cached, enter it in the text area below."
2334
+ msgstr ""
2335
+
2336
+ #: admin/tpl/settings_inc.exclude_cookies.php:12
2337
+ msgid "SYNTAX: Cookies should be listed one per line."
2338
+ msgstr ""
2339
+
2340
+ #: admin/tpl/settings_inc.exclude_cookies.php:13
2341
+ msgid "Spaces should have a backslash in front of them, %s"
2342
+ msgstr ""
2343
+
2344
+ #: admin/tpl/settings_inc.exclude_useragent.php:7
2345
+ msgid "User Agent List"
2346
+ msgstr ""
2347
+
2348
+ #: admin/tpl/settings_inc.exclude_useragent.php:8
2349
+ msgid ""
2350
+ "To prevent user agents from being cached, enter it in the text field below."
2351
+ msgstr ""
2352
+
2353
+ #: admin/tpl/settings_inc.exclude_useragent.php:17
2354
+ msgid ""
2355
+ "SYNTAX: Separate each user agent with a bar, <font style=\"font-style:normal"
2356
+ "\">%s</font>."
2357
+ msgstr ""
2358
+
2359
+ #: admin/tpl/settings_inc.exclude_useragent.php:18
2360
+ msgid "Spaces should have a backslash in front of them, %s."
2361
+ msgstr ""
2362
+
2363
+ #: admin/tpl/settings_inc.purge_on_upgrade.php:7
2364
+ msgid "Purge All on upgrade"
2365
+ msgstr ""
2366
+
2367
+ #: admin/tpl/settings_inc.purge_on_upgrade.php:11
2368
+ msgid ""
2369
+ "When enabled, the cache will automatically purge when any plugins, themes, "
2370
+ "or WordPress core is upgraded."
2371
+ msgstr ""
2372
+
2373
+ #: admin/tpl/settings_purge.php:5
2374
+ msgid "Purge Settings"
2375
+ msgstr ""
2376
+
2377
+ #: admin/tpl/settings_purge.php:10
2378
+ msgid "All pages"
2379
+ msgstr ""
2380
+
2381
+ #: admin/tpl/settings_purge.php:11
2382
+ msgid "Front page"
2383
+ msgstr ""
2384
+
2385
+ #: admin/tpl/settings_purge.php:12
2386
+ msgid "Home page"
2387
+ msgstr ""
2388
+
2389
+ #: admin/tpl/settings_purge.php:13
2390
+ msgid "Pages"
2391
+ msgstr ""
2392
+
2393
+ #: admin/tpl/settings_purge.php:15
2394
+ msgid "All pages with Recent Posts Widget"
2395
+ msgstr ""
2396
+
2397
+ #: admin/tpl/settings_purge.php:17
2398
+ msgid "Author archive"
2399
+ msgstr ""
2400
+
2401
+ #: admin/tpl/settings_purge.php:18
2402
+ msgid "Post type archive"
2403
+ msgstr ""
2404
+
2405
+ #: admin/tpl/settings_purge.php:20
2406
+ msgid "Yearly archive"
2407
+ msgstr ""
2408
+
2409
+ #: admin/tpl/settings_purge.php:21
2410
+ msgid "Monthly archive"
2411
+ msgstr ""
2412
+
2413
+ #: admin/tpl/settings_purge.php:22
2414
+ msgid "Daily archive"
2415
+ msgstr ""
2416
+
2417
+ #: admin/tpl/settings_purge.php:24
2418
+ msgid "Term archive (include category, tag, and tax)"
2419
+ msgstr ""
2420
+
2421
+ #: admin/tpl/settings_purge.php:44
2422
+ msgid "Auto Purge Rules For Publish/Update"
2423
+ msgstr ""
2424
+
2425
+ #: admin/tpl/settings_purge.php:48
2426
+ #: thirdparty/lscwp-3rd-woocommerce.cls.php:647
2427
+ msgid "Note:"
2428
+ msgstr ""
2429
+
2430
+ #: admin/tpl/settings_purge.php:50
2431
+ msgid ""
2432
+ "Select \"All\" if there are dynamic widgets linked to posts on pages other "
2433
+ "than the front or home pages."
2434
+ msgstr ""
2435
+
2436
+ #: admin/tpl/settings_purge.php:51
2437
+ msgid "Other checkboxes will be ignored."
2438
+ msgstr ""
2439
+
2440
+ #: admin/tpl/settings_purge.php:52
2441
+ msgid ""
2442
+ "Select only the archive types that are currently used, the others can be "
2443
+ "left unchecked."
2444
+ msgstr ""
2445
+
2446
+ #: admin/tpl/settings_purge.php:69
2447
+ msgid ""
2448
+ "Select which pages will be automatically purged when posts are published/"
2449
+ "updated."
2450
+ msgstr ""
2451
+
2452
+ #: admin/tpl/settings_purge.php:75 admin/tpl/settings_purge.php:91
2453
+ msgid "Scheduled Purge URLs"
2454
+ msgstr ""
2455
+
2456
+ #: admin/tpl/settings_purge.php:79
2457
+ msgid ""
2458
+ "The URLs here (one per line) will be purged automatically at the time set in "
2459
+ "the option \"%s\"."
2460
+ msgstr ""
2461
+
2462
+ #: admin/tpl/settings_purge.php:79 admin/tpl/settings_purge.php:86
2463
+ msgid "Scheduled Purge Time"
2464
+ msgstr ""
2465
+
2466
+ #: admin/tpl/settings_purge.php:80
2467
+ msgid "Both %1$s and %2$s are acceptable."
2468
+ msgstr ""
2469
+
2470
+ #: admin/tpl/settings_purge.php:91
2471
+ msgid "Specify the time to purge the \"%s\" list."
2472
+ msgstr ""
2473
+
2474
+ #: admin/tpl/settings_purge.php:92
2475
+ msgid "Current server time is %s."
2476
+ msgstr ""
2477
+
2478
+ #: admin/tpl/show_display_installed.php:5
2479
+ msgid "LiteSpeed Cache plugin is installed!"
2480
+ msgstr ""
2481
+
2482
+ #: admin/tpl/show_display_installed.php:6
2483
+ msgid ""
2484
+ "This message indicates that the plugin was installed by the server admin."
2485
+ msgstr ""
2486
+
2487
+ #: admin/tpl/show_display_installed.php:7
2488
+ msgid ""
2489
+ "The LiteSpeed Cache plugin is used to cache pages - a simple way to improve "
2490
+ "the performance of the site."
2491
+ msgstr ""
2492
+
2493
+ #: admin/tpl/show_display_installed.php:8
2494
+ msgid ""
2495
+ "However, there is no way of knowing all the possible customizations that "
2496
+ "were implemented."
2497
+ msgstr ""
2498
+
2499
+ #: admin/tpl/show_display_installed.php:9
2500
+ msgid ""
2501
+ "For that reason, please test the site to make sure everything still "
2502
+ "functions properly."
2503
+ msgstr ""
2504
+
2505
+ #: admin/tpl/show_display_installed.php:11
2506
+ msgid "Examples of test cases include:"
2507
+ msgstr ""
2508
+
2509
+ #: admin/tpl/show_display_installed.php:13
2510
+ msgid "Visit the site while logged out."
2511
+ msgstr ""
2512
+
2513
+ #: admin/tpl/show_display_installed.php:14
2514
+ msgid "Create a post, make sure the front page is accurate."
2515
+ msgstr ""
2516
+
2517
+ #: admin/tpl/show_display_installed.php:16
2518
+ msgid ""
2519
+ "If there are any questions, the team is always happy to answer any questions "
2520
+ "on the <a %s>support forum</a>."
2521
+ msgstr ""
2522
+
2523
+ #: admin/tpl/show_display_installed.php:19
2524
+ msgid ""
2525
+ "If you would rather not move at litespeed, you can deactivate this plugin."
2526
+ msgstr ""
2527
+
2528
+ #: admin/tpl/show_error_cookie.php:4
2529
+ msgid "NOTICE: Database login cookie did not match your login cookie."
2530
+ msgstr ""
2531
+
2532
+ #: admin/tpl/show_error_cookie.php:5
2533
+ msgid ""
2534
+ "If the login cookie was recently changed in the settings, please log out and "
2535
+ "back in."
2536
+ msgstr ""
2537
+
2538
+ #: admin/tpl/show_error_cookie.php:6
2539
+ msgid ""
2540
+ "If not, please verify the setting in the <a href=\"%1$s\">Advanced tab</a>."
2541
+ msgstr ""
2542
+
2543
+ #: admin/tpl/show_error_cookie.php:10
2544
+ msgid ""
2545
+ "If using OpenLiteSpeed, the server must be restarted once for the changes to "
2546
+ "take effect."
2547
+ msgstr ""
2548
+
2549
+ #: admin/tpl/show_rule_conflict.php:5
2550
+ msgid ""
2551
+ "Unexpected cache rule %2$s found in %1$s file. This rule may cause visitors "
2552
+ "to see old versions of pages due to the browser caching html pages. If you "
2553
+ "are sure that html pages are not being browser cached, this message can be "
2554
+ "dismissed. (<a %3$s>Learn More</a>)"
2555
+ msgstr ""
2556
+
2557
+ #: cli/litespeed-cache-cli-purge.class.php:90
2558
+ msgid "Purged All!"
2559
+ msgstr ""
2560
+
2561
+ #: cli/litespeed-cache-cli-purge.class.php:135
2562
+ msgid "Purged the blog!"
2563
+ msgstr ""
2564
+
2565
+ #: cli/litespeed-cache-cli-purge.class.php:187
2566
+ msgid "Purged the url!"
2567
+ msgstr ""
2568
+
2569
+ #: cli/litespeed-cache-cli-purge.class.php:236
2570
+ msgid "Purged the tags!"
2571
+ msgstr ""
2572
+
2573
+ #: includes/litespeed-cache-crawler.class.php:108
2574
+ msgid "Can not find any form data for blacklist"
2575
+ msgstr ""
2576
+
2577
+ #: includes/litespeed-cache-crawler.class.php:123
2578
+ msgid "File saved successfully: %s"
2579
+ msgstr ""
2580
+
2581
+ #: includes/litespeed-cache-crawler.class.php:175
2582
+ msgid "File created successfully: %s"
2583
+ msgstr ""
2584
+
2585
+ #: includes/litespeed-cache-crawler.class.php:323
2586
+ msgid "Failed to send position reset notification: %s"
2587
+ msgstr ""
2588
+
2589
+ #: includes/litespeed-cache-crawler.class.php:327
2590
+ msgid "Position reset notification sent successfully"
2591
+ msgstr ""
2592
+
2593
+ #: includes/litespeed-cache-crawler.class.php:410
2594
+ #: lib/litespeed/litespeed-crawler.class.php:327
2595
+ msgid "Reached end of sitemap file. Crawling completed."
2596
+ msgstr ""
2597
+
2598
+ #: includes/litespeed-cache-purge.class.php:199
2599
+ msgid "Purge category %s"
2600
+ msgstr ""
2601
+
2602
+ #: includes/litespeed-cache-purge.class.php:226
2603
+ msgid "Purge Post ID %s"
2604
+ msgstr ""
2605
+
2606
+ #: includes/litespeed-cache-purge.class.php:255
2607
+ msgid "Purge tag %s"
2608
+ msgstr ""
2609
+
2610
+ #: includes/litespeed-cache-purge.class.php:289
2611
+ msgid "Purge url %s"
2612
+ msgstr ""
2613
+
2614
+ #: includes/litespeed-cache-task.class.php:97
2615
+ msgid "LiteSpeed Cache Custom Cron"
2616
+ msgstr ""
2617
+
2618
+ #: includes/litespeed-cache.class.php:196
2619
+ msgid "Crawler blacklist is saved."
2620
+ msgstr ""
2621
+
2622
+ #: includes/litespeed-cache.class.php:201
2623
+ msgid "Notified LiteSpeed Web Server to purge the front page."
2624
+ msgstr ""
2625
+
2626
+ #: includes/litespeed-cache.class.php:206
2627
+ msgid "Notified LiteSpeed Web Server to purge pages."
2628
+ msgstr ""
2629
+
2630
+ #: includes/litespeed-cache.class.php:211
2631
+ msgid "Notified LiteSpeed Web Server to purge error pages."
2632
+ msgstr ""
2633
+
2634
+ #: includes/litespeed-cache.class.php:217
2635
+ msgid "Notified LiteSpeed Web Server to purge all caches."
2636
+ msgstr ""
2637
+
2638
+ #: includes/litespeed-cache.class.php:224
2639
+ msgid "Notified LiteSpeed Web Server to purge everything."
2640
+ msgstr ""
2641
+
2642
+ #: includes/litespeed-cache.class.php:229
2643
+ msgid "Notified LiteSpeed Web Server to purge the list."
2644
+ msgstr ""
2645
+
2646
+ #: lib/litespeed/litespeed-crawler.class.php:174
2647
+ msgid "Oh look, there is already another LiteSpeed crawler running!"
2648
+ msgstr ""
2649
+
2650
+ #: lib/litespeed/litespeed-crawler.class.php:180
2651
+ msgid "Stopped due to load hit the maximum."
2652
+ msgstr ""
2653
+
2654
+ #: lib/litespeed/litespeed-crawler.class.php:234
2655
+ msgid "Stopped due to error when crawling urls %1$s : %2$s"
2656
+ msgstr ""
2657
+
2658
+ #: lib/litespeed/litespeed-crawler.class.php:241
2659
+ msgid "Stopped: crawler disabled by the server admin"
2660
+ msgstr ""
2661
+
2662
+ #: lib/litespeed/litespeed-crawler.class.php:261
2663
+ msgid "Stopped due to exceeding defined Maximum Run Time"
2664
+ msgstr ""
2665
+
2666
+ #: lib/litespeed/litespeed-crawler.class.php:277
2667
+ msgid "Stopped due to reset meta position"
2668
+ msgstr ""
2669
+
2670
+ #: lib/litespeed/litespeed-crawler.class.php:285
2671
+ msgid "Stopped due to load over limit"
2672
+ msgstr ""
2673
+
2674
+ #: lib/litespeed/litespeed-crawler.class.php:538
2675
+ msgid "Cannot read meta file: %s"
2676
+ msgstr ""
2677
+
2678
+ #: lib/litespeed/litespeed-file.class.php:113
2679
+ msgid "Folder does not exist: %s"
2680
+ msgstr ""
2681
+
2682
+ #: lib/litespeed/litespeed-file.class.php:122
2683
+ msgid "Can not create folder: %1$s. Error: %2$s"
2684
+ msgstr ""
2685
+
2686
+ #: lib/litespeed/litespeed-file.class.php:130
2687
+ msgid "Folder is not writable: %s."
2688
+ msgstr ""
2689
+
2690
+ #: lib/litespeed/litespeed-file.class.php:137
2691
+ #: lib/litespeed/litespeed-file.class.php:142
2692
+ msgid "File %s is not writable."
2693
+ msgstr ""
2694
+
2695
+ #: lib/litespeed/litespeed-file.class.php:147
2696
+ msgid "Failed to write to %s."
2697
+ msgstr ""
2698
+
2699
+ #: thirdparty/lscwp-3rd-woocommerce.cls.php:592
2700
+ msgid "WooCommerce"
2701
+ msgstr ""
2702
+
2703
+ #: thirdparty/lscwp-3rd-woocommerce.cls.php:595
2704
+ msgid "Purge product on changes to the quantity or stock status."
2705
+ msgstr ""
2706
+
2707
+ #: thirdparty/lscwp-3rd-woocommerce.cls.php:596
2708
+ msgid "Purge categories only when stock status changes."
2709
+ msgstr ""
2710
+
2711
+ #: thirdparty/lscwp-3rd-woocommerce.cls.php:597
2712
+ msgid "Purge product and categories only when the stock status changes."
2713
+ msgstr ""
2714
+
2715
+ #: thirdparty/lscwp-3rd-woocommerce.cls.php:598
2716
+ msgid "Purge product only when the stock status changes."
2717
+ msgstr ""
2718
+
2719
+ #: thirdparty/lscwp-3rd-woocommerce.cls.php:599
2720
+ msgid "Do not purge categories on changes to the quantity or stock status."
2721
+ msgstr ""
2722
+
2723
+ #: thirdparty/lscwp-3rd-woocommerce.cls.php:600
2724
+ msgid ""
2725
+ "Always purge both product and categories on changes to the quantity or stock "
2726
+ "status."
2727
+ msgstr ""
2728
+
2729
+ #: thirdparty/lscwp-3rd-woocommerce.cls.php:603
2730
+ msgid ""
2731
+ "Determines how changes in product quantity and product stock status affect "
2732
+ "product pages and their associated category pages."
2733
+ msgstr ""
2734
+
2735
+ #: thirdparty/lscwp-3rd-woocommerce.cls.php:604
2736
+ msgid ""
2737
+ "Checking this option will force the shop page to use the front page TTL "
2738
+ "setting."
2739
+ msgstr ""
2740
+
2741
+ #: thirdparty/lscwp-3rd-woocommerce.cls.php:605
2742
+ msgid ""
2743
+ "For example, if the homepage for the site is located at %1$s, the shop page "
2744
+ "may be located at %2$s."
2745
+ msgstr ""
2746
+
2747
+ #: thirdparty/lscwp-3rd-woocommerce.cls.php:632
2748
+ msgid "Product Update Interval"
2749
+ msgstr ""
2750
+
2751
+ #: thirdparty/lscwp-3rd-woocommerce.cls.php:639
2752
+ msgid "Use Front Page TTL for the Shop Page"
2753
+ msgstr ""
2754
+
2755
+ #: thirdparty/lscwp-3rd-woocommerce.cls.php:649
2756
+ msgid "After verifying that the cache works in general, please test the cart."
2757
+ msgstr ""
2758
+
2759
+ #: thirdparty/lscwp-3rd-woocommerce.cls.php:650
2760
+ msgid "To test the cart, visit the %s."
2761
+ msgstr ""
2762
+
2763
+ #. Plugin Name of the plugin/theme
2764
+ msgid "LiteSpeed Cache"
2765
+ msgstr ""
2766
+
2767
+ #. Plugin URI of the plugin/theme
2768
+ msgid ""
2769
+ "https://www.litespeedtech.com/products/cache-plugins/wordpress-acceleration"
2770
+ msgstr ""
2771
+
2772
+ #. Description of the plugin/theme
2773
+ msgid "WordPress plugin to connect to LSCache on LiteSpeed Web Server."
2774
+ msgstr ""
2775
+
2776
+ #. Author of the plugin/theme
2777
+ msgid "LiteSpeed Technologies"
2778
+ msgstr ""
2779
+
2780
+ #. Author URI of the plugin/theme
2781
+ msgid "https://www.litespeedtech.com"
2782
+ msgstr ""
lib/litespeed-php-compatibility.func.php ADDED
@@ -0,0 +1,123 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * LiteSpeed PHP compatibility functions for lower PHP version
4
+ *
5
+ * @since 1.1.3
6
+ * @package LiteSpeed_Cache
7
+ * @subpackage LiteSpeed_Cache/lib
8
+ * @author LiteSpeed Technologies <info@litespeedtech.com>
9
+ */
10
+
11
+ if ( ! defined('WPINC') ) {
12
+ die ;
13
+ }
14
+
15
+
16
+
17
+ /**
18
+ * http_build_url() compatibility
19
+ *
20
+ */
21
+ if ( ! function_exists('http_build_url') ) {
22
+ define('HTTP_URL_REPLACE', 1); // Replace every part of the first URL when there's one of the second URL
23
+ define('HTTP_URL_JOIN_PATH', 2); // Join relative paths
24
+ define('HTTP_URL_JOIN_QUERY', 4); // Join query strings
25
+ define('HTTP_URL_STRIP_USER', 8); // Strip any user authentication information
26
+ define('HTTP_URL_STRIP_PASS', 16); // Strip any password authentication information
27
+ define('HTTP_URL_STRIP_AUTH', 32); // Strip any authentication information
28
+ define('HTTP_URL_STRIP_PORT', 64); // Strip explicit port numbers
29
+ define('HTTP_URL_STRIP_PATH', 128); // Strip complete path
30
+ define('HTTP_URL_STRIP_QUERY', 256); // Strip query string
31
+ define('HTTP_URL_STRIP_FRAGMENT', 512); // Strip any fragments (#identifier)
32
+ define('HTTP_URL_STRIP_ALL', 1024); // Strip anything but scheme and host
33
+
34
+ // Build an URL
35
+ // The parts of the second URL will be merged into the first according to the flags argument.
36
+ //
37
+ // @param mixed (Part(s) of) an URL in form of a string or associative array like parse_url() returns
38
+ // @param mixed Same as the first argument
39
+ // @param int A bitmask of binary or'ed HTTP_URL constants (Optional)HTTP_URL_REPLACE is the default
40
+ // @param array If set, it will be filled with the parts of the composed url like parse_url() would return
41
+ function http_build_url($url, $parts = array(), $flags = HTTP_URL_REPLACE, &$new_url = false)
42
+ {
43
+ $keys = array('user','pass','port','path','query','fragment');
44
+
45
+ // HTTP_URL_STRIP_ALL becomes all the HTTP_URL_STRIP_Xs
46
+ if ( $flags & HTTP_URL_STRIP_ALL ) {
47
+ $flags |= HTTP_URL_STRIP_USER;
48
+ $flags |= HTTP_URL_STRIP_PASS;
49
+ $flags |= HTTP_URL_STRIP_PORT;
50
+ $flags |= HTTP_URL_STRIP_PATH;
51
+ $flags |= HTTP_URL_STRIP_QUERY;
52
+ $flags |= HTTP_URL_STRIP_FRAGMENT;
53
+ }
54
+ // HTTP_URL_STRIP_AUTH becomes HTTP_URL_STRIP_USER and HTTP_URL_STRIP_PASS
55
+ else if ( $flags & HTTP_URL_STRIP_AUTH ) {
56
+ $flags |= HTTP_URL_STRIP_USER;
57
+ $flags |= HTTP_URL_STRIP_PASS;
58
+ }
59
+
60
+ // Parse the original URL
61
+ // - Suggestion by Sayed Ahad Abbas
62
+ // In case you send a parse_url array as input
63
+ $parse_url = !is_array($url) ? parse_url($url) : $url;
64
+
65
+ // Scheme and Host are always replaced
66
+ if ( isset($parts['scheme']) ) {
67
+ $parse_url['scheme'] = $parts['scheme'];
68
+ }
69
+ if ( isset($parts['host']) ) {
70
+ $parse_url['host'] = $parts['host'];
71
+ }
72
+
73
+ // (If applicable) Replace the original URL with it's new parts
74
+ if ( $flags & HTTP_URL_REPLACE ) {
75
+ foreach ($keys as $key) {
76
+ if ( isset($parts[$key]) ) {
77
+ $parse_url[$key] = $parts[$key];
78
+ }
79
+ }
80
+ }
81
+ else {
82
+ // Join the original URL path with the new path
83
+ if (isset($parts['path']) && ($flags & HTTP_URL_JOIN_PATH)) {
84
+ if ( isset($parse_url['path']) ) {
85
+ $parse_url['path'] = rtrim(str_replace(basename($parse_url['path']), '', $parse_url['path']), '/') . '/' . ltrim($parts['path'], '/');
86
+ }
87
+ else {
88
+ $parse_url['path'] = $parts['path'];
89
+ }
90
+ }
91
+
92
+ // Join the original query string with the new query string
93
+ if ( isset($parts['query']) && ($flags & HTTP_URL_JOIN_QUERY) ) {
94
+ if ( isset($parse_url['query']) ) {
95
+ $parse_url['query'] .= '&' . $parts['query'];
96
+ }
97
+ else {
98
+ $parse_url['query'] = $parts['query'];
99
+ }
100
+ }
101
+ }
102
+
103
+ // Strips all the applicable sections of the URL
104
+ // Note: Scheme and Host are never stripped
105
+ foreach ($keys as $key) {
106
+ if ( $flags & (int)constant('HTTP_URL_STRIP_' . strtoupper($key)) ) {
107
+ unset($parse_url[$key]);
108
+ }
109
+ }
110
+
111
+ $new_url = $parse_url;
112
+
113
+ return
114
+ (isset($parse_url['scheme']) ? $parse_url['scheme'] . '://' : '')
115
+ .(isset($parse_url['user']) ? $parse_url['user'] . (isset($parse_url['pass']) ? ':' . $parse_url['pass'] : '') .'@' : '')
116
+ .(isset($parse_url['host']) ? $parse_url['host'] : '')
117
+ .(isset($parse_url['port']) ? ':' . $parse_url['port'] : '')
118
+ .(isset($parse_url['path']) ? $parse_url['path'] : '')
119
+ .(isset($parse_url['query']) ? '?' . $parse_url['query'] : '')
120
+ .(isset($parse_url['fragment']) ? '#' . $parse_url['fragment'] : '')
121
+ ;
122
+ }
123
+ }
lib/litespeed/litespeed-crawler.class.php ADDED
@@ -0,0 +1,573 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * LiteSpeed Crawler Class
4
+ *
5
+ * @since 1.1.0
6
+ */
7
+ require_once LSWCP_DIR . 'lib/litespeed-php-compatibility.func.php' ;
8
+
9
+ class Litespeed_Crawler
10
+ {
11
+ private $_baseUrl ;
12
+ private $_sitemap_file ;
13
+ private $_meta_file ;
14
+ private $_run_delay = 500 ;//microseconds
15
+ private $_run_duration = 200 ;//seconds
16
+ private $_threads_limit = 3 ;
17
+ private $_load_limit = 1 ;
18
+ private $_domain_ip = '' ;
19
+
20
+ protected $_blacklist ;
21
+ protected $_meta ;
22
+ protected $_max_run_time ;
23
+ protected $_cur_thread_time ;
24
+ protected $_cur_threads = -1 ;
25
+
26
+ const CHUNKS = 10000 ;
27
+ const USER_AGENT = 'lscache_walker' ;
28
+ const FAST_USER_AGENT = 'lscache_runner' ;
29
+
30
+ /**
31
+ * Set load limit
32
+ *
33
+ * @since 1.1.0
34
+ * @access public
35
+ * @param string $sitemap_file Sitemap file location
36
+ */
37
+ public function __construct($sitemap_file)
38
+ {
39
+ $this->_sitemap_file = $sitemap_file ;
40
+ $this->_meta_file = $this->_sitemap_file . '.meta' ;
41
+ }
42
+
43
+ /**
44
+ * Set domain ip
45
+ *
46
+ * @since 1.1.1
47
+ * @access public
48
+ * @param string $val The domain's direct ip
49
+ */
50
+ public function set_domain_ip($val)
51
+ {
52
+ $this->_domain_ip = $val ;
53
+ }
54
+
55
+ /**
56
+ * Set domain url
57
+ *
58
+ * @since 1.1.0
59
+ * @access public
60
+ * @param string $val The prefix url
61
+ */
62
+ public function set_base_url($val)
63
+ {
64
+ $this->_baseUrl = $val ;
65
+ }
66
+
67
+ /**
68
+ * Set run delay
69
+ *
70
+ * @since 1.1.0
71
+ * @access public
72
+ * @param int $val Delay microseconds
73
+ */
74
+ public function set_run_delay($val)
75
+ {
76
+ $this->_run_delay = $val ;
77
+ }
78
+
79
+ /**
80
+ * Set load limit
81
+ *
82
+ * @since 1.1.0
83
+ * @access public
84
+ * @param int $val Run duration in seconds
85
+ */
86
+ public function set_run_duration($val)
87
+ {
88
+ $this->_run_duration = $val ;
89
+ }
90
+
91
+ /**
92
+ * Set load limit
93
+ *
94
+ * @since 1.1.0
95
+ * @access public
96
+ * @param int $val Threads limit in a time
97
+ */
98
+ public function set_threads_limit($val)
99
+ {
100
+ $this->_threads_limit = $val ;
101
+ }
102
+
103
+ /**
104
+ * Set load limit
105
+ *
106
+ * @since 1.1.0
107
+ * @access public
108
+ * @param int $val Server load limit to be checked before crawling
109
+ */
110
+ public function set_load_limit($val)
111
+ {
112
+ $this->_load_limit = $val ;
113
+ }
114
+
115
+ /**
116
+ * Get if last crawler touched end
117
+ *
118
+ * @since 1.1.0
119
+ * @access public
120
+ * @return bool|int False or last ended time
121
+ */
122
+ public function get_done_status()
123
+ {
124
+ if ( $this->read_meta() === true && $this->_meta['done'] === 'touchedEnd' ) {
125
+ return $this->_meta['last_full_time_cost'] + $this->_meta['this_full_beginning_time'] ;
126
+ }
127
+ return false ;
128
+ }
129
+
130
+ /**
131
+ * Refresh list_size in meta
132
+ *
133
+ * @since 1.1.0
134
+ * @access public
135
+ * @return boolean True if succeeded, false otherwise
136
+ */
137
+ public function refresh_list_size()
138
+ {
139
+ if ( $this->read_meta() === true ) {
140
+ $this->_meta['list_size'] = Litespeed_File::count_lines($this->_sitemap_file) ;
141
+ $this->save_meta() ;
142
+ }
143
+ return false ;
144
+ }
145
+
146
+ /**
147
+ * Create reset pos file
148
+ *
149
+ * @since 1.1.0
150
+ * @access public
151
+ * @return mixed True or error message
152
+ */
153
+ public function reset_pos()
154
+ {
155
+ return Litespeed_File::save( $this->_meta_file . '.reset', time() , true, false, false ) ;
156
+ }
157
+
158
+ /**
159
+ * Start crawler
160
+ *
161
+ * @since 1.1.0
162
+ * @access public
163
+ * @return string|bool crawled result
164
+ */
165
+ public function engine_start()
166
+ {
167
+ $ret = $this->read_meta() ;
168
+ if ( $ret !== true || ! $this->_meta ) {
169
+ return $this->_return($ret) ;
170
+ }
171
+
172
+ // check if is running
173
+ if ( $this->_meta['is_running'] && time() - $this->_meta['is_running'] < $this->_run_duration ) {
174
+ return $this->_return(__('Oh look, there is already another LiteSpeed crawler running!', 'litespeed-cache')) ;
175
+ }
176
+
177
+ // check current load
178
+ $this->_adjust_current_threads() ;
179
+ if ( $this->_cur_threads == 0 ) {
180
+ return $this->_return(__('Stopped due to load hit the maximum.', 'litespeed-cache')) ;
181
+ }
182
+
183
+ // log started time
184
+ $this->_meta['last_start_time'] = time() ;
185
+ $ret = $this->save_meta() ;
186
+ if ( $ret !== true ) {
187
+ return $this->_return($ret) ;
188
+ }
189
+ // set time limit
190
+ $maxTime = (int) ini_get('max_execution_time') ;
191
+ if ( $maxTime == 0 ) {
192
+ $maxTime = 300 ; // hardlimit
193
+ }
194
+ else {
195
+ $maxTime -= 5 ;
196
+ }
197
+ if ( $maxTime >= $this->_run_duration ) {
198
+ $maxTime = $this->_run_duration ;
199
+ }
200
+ elseif ( ini_set('max_execution_time', $this->_run_duration + 15 ) !== false ) {
201
+ $maxTime = $this->_run_duration ;
202
+ }
203
+ $this->_max_run_time = $maxTime + time() ;
204
+
205
+ // mark running
206
+ $this->_prepare_running() ;
207
+ $curlOptions = $this->_get_curl_options() ;
208
+ // run cralwer
209
+ $end_reason = $this->_do_running($curlOptions) ;
210
+ $this->_terminate_running($end_reason) ;
211
+
212
+ return $this->_return($end_reason) ;
213
+ }
214
+
215
+ /**
216
+ * Run crawler
217
+ *
218
+ * @since 1.1.0
219
+ * @access private
220
+ * @param array $curlOptions Curl options
221
+ * @return array array('error', 'blacklist')
222
+ */
223
+ private function _do_running($curlOptions)
224
+ {
225
+ while ( $urlChunks = Litespeed_File::read($this->_sitemap_file, $this->_meta['last_pos'], self::CHUNKS) ) {// get url list
226
+ // start crawling
227
+ $urlChunks = array_chunk($urlChunks, $this->_cur_threads) ;
228
+ foreach ( $urlChunks as $urls ) {
229
+ $urls = array_map('trim', $urls) ;
230
+ // multi curl
231
+ try {
232
+ $rets = $this->_multi_request($urls, $curlOptions) ;
233
+ } catch ( Exception $e ) {
234
+ return sprintf(__('Stopped due to error when crawling urls %1$s : %2$s', 'litespeed-cache'), implode(' ', $urls) , $e->getMessage()) ;
235
+ }
236
+
237
+ // check result headers
238
+ foreach ( $urls as $i => $url ) {
239
+ // check response
240
+ if ( stripos($rets[$i], "HTTP/1.1 428 Precondition Required") !== false ) {
241
+ return __('Stopped: crawler disabled by the server admin', 'litespeed-cache') ;
242
+ }
243
+ elseif ( stripos($rets[$i], "X-Litespeed-Cache-Control: no-cache") !== false ) {
244
+ $this->_blacklist[] = $url ;
245
+ }
246
+ elseif ( stripos($rets[$i], "HTTP/1.1 200 OK") === false && stripos($rets[$i], "HTTP/1.1 201 Created") === false ){
247
+ $this->_blacklist[] = $url ;
248
+ }
249
+ }
250
+
251
+ // update offset position
252
+ $_time = time() ;
253
+ $this->_meta['last_pos'] += $i + 1 ;
254
+ $this->_meta['last_count'] = $i + 1 ;
255
+ $this->_meta['last_crawled'] += $i + 1 ;
256
+ $this->_meta['last_update_time'] = $_time ;
257
+ $this->_meta['last_status'] = 'updated position' ;
258
+
259
+ // check duration
260
+ if ( $this->_meta['last_update_time'] > $this->_max_run_time ) {
261
+ return __('Stopped due to exceeding defined Maximum Run Time', 'litespeed-cache') ;
262
+ }
263
+
264
+ // make sure at least each 10s save meta once
265
+ if ( $_time - $this->_meta['meta_save_time'] > 10 ) {
266
+ $this->save_meta() ;
267
+ }
268
+
269
+ // check if need to reset pos each 5s
270
+ if ( $_time > $this->_meta['pos_reset_check'] ) {
271
+ $this->_meta['pos_reset_check'] = $_time + 5 ;
272
+ if ( file_exists($this->_meta_file . '.reset') && unlink($this->_meta_file . '.reset') ) {
273
+ $this->_meta['last_pos'] = 0 ;
274
+ // reset done status
275
+ $this->_meta['done'] = 0 ;
276
+ $this->_meta['this_full_beginning_time'] = 0 ;
277
+ return __('Stopped due to reset meta position', 'litespeed-cache') ;
278
+ }
279
+ }
280
+
281
+ // check loads
282
+ if ( $this->_meta['last_update_time'] - $this->_cur_thread_time > 60 ) {
283
+ $this->_adjust_current_threads() ;
284
+ if ( $this->_cur_threads == 0 ) {
285
+ return __('Stopped due to load over limit', 'litespeed-cache') ;
286
+ }
287
+ }
288
+
289
+ $this->_meta['last_status'] = 'sleeping ' . $this->_run_delay . 'ms' ;
290
+
291
+ usleep($this->_run_delay) ;
292
+ }
293
+ }
294
+
295
+ return true ;
296
+ }
297
+
298
+ /**
299
+ * Mark running status
300
+ *
301
+ * @since 1.1.0
302
+ * @access protected
303
+ */
304
+ protected function _prepare_running()
305
+ {
306
+ $this->_meta['is_running'] = time() ;
307
+ $this->_meta['done'] = 0 ;// reset done status
308
+ $this->_meta['last_status'] = 'prepare running' ;
309
+ $this->_meta['last_crawled'] = 0 ;
310
+ if ( $this->_meta['last_pos'] == 0 ) {
311
+ $this->_meta['this_full_beginning_time'] = time() ;
312
+ $this->_meta['list_size'] = Litespeed_File::count_lines($this->_sitemap_file) ;
313
+ }
314
+ $this->save_meta() ;
315
+ }
316
+
317
+ /**
318
+ * Terminate crawling
319
+ *
320
+ * @since 1.1.0
321
+ * @access protected
322
+ * @param string $end_reason The reason to terminate
323
+ */
324
+ protected function _terminate_running($end_reason)
325
+ {
326
+ if ( $end_reason === true ) {
327
+ $end_reason = __('Reached end of sitemap file. Crawling completed.', 'litespeed-cache') ;
328
+ $this->_meta['last_pos'] = 0 ;// reset last position
329
+ $this->_meta['done'] = 'touchedEnd' ;// log done status
330
+ $this->_meta['last_full_time_cost'] = time() - $this->_meta['this_full_beginning_time'] ;
331
+ }
332
+ $this->_meta['last_status'] = 'stopped' ;
333
+ $this->_meta['is_running'] = 0 ;
334
+ $this->_meta['end_reason'] = $end_reason ;
335
+ $this->save_meta() ;
336
+ }
337
+
338
+ /**
339
+ * Return crawler result
340
+ *
341
+ * @since 1.1.0
342
+ * @access protected
343
+ * @param string $end_reason Reason to end
344
+ * @return array The results of returning
345
+ */
346
+ protected function _return($end_reason)
347
+ {
348
+ return array(
349
+ 'error' => $end_reason === true ? false : $end_reason,
350
+ 'blacklist' => $this->_blacklist,
351
+ 'crawled' => $this->_meta['last_crawled'],
352
+ ) ;
353
+
354
+ }
355
+
356
+ /**
357
+ * Adjust threads dynamically
358
+ *
359
+ * @since 1.1.0
360
+ * @access protected
361
+ */
362
+ protected function _adjust_current_threads()
363
+ {
364
+ $load = sys_getloadavg() ;
365
+ $curload = 1 ;
366
+
367
+ if ( $this->_cur_threads == -1 ) {
368
+ // init
369
+ if ( $curload > $this->_load_limit ) {
370
+ $curthreads = 0 ;
371
+ }
372
+ elseif ( $curload >= ($this->_load_limit - 1) ) {
373
+ $curthreads = 1 ;
374
+ }
375
+ else {
376
+ $curthreads = intval($this->_load_limit - $curload) ;
377
+ if ( $curthreads > $this->_threads_limit ) {
378
+ $curthreads = $this->_threads_limit ;
379
+ }
380
+ }
381
+ }
382
+ else {
383
+ // adjust
384
+ $curthreads = $this->_cur_threads ;
385
+ if ( $curload >= $this->_load_limit + 1 ) {
386
+ sleep(5) ; // sleep 5 secs
387
+ if ( $curthreads >= 1 ) {
388
+ $curthreads -- ;
389
+ }
390
+ }
391
+ elseif ( $curload >= $this->_load_limit ) {
392
+ if ( $curthreads > 1 ) {// if already 1, keep
393
+ $curthreads -- ;
394
+ }
395
+ }
396
+ elseif ( ($curload + 1) < $this->_load_limit ) {
397
+ if ( $curthreads < $this->_threads_limit ) {
398
+ $curthreads ++ ;
399
+ }
400
+ }
401
+ }
402
+
403
+ // $log = 'set current threads = ' . $curthreads . ' previous=' . $this->_cur_threads
404
+ // . ' max_allowed=' . $this->_threads_limit . ' load_limit=' . $this->_load_limit . ' current_load=' . $curload;
405
+
406
+ $this->_cur_threads = $curthreads ;
407
+ $this->_cur_thread_time = time() ;
408
+ }
409
+
410
+ /**
411
+ * Send multi curl requests
412
+ *
413
+ * @since 1.1.0
414
+ * @access protected
415
+ * @param array $urls The url lists to send to
416
+ * @param array $options Curl options
417
+ * @return array Curl results
418
+ */
419
+ protected function _multi_request($urls, $options)
420
+ {
421
+ $mh = curl_multi_init() ;
422
+ $curls = array() ;
423
+ foreach ($urls as $i => $url) {
424
+ $curls[$i] = curl_init() ;
425
+ curl_setopt($curls[$i], CURLOPT_URL, $this->_baseUrl . $url) ;
426
+ curl_setopt_array($curls[$i], $options) ;
427
+ curl_multi_add_handle($mh, $curls[$i]) ;
428
+ }
429
+
430
+ // execute curl
431
+ $last_start_time = null ;
432
+ do {
433
+ curl_multi_exec($mh, $last_start_time) ;
434
+ if ( curl_multi_select($mh) == -1 ) {
435
+ usleep(1) ;
436
+ }
437
+ } while ($last_start_time > 0) ;
438
+
439
+ // curl done
440
+ $ret = array() ;
441
+ foreach ($urls as $i => $url) {
442
+ $thisCurl = $curls[$i] ;
443
+ $ret[] = curl_multi_getcontent($thisCurl) ;
444
+
445
+ curl_multi_remove_handle($mh, $thisCurl) ;
446
+ curl_close($thisCurl) ;
447
+ }
448
+ curl_multi_close($mh) ;
449
+
450
+ return $ret ;
451
+ }
452
+
453
+ /**
454
+ * Get curl_options
455
+ *
456
+ * @since 1.1.0
457
+ * @access private
458
+ * @param string $ua as user-agent
459
+ * @return options array
460
+ */
461
+ private function _get_curl_options($ua = '')
462
+ {
463
+ $referer = null ;
464
+ if ( isset($_SERVER['HTTP_HOST']) && isset($_SERVER['REQUEST_URI']) ) {
465
+ $referer = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] ;
466
+ }
467
+
468
+ $options = array(
469
+ CURLOPT_RETURNTRANSFER => true,
470
+ CURLOPT_HEADER => true,
471
+ CURLOPT_CUSTOMREQUEST => 'GET',
472
+ CURLOPT_FOLLOWLOCATION => false,
473
+ CURLOPT_ENCODING => 'gzip',
474
+ CURLOPT_CONNECTTIMEOUT => 10,
475
+ CURLOPT_TIMEOUT => 10,
476
+ CURLOPT_SSL_VERIFYHOST => 0,
477
+ CURLOPT_SSL_VERIFYPEER => false,
478
+ CURLOPT_NOBODY => false,
479
+ CURL_HTTP_VERSION_1_1 => 1,
480
+ CURLOPT_HTTPHEADER => array(),
481
+ ) ;
482
+ $options[CURLOPT_HTTPHEADER][] = "Cache-Control: max-age=0" ;
483
+
484
+ if ( ! $ua ) {
485
+ $ua = self::FAST_USER_AGENT ;
486
+ }
487
+ $options[CURLOPT_USERAGENT] = $ua ;
488
+
489
+ if ( $this->_domain_ip && $this->_baseUrl ) {
490
+ $parsed_url = parse_url($this->_baseUrl) ;
491
+
492
+ if ( !empty($parsed_url['host']) ) {
493
+ // assign domain for curl
494
+ $options[CURLOPT_HTTPHEADER][] = "Host: " . $parsed_url['host'] ;
495
+ // replace domain with direct ip
496
+ $parsed_url['host'] = $this->_domain_ip ;
497
+ $this->_baseUrl = http_build_url($parsed_url) ;
498
+ }
499
+ }
500
+
501
+ // if is walker
502
+ // $options[CURLOPT_FRESH_CONNECT] = true ;
503
+
504
+ if ( !empty($referer) ) {
505
+ $options[CURLOPT_REFERER] = $referer ;
506
+ }
507
+
508
+ return $options ;
509
+ }
510
+
511
+ /**
512
+ * Save existing meta
513
+ *
514
+ * @since 1.1.0
515
+ * @access public
516
+ * @return mixed True or error message
517
+ */
518
+ public function save_meta()
519
+ {
520
+ $this->_meta[ 'meta_save_time' ] = time() ;
521
+
522
+ $ret = Litespeed_File::save( $this->_meta_file, json_encode( $this->_meta ), false, false, false ) ;
523
+ return $ret ;
524
+ }
525
+
526
+ /**
527
+ * Read existing meta
528
+ *
529
+ * @since 1.1.0
530
+ * @access public
531
+ * @return mixed True or error message
532
+ */
533
+ public function read_meta()
534
+ {
535
+ // get current meta info
536
+ $meta = Litespeed_File::read($this->_meta_file) ;
537
+ if ( $meta === false ) {
538
+ return sprintf(__('Cannot read meta file: %s', 'litespeed-cache'), $this->_meta_file) ;
539
+ }
540
+
541
+ if ( $meta && $meta = json_decode($meta, true) ) {
542
+ // check if sitemap changed since last time
543
+ if ( ! isset($meta['file_time']) || $meta['file_time'] < filemtime($this->_sitemap_file) ) {
544
+ $meta['file_time'] = filemtime($this->_sitemap_file) ;
545
+ $meta['last_pos'] = 0 ;
546
+ }
547
+ }
548
+ else {
549
+ // initialize meta
550
+ $meta = array(
551
+ 'list_size' => Litespeed_File::count_lines($this->_sitemap_file),
552
+ 'last_update_time' => 0,
553
+ 'last_pos' => 0,
554
+ 'last_count' => 0,
555
+ 'last_crawled' => 0,
556
+ 'last_start_time' => 0,
557
+ 'last_status' => '',
558
+ 'is_running' => 0,
559
+ 'end_reason' => '',
560
+ 'meta_save_time' => 0,
561
+ 'pos_reset_check' => 0,
562
+ 'done' => 0,
563
+ 'this_full_beginning_time' => 0,
564
+ 'last_full_time_cost' => 0,
565
+ ) ;
566
+ }
567
+
568
+ $this->_meta = $meta ;
569
+
570
+ return true ;
571
+ }
572
+
573
+ }
lib/litespeed/litespeed-file.class.php ADDED
@@ -0,0 +1,400 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * LiteSpeed File Operator Library Class
4
+ * Append/Replace content to a file
5
+ *
6
+ * @since 1.1.0
7
+ */
8
+
9
+ function litespeed_exception_error_handler($errno, $errstr, $errfile, $errline )
10
+ {
11
+ throw new ErrorException($errstr, 0, $errno, $errfile, $errline) ;
12
+ }
13
+
14
+ class Litespeed_File
15
+ {
16
+ const MARKER = 'LiteSpeed Operator' ;
17
+
18
+ function __construct()
19
+ {
20
+ // nothing to do here
21
+ }
22
+
23
+ public static function count_lines($filename)
24
+ {
25
+ if ( ! file_exists($filename) ) {
26
+ return 0 ;
27
+ }
28
+
29
+ $file = new SplFileObject($filename) ;
30
+ $file->seek(PHP_INT_MAX) ;
31
+ return $file->key() + 1 ;
32
+ }
33
+
34
+ /**
35
+ * Read data from file
36
+ *
37
+ * @since 1.1.0
38
+ * @param string $filename
39
+ * @param int $start_line
40
+ * @param int $lines
41
+ */
42
+ public static function read($filename, $start_line = null, $lines = null)
43
+ {
44
+ if ( ! file_exists($filename) ) {
45
+ return '' ;
46
+ }
47
+
48
+ if ( ! is_readable($filename) ) {
49
+ return false ;
50
+ }
51
+
52
+ if ( $start_line !== null ) {
53
+ $res = array() ;
54
+ $file = new SplFileObject($filename) ;
55
+ $file->seek($start_line) ;
56
+
57
+ if ( $lines === null) {
58
+ while ( ! $file->eof() ) {
59
+ $res[] = rtrim($file->current(), "\n") ;
60
+ $file->next() ;
61
+ }
62
+ }
63
+ else{
64
+ for ( $i=0 ; $i < $lines ; $i++ ) {
65
+ if ( $file->eof() ) {
66
+ break ;
67
+ }
68
+ $res[] = rtrim($file->current(), "\n") ;
69
+ $file->next() ;
70
+ }
71
+ }
72
+
73
+ unset($file) ;
74
+ return $res ;
75
+ }
76
+
77
+ return file_get_contents($filename) ;
78
+ }
79
+
80
+ /**
81
+ * Append data to file
82
+ *
83
+ * @since 1.1.5
84
+ * @access public
85
+ * @param string $filename
86
+ * @param string $data
87
+ * @param boolean $mkdir
88
+ * @param boolean $silence Used to avoid WP's functions are used
89
+ */
90
+ public static function append( $filename, $data, $mkdir = false, $silence = true )
91
+ {
92
+ return self::save( $filename, $data, $mkdir, true, $silence ) ;
93
+ }
94
+
95
+ /**
96
+ * Save data to file
97
+ *
98
+ * @since 1.1.0
99
+ * @param string $filename
100
+ * @param string $data
101
+ * @param boolean $mkdir
102
+ * @param boolean $append If the content needs to be appended
103
+ * @param boolean $silence Used to avoid WP's functions are used
104
+ */
105
+ public static function save( $filename, $data, $mkdir = false, $append = false, $silence = true )
106
+ {
107
+ $error = false ;
108
+ $folder = dirname( $filename ) ;
109
+
110
+ // mkdir if folder does not exist
111
+ if ( ! file_exists( $folder ) ) {
112
+ if ( ! $mkdir ) {
113
+ return $silence ? false : sprintf( __( 'Folder does not exist: %s', 'litespeed-cache' ), $folder ) ;
114
+ }
115
+
116
+ set_error_handler( 'litespeed_exception_error_handler' ) ;
117
+
118
+ try {
119
+ mkdir( $folder, 0755, true ) ;
120
+ }
121
+ catch ( ErrorException $ex ) {
122
+ return $silence ? false : sprintf( __( 'Can not create folder: %1$s. Error: %2$s', 'litespeed-cache' ), $folder, $ex->getMessage() ) ;
123
+ }
124
+
125
+ restore_error_handler() ;
126
+ }
127
+
128
+ if ( ! file_exists( $filename ) ) {
129
+ if ( ! is_writable( $folder ) ) {
130
+ return $silence ? false : sprintf( __( 'Folder is not writable: %s.', 'litespeed-cache' ), $folder ) ;
131
+ }
132
+ set_error_handler( 'litespeed_exception_error_handler' ) ;
133
+ try {
134
+ touch( $filename ) ;
135
+ }
136
+ catch ( ErrorException $ex ){
137
+ return $silence ? false : sprintf( __( 'File %s is not writable.', 'litespeed-cache' ), $filename ) ;
138
+ }
139
+ restore_error_handler() ;
140
+ }
141
+ elseif ( ! is_writeable( $filename ) ) {
142
+ return $silence ? false : sprintf( __( 'File %s is not writable.', 'litespeed-cache' ), $filename ) ;
143
+ }
144
+
145
+ $ret = file_put_contents( $filename, $data, $append ? FILE_APPEND : LOCK_EX ) ;
146
+ if ( $ret === false ) {
147
+ return $silence ? false : sprintf( __( 'Failed to write to %s.', 'litespeed-cache' ), $filename ) ;
148
+ }
149
+
150
+ return true ;
151
+ }
152
+
153
+ /**
154
+ * Appends an array of strings into a file (.htaccess ), placing it between
155
+ * BEGIN and END markers.
156
+ *
157
+ * Replaces existing marked info. Retains surrounding
158
+ * data. Creates file if none exists.
159
+ *
160
+ * @param string $filename Filename to alter.
161
+ * @param string $marker The marker to alter.
162
+ * @param array|string $insertion The new content to insert.
163
+ * @param bool $prepend Prepend insertion if not exist.
164
+ * @return bool True on write success, false on failure.
165
+ */
166
+ public static function insert_with_markers($filename, $insertion = false, $marker = false, $prepend = false)
167
+ {
168
+ if ( !$marker ) {
169
+ $marker = self::MARKER ;
170
+ }
171
+
172
+ if ( !$insertion ) {
173
+ $insertion = array() ;
174
+ }
175
+
176
+ return self::_insert_with_markers($filename, $marker, $insertion, $prepend) ;
177
+ }
178
+
179
+ /**
180
+ * Return wrapped block data with marker
181
+ *
182
+ * @param string $insertion
183
+ * @param string $marker
184
+ * @return string The block data
185
+ */
186
+ public static function wrap_marker_data($insertion, $marker = false)
187
+ {
188
+ if ( ! $marker ) {
189
+ $marker = self::MARKER ;
190
+ }
191
+ $start_marker = "# BEGIN {$marker}" ;
192
+ $end_marker = "# END {$marker}" ;
193
+
194
+ $new_data = implode( "\n", array_merge(
195
+ array( $start_marker ),
196
+ $insertion,
197
+ array( $end_marker )
198
+ ) ) ;
199
+ return $new_data ;
200
+ }
201
+
202
+ /**
203
+ * Touch block data from file, return with marker
204
+ *
205
+ * @param string $filename
206
+ * @param string $marker
207
+ * @return string The current block data
208
+ */
209
+ public static function touch_marker_data($filename, $marker = false)
210
+ {
211
+ if( ! $marker ) {
212
+ $marker = self::MARKER ;
213
+ }
214
+
215
+ $result = self::_extract_from_markers($filename, $marker) ;
216
+
217
+ if( ! $result ) {
218
+ return false ;
219
+ }
220
+
221
+ $start_marker = "# BEGIN {$marker}" ;
222
+ $end_marker = "# END {$marker}" ;
223
+ $new_data = implode( "\n", array_merge(
224
+ array( $start_marker ),
225
+ $result,
226
+ array( $end_marker )
227
+ ) ) ;
228
+ return $new_data ;
229
+ }
230
+
231
+ /**
232
+ * Extracts strings from between the BEGIN and END markers in the .htaccess file.
233
+ *
234
+ * @param string $filename
235
+ * @param string $marker
236
+ * @return array An array of strings from a file (.htaccess ) from between BEGIN and END markers.
237
+ */
238
+ public static function extract_from_markers($filename, $marker = false)
239
+ {
240
+ if( ! $marker ) {
241
+ $marker = self::MARKER ;
242
+ }
243
+ return self::_extract_from_markers($filename, $marker) ;
244
+ }
245
+
246
+ /**
247
+ * Extracts strings from between the BEGIN and END markers in the .htaccess file.
248
+ *
249
+ * @param string $filename
250
+ * @param string $marker
251
+ * @return array An array of strings from a file (.htaccess ) from between BEGIN and END markers.
252
+ */
253
+ private static function _extract_from_markers( $filename, $marker )
254
+ {
255
+ $result = array () ;
256
+
257
+ if (!file_exists($filename) ) {
258
+ return $result ;
259
+ }
260
+
261
+ if ( $markerdata = explode( "\n", implode( '', file($filename) ) ) ) {
262
+ $state = false ;
263
+ foreach ( $markerdata as $markerline ) {
264
+ if ( strpos($markerline, '# END ' . $marker) !== false ) {
265
+ $state = false ;
266
+ }
267
+ if ( $state ) {
268
+ $result[] = $markerline ;
269
+ }
270
+ if (strpos($markerline, '# BEGIN ' . $marker) !== false) {
271
+ $state = true ;
272
+ }
273
+ }
274
+ }
275
+
276
+ return array_map('trim', $result) ;
277
+ }
278
+
279
+ /**
280
+ * Inserts an array of strings into a file (.htaccess ), placing it between
281
+ * BEGIN and END markers.
282
+ *
283
+ * Replaces existing marked info. Retains surrounding
284
+ * data. Creates file if none exists.
285
+ *
286
+ * @param string $filename Filename to alter.
287
+ * @param string $marker The marker to alter.
288
+ * @param array|string $insertion The new content to insert.
289
+ * @param bool $prepend Prepend insertion if not exist.
290
+ * @return bool True on write success, false on failure.
291
+ */
292
+ private static function _insert_with_markers( $filename, $marker, $insertion, $prepend = false)
293
+ {
294
+ if ( ! file_exists($filename) ) {
295
+ if ( ! is_writable( dirname($filename) ) ) {
296
+ return false ;
297
+ }
298
+ set_error_handler("litespeed_exception_error_handler") ;
299
+ try {
300
+ touch($filename) ;
301
+ }
302
+ catch ( ErrorException $ex ){
303
+ return false ;
304
+ }
305
+ restore_error_handler() ;
306
+ }
307
+ elseif ( ! is_writeable($filename) ) {
308
+ return false ;
309
+ }
310
+
311
+ if ( ! is_array($insertion) ) {
312
+ $insertion = explode( "\n", $insertion ) ;
313
+ }
314
+
315
+ $start_marker = "# BEGIN {$marker}" ;
316
+ $end_marker = "# END {$marker}" ;
317
+
318
+ $fp = fopen($filename, 'r+' ) ;
319
+ if ( ! $fp ) {
320
+ return false ;
321
+ }
322
+
323
+ // Attempt to get a lock. If the filesystem supports locking, this will block until the lock is acquired.
324
+ flock( $fp, LOCK_EX ) ;
325
+
326
+ $lines = array() ;
327
+ while ( ! feof($fp) ) {
328
+ $lines[] = rtrim(fgets($fp), "\r\n" ) ;
329
+ }
330
+
331
+ // Split out the existing file into the preceding lines, and those that appear after the marker
332
+ $pre_lines = $post_lines = $existing_lines = array() ;
333
+ $found_marker = $found_end_marker = false ;
334
+ foreach ( $lines as $line ) {
335
+ if ( ! $found_marker && false !== strpos($line, $start_marker) ) {
336
+ $found_marker = true ;
337
+ continue ;
338
+ }
339
+ elseif ( ! $found_end_marker && false !== strpos($line, $end_marker) ) {
340
+ $found_end_marker = true ;
341
+ continue ;
342
+ }
343
+
344
+ if ( ! $found_marker ) {
345
+ $pre_lines[] = $line ;
346
+ }
347
+ elseif ( $found_marker && $found_end_marker ) {
348
+ $post_lines[] = $line ;
349
+ }
350
+ else {
351
+ $existing_lines[] = $line ;
352
+ }
353
+ }
354
+
355
+ // Check to see if there was a change
356
+ if ( $existing_lines === $insertion ) {
357
+ flock($fp, LOCK_UN) ;
358
+ fclose($fp) ;
359
+
360
+ return true ;
361
+ }
362
+
363
+ // Check if need to prepend data if not exist
364
+ if( $prepend && ! $post_lines ) {
365
+ // Generate the new file data
366
+ $new_file_data = implode( "\n", array_merge(
367
+ array( $start_marker ),
368
+ $insertion,
369
+ array( $end_marker ),
370
+ $pre_lines
371
+ ) ) ;
372
+
373
+ }
374
+ else {
375
+ // Generate the new file data
376
+ $new_file_data = implode( "\n", array_merge(
377
+ $pre_lines,
378
+ array( $start_marker ),
379
+ $insertion,
380
+ array( $end_marker ),
381
+ $post_lines
382
+ ) ) ;
383
+ }
384
+
385
+
386
+ // Write to the start of the file, and truncate it to that length
387
+ fseek($fp, 0) ;
388
+ $bytes = fwrite($fp, $new_file_data) ;
389
+ if ( $bytes ) {
390
+ ftruncate($fp, ftell($fp)) ;
391
+ }
392
+ fflush($fp) ;
393
+ flock($fp, LOCK_UN) ;
394
+ fclose($fp) ;
395
+
396
+ return (bool) $bytes ;
397
+ }
398
+ }
399
+
400
+
litespeed-cache.php ADDED
@@ -0,0 +1,140 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The plugin bootstrap file
4
+ *
5
+ * This file is read by WordPress to generate the plugin information in the plugin
6
+ * admin area. This file also includes all of the dependencies used by the plugin,
7
+ * registers the activation and deactivation functions, and defines a function
8
+ * that starts the plugin.
9
+ *
10
+ * @link https://www.litespeedtech.com
11
+ * @since 1.0.0
12
+ * @package LiteSpeed_Cache
13
+ *
14
+ * @wordpress-plugin
15
+ * Plugin Name: LiteSpeed Cache
16
+ * Plugin URI: https://www.litespeedtech.com/products/cache-plugins/wordpress-acceleration
17
+ * Description: WordPress plugin to connect to LSCache on LiteSpeed Web Server.
18
+ * Version: 1.1.6
19
+ * Author: LiteSpeed Technologies
20
+ * Author URI: https://www.litespeedtech.com
21
+ * License: GPLv3
22
+ * License URI: http://www.gnu.org/licenses/gpl.html
23
+ * Text Domain: litespeed-cache
24
+ * Domain Path: /languages
25
+ *
26
+ * Copyright (C) 2015-2017 LiteSpeed Technologies, Inc.
27
+ *
28
+ * This program is free software: you can redistribute it and/or modify
29
+ * it under the terms of the GNU General Public License as published by
30
+ * the Free Software Foundation, either version 3 of the License, or
31
+ * (at your option) any later version.
32
+ *
33
+ * This program is distributed in the hope that it will be useful,
34
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
35
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
36
+ * GNU General Public License for more details.
37
+ *
38
+ * You should have received a copy of the GNU General Public License
39
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
40
+
41
+ */
42
+ // If this file is called directly, abort.
43
+ if ( ! defined( 'WPINC' ) ) {
44
+ die ;
45
+ }
46
+
47
+ if ( class_exists( 'LiteSpeed_Cache' ) || defined( 'LSWCP_DIR' ) ) {
48
+ return ;
49
+ }
50
+
51
+ define( 'LSWCP_CONTENT_DIR', dirname( get_theme_root() ) ) ;
52
+ define( 'LSWCP_DIR', plugin_dir_path( __FILE__ ) ) ;// Full absolute path '/usr/local/lsws/***/wp-content/plugins/litespeed-cache/'
53
+ define( 'LSWCP_BASENAME', plugin_basename( LSWCP_DIR . 'litespeed-cache.php' ) ) ;//LSWCP_BASENAME='litespeed-cache/litespeed-cache.php'
54
+
55
+ // Auto register LiteSpeed classes
56
+ require_once LSWCP_DIR . 'includes/litespeed.autoload.php' ;
57
+
58
+ if ( LiteSpeed_Cache_Router::is_cli() ) {
59
+ WP_CLI::add_command( 'lscache-admin', 'LiteSpeed_Cache_Cli_Admin' ) ;
60
+ WP_CLI::add_command( 'lscache-purge', 'LiteSpeed_Cache_Cli_Purge' ) ;
61
+ }
62
+
63
+ if ( ! defined( 'LITESPEED_SERVER_TYPE' ) ) {
64
+ if ( isset( $_SERVER['HTTP_X_LSCACHE'] ) && $_SERVER['HTTP_X_LSCACHE'] ) {
65
+ define( 'LITESPEED_SERVER_TYPE', 'LITESPEED_SERVER_ADC' ) ;
66
+ }
67
+ elseif ( isset( $_SERVER['LSWS_EDITION'] ) && strncmp( $_SERVER['LSWS_EDITION'], 'Openlitespeed', 13 ) == 0 ) {
68
+ define( 'LITESPEED_SERVER_TYPE', 'LITESPEED_SERVER_OLS' ) ;
69
+ }
70
+ elseif ( isset( $_SERVER['SERVER_SOFTWARE'] ) && $_SERVER['SERVER_SOFTWARE'] == 'LiteSpeed' ) {
71
+ define( 'LITESPEED_SERVER_TYPE', 'LITESPEED_SERVER_ENT' ) ;
72
+ }
73
+ else {
74
+ define( 'LITESPEED_SERVER_TYPE', 'NONE' ) ;
75
+ }
76
+ }
77
+
78
+ // ESI const defination
79
+ if ( ! defined( 'LSWCP_ESI_SUPPORT' ) ) {
80
+ define( 'LSWCP_ESI_SUPPORT', LITESPEED_SERVER_TYPE !== 'LITESPEED_SERVER_OLS' ? false : false ) ;
81
+ }
82
+
83
+ if ( ! defined( 'LSWCP_TAG_PREFIX' ) ) {
84
+ define( 'LSWCP_TAG_PREFIX', substr( md5( LSWCP_DIR ), -3 ) ) ;
85
+ }
86
+
87
+ /**
88
+ * Begins execution of the plugin.
89
+ *
90
+ * Since everything within the plugin is registered via hooks,
91
+ * then kicking off the plugin from this point in the file does
92
+ * not affect the page life cycle.
93
+ *
94
+ * @since 1.0.0
95
+ */
96
+ if ( ! function_exists( 'run_litespeed_cache' ) ) {
97
+ function run_litespeed_cache()
98
+ {
99
+ $version_supported = true ;
100
+
101
+ //Check minimum PHP requirements, which is 5.3 at the moment.
102
+ if ( version_compare( PHP_VERSION, '5.3.0', '<' ) ) {
103
+ error_log( LiteSpeed_Cache_Admin_Display::get_error( LiteSpeed_Cache_Admin_Error::E_PHP_VER ) ) ;
104
+ $version_supported = false ;
105
+ }
106
+
107
+ //Check minimum WP requirements, which is 4.0 at the moment.
108
+ if ( version_compare( $GLOBALS['wp_version'], '4.0', '<' ) ) {
109
+ error_log( LiteSpeed_Cache_Admin_Display::get_error( LiteSpeed_Cache_Admin_Error::E_WP_VER ) ) ;
110
+ $version_supported = false ;
111
+ }
112
+
113
+ if ( $version_supported ) {
114
+ LiteSpeed_Cache::get_instance() ;
115
+ }
116
+ }
117
+
118
+ run_litespeed_cache() ;
119
+ }
120
+
121
+ /**
122
+ * Easier API for Purging a single post.
123
+ *
124
+ * If a third party plugin needs to purge a single post, it can send
125
+ * a purge tag using this function.
126
+ *
127
+ * @since 1.0.1
128
+ * @access public
129
+ * @param integer $id The post id to purge.
130
+ */
131
+ if ( ! function_exists( 'litespeed_purge_single_post' ) ) {
132
+ function litespeed_purge_single_post( $id )
133
+ {
134
+ $post_id = intval( $id ) ;
135
+ if ( ! in_array( get_post_status( $post_id ), array( 'publish', 'trash' ) ) ) {
136
+ return ;
137
+ }
138
+ LiteSpeed_Cache_Purge::add( LiteSpeed_Cache_Tag::TYPE_POST . $post_id ) ;
139
+ }
140
+ }
readme.txt ADDED
@@ -0,0 +1,517 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ === LiteSpeed Cache ===
2
+ Contributors: LiteSpeedTech
3
+ Tags: caching, cache, performance, optimization, wp-cache, busting, wordpress cache busting, litespeed, http2, woo, yoast, wordfence, contact, Contact Form 7, varnish, widget, litespeed web server, lsws, availability, pagespeed, woocommerce, bbpress, nextgengallery, wp-polls, wptouch, customization, plugin, rewrite, scalability, speed, multisite, cpanel, openlitespeed, ols, google, optimize, wp-super-cache, w3total cache, w3totalcache, w3 total cache, wp super cache, wp rocket
4
+ Requires at least: 4.0
5
+ Tested up to: 4.8.1
6
+ Stable tag: 1.1.6
7
+ License: GPLv3
8
+ License URI: http://www.gnu.org/licenses/gpl.html
9
+
10
+ Quickly and easily implement high-performance page caching on your WordPress site with the ultra-efficient LiteSpeed Cache.
11
+
12
+ == Description ==
13
+
14
+ The LiteSpeed Cache Plugin for WordPress (LSCWP) is a PHP-based plugin that communicates with your installation of LiteSpeed Web Server (LSWS) and its built-in page cache, LSCache.
15
+
16
+ Because LSCache is built directly into LSWS, overhead is significantly reduced and caching can be done more efficiently than with other PHP-based caches.
17
+
18
+ = Installation =
19
+
20
+ 1. Install `LiteSpeed Web Server Enterprise` (LSWS) or `OpenLiteSeed` (OLS) [Free].
21
+
22
+ 2. Install `LiteSpeed Cache` and activate.
23
+
24
+ 3. Goto `LiteSpeed Cache` -> `Settings`, make sure the option `Enable LiteSpeed Cache` is `Enable`.
25
+
26
+ 4. Enjoy!
27
+
28
+ = Instructions for LiteSpeed Web Server Enterprise (LSWS) =
29
+
30
+ 1. Make sure that your license includes the LSCache module enabled. A [2-CPU trial license with LSCache module](https://www.litespeedtech.com/products/litespeed-web-server/download/get-a-trial-license "trial license") is available for free for 15 days.
31
+
32
+ 2. The server must be configured to have caching enabled. If you are the server admin, [click here](https://www.litespeedtech.com/support/wiki/doku.php/litespeed_wiki:cache:common_installation#web_server_configuration). Otherwise request that the server admin configure the cache root for the server.
33
+
34
+ = Instructions for OpenLiteSpeed (OLS) =
35
+
36
+ * This integration utilizes OLS's cache module.
37
+
38
+ * If it is a fresh OLS installation, the easiest way to integrate is to use [ols1clk](http://open.litespeedtech.com/mediawiki/index.php/Help:1-Click_Install). If using an existing WordPress installation, use the --wordpresspath parameter.
39
+
40
+ * If OLS and WordPress are already installed, please follow the instructions [How To Set Up LSCache For WordPress](http://open.litespeedtech.com/mediawiki/index.php/Help:How_To_Set_Up_LSCache_For_WordPress).
41
+
42
+ Additional plugin features:
43
+
44
+ * Automatic page caching greatly improves site performance
45
+ * Automatically purge related pages based on certain events
46
+ * Smart preload crawler with support to SEO friendly sitemap
47
+ * Cache logged in users with private cache
48
+ * Cache WordPress REST API calls
49
+ * Cache desktop and mobile views separately
50
+ * Scheduled Purge URLs at a certain time
51
+ * Support for HTTP/2 & HTTPS out-of-box
52
+ * Single Site and Multi Sites support
53
+ * Supports WooCommerce and bbPress
54
+ * Simple API system that enables other plugins to easily integrate with cache and operate cache functionalities.
55
+ * No Cache configuration by URI, Categories, Tags, Cookies, and User Agents
56
+ * Works with LiteSpeed Web ADC in clustered environments.
57
+ * Nice looking :)
58
+
59
+ = Known Compatible Plugins =
60
+
61
+ * [bbPress](https://wordpress.org/plugins/bbpress/)
62
+ * [WooCommerce](https://wordpress.org/plugins/woocommerce/)
63
+ * [Contact Form 7](https://wordpress.org/plugins/contact-form-7/)
64
+ * [Google XML Sitemaps](https://wordpress.org/plugins/google-sitemap-generator/)
65
+ * [Yoast SEO](https://wordpress.org/plugins/wordpress-seo/)
66
+ * [Wordfence Security](https://wordpress.org/plugins/wordfence/)
67
+ * [NextGen Gallery](https://wordpress.org/plugins/nextgen-gallery/)
68
+ * <a href="https://shortpixel.com/h/af/CXNO4OI28044" rel="friend noopener noreferer" target="_blank">ShortPixel</a>
69
+ * Aelia CurrencySwitcher
70
+ * [Fast Velocity Minify](https://wordpress.org/plugins/fast-velocity-minify/) - Thanks Raul Peixoto!
71
+ * [Autoptimize](https://wordpress.org/plugins/autoptimize/)
72
+ * [Better WP Minify](https://wordpress.org/plugins/bwp-minify/)
73
+ * [WP Touch](https://wordpress.org/plugins/wptouch/)
74
+ * [Theme My Login](https://wordpress.org/plugins/theme-my-login/)
75
+ * [wpForo](https://wordpress.org/plugins/wpforo/)
76
+ * [WPLister](https://www.wplab.com/plugins/wp-lister/)
77
+ * [Avada 5.1 RC1+](https://avada.theme-fusion.com/)
78
+ * [WP-PostRatings](https://wordpress.org/plugins/wp-postratings/)
79
+ * [Elegant Themes Divi 3.0.67+]
80
+
81
+ = Known Uncompatible Plugins =
82
+
83
+ * No known uncompatible plugins at this time.
84
+
85
+ For support visit [WordPress LiteSpeed Support Forums](https://wordpress.org/support/plugin/litespeed-cache "WordPress LiteSpeed forums"), [LiteSpeedWiki](https://www.litespeedtech.com/support/wiki/doku.php/litespeed_wiki:cache:lscwp "wiki"), or email us at info@litespeedtech.com.
86
+
87
+ = How to test the plugin =
88
+
89
+ The LiteSpeed Cache Plugin utilizes LiteSpeed specific response headers. Visiting a page for the first time should result in a `X-LiteSpeed-Cache-Control:miss` or `X-LiteSpeed-Cache-Control:no-cache` response header for the page. Subsequent requests should have the `X-LiteSpeed-Cache-Control:hit` response header until the page is updated, expired, or purged. Please visit [LiteSpeed Cache Plugin Testing](https://www.litespeedtech.com/support/wiki/doku.php/litespeed_wiki:cache:lscwp:installation#testing) for more information.
90
+
91
+ == Frequently Asked Questions ==
92
+
93
+ = Is the LiteSpeed Cache Plugin for WordPress free? =
94
+
95
+ Yes, the plugin itself will remain free and open source. That said, a LiteSpeed server is required (see question 2).
96
+
97
+ = What server software is required for this plugin? =
98
+
99
+ A LiteSpeed server is required in order to use this plugin.
100
+
101
+ 1. LiteSPeed Web Server Enterprise with LSCache Module (v5.0.10+)
102
+
103
+ 2. OpenLiteSpeed (v1.4.17+)
104
+
105
+ 3. LiteSpeed WebADC (v2.0+)
106
+
107
+ Any single server or cluster including a LiteSpeed server will work.
108
+
109
+ = Does this plugin work in a clustered environment? =
110
+
111
+ The cache entries are stored at the litespeed server level. The simplest solution is to use LiteSpeed WebADC, as the cache entries will be cached at that level.
112
+
113
+ If using another load balancer, the cache entries will only be stored at the backend nodes, not at the load balancer.
114
+
115
+ The purges will also not be synchronized across the nodes, so this is not recommended.
116
+
117
+ If a customized solution is required, please contact LiteSpeed Technologies at info@litespeedtech.com
118
+
119
+ NOTICE: The rewrite rules created by this plugin must be copied to the Load Balancer.
120
+
121
+ = Where are the cached files stored? =
122
+
123
+ The actual cached pages are stored and managed by LiteSpeed Servers.
124
+
125
+ Nothing is stored on the PHP side.
126
+
127
+ = Does LiteSpeed Cache for WordPress work with OpenLiteSpeed? =
128
+
129
+ Yes it can work well with OpenLiteSpeed. As well, any settings changes that require modifying the .htaccess file requires a server restart.
130
+
131
+ = Is WooCommerce supported? =
132
+
133
+ In short, yes. However, for some woocommerce themes, the cart may not be updated correctly.
134
+
135
+ To test the cart:
136
+
137
+ 1. On a non-logged-in browser, visit and cache a page, then visit and cache a product page.
138
+
139
+ 2. The first page should be accessible from the product page (e.g. the shop).
140
+
141
+ 3. Once both pages are confirmed cached, add the product to your cart.
142
+
143
+ 4. After adding to the cart, visit the first page.
144
+
145
+ 5. The page should still be cached, and the cart should be up to date.
146
+
147
+ 6. If that is not the case, please add woocommerce_items_in_cart to the do not cache cookie list.
148
+
149
+ Some themes like Storefront and Shop Isle are built such that the cart works without the rule.
150
+
151
+ However, other themes like the E-Commerce theme, do not, so please verify the theme used.
152
+
153
+ = My plugin has some pages that are not cacheable. How do I instruct the LiteSpeed Cache Plugin to not cache the page? =
154
+
155
+ As of version 1.0.10, you may simply add `define('LSCACHE_NO_CACHE', true);` sometime before the shutdown hook, and it should be recognized by the cache.
156
+
157
+ Alternatively, you may use the function xxx`LiteSpeed_Cache_Tags::set_noncacheable();` for earlier versions (1.0.7+).
158
+
159
+ If using the function, make sure to check that the class exists prior to using the function.
160
+
161
+ Please visit the [Other Notes tab](https://wordpress.org/plugins/litespeed-cache/other_notes/) for more information.
162
+
163
+ = Are my images optimized? =
164
+
165
+ The cache plugin does not do anything with the images themselves.
166
+
167
+ We recommend you trying an image optimization plugin like <a href="https://shortpixel.com/h/af/CXNO4OI28044" rel="friend noopener noreferer" target="_blank">ShortPixel</a> to optimize your images. It can reduce your site's images up to 90%.
168
+
169
+ = How do I get WP-PostViews to display an updating view count? =
170
+
171
+ 1. Use: `<div id="postviews_lscwp"></div>`
172
+
173
+ to replace
174
+
175
+ `<?php if(function_exists('the_views')) { the_views(); } ?>`
176
+
177
+ * NOTE: The id can be changed, but the div id and the ajax function must match.
178
+
179
+ 2. Replace the ajax query in `wp-content/plugins/wp-postviews/postviews-cache.js` with
180
+
181
+ ```
182
+ jQuery.ajax({
183
+ type:"GET",
184
+ url:viewsCacheL10n.admin_ajax_url,
185
+ data:"postviews_id="+viewsCacheL10n.post_id+"&action=postviews",
186
+ cache:!1,
187
+ success:function(data) {
188
+ if(data) {
189
+ jQuery('#postviews_lscwp').html(data+' views');
190
+ }
191
+ }
192
+ });
193
+ ```
194
+
195
+ 3. Purge the cache to use the updated pages.
196
+
197
+ = How do I enable the crawler? =
198
+
199
+ The crawler is disabled by default, and must be enabled by the server admin first.
200
+
201
+ Then, you can enable crawler from "LiteSpeed Cache" -> "Crawler".
202
+
203
+ For more detailed information about crawler setup, please see [our blog post on the subject](https://blog.litespeedtech.com/2017/06/14/wpw-crawl-your-site-make-it-fly/).
204
+
205
+
206
+ == Plugin Developers ==
207
+
208
+ [Latest LiteSpeed Cache plugin for WordPress API Documentation for Plugin Developers](https://www.litespeedtech.com/support/wiki/doku.php/litespeed_wiki:cache:lscwp:api)
209
+
210
+ [LiteSpeed Cache plugin for WordPress GitHub](https://github.com/litespeedtech/lscache_wp/)
211
+
212
+ == Screenshots ==
213
+
214
+ 1. Admin Settings - General
215
+ 2. Admin Settings - Cache
216
+ 3. Admin Settings - Purge
217
+ 4. Admin Settings - Excludes
218
+ 5. Admin Settings - Debug
219
+ 6. Admin Settings - Crawler
220
+ 7. Admin Management Page
221
+ 8. Admin Information Page
222
+ 9. Admin Crawler Status Page
223
+ 10. Cache Miss Example
224
+ 11. Cache Hit Example
225
+
226
+ == Changelog ==
227
+
228
+ = 1.1.6 - August 23 2017 =
229
+ * [NEW FEATURE] Added option to privately cache logged-in users.
230
+ * [NEW FEATURE] Added option to privately cache commenters.
231
+ * [NEW FEATURE] Added option to cache requests made through WordPress REST API.
232
+ * [BUGFIX] Fixed network 3rd-party full-page cache detection bug.
233
+ * [GUI] New Cache and Purge menus in Settings.
234
+
235
+ = 1.1.5.1 - August 16 2017 =
236
+ * [IMPROVEMENT] Improved compatibility of frontend&backend .htaccess path detection when site url is different than installation path.
237
+ * [UPDATE] Removed unused format string from header tags.
238
+ * [BUGFIX] 'showheader' Admin Query String now works.
239
+ * [REFACTOR] Cache tags will no longer output if not needed.
240
+
241
+ = 1.1.5 - August 10 2017 =
242
+ * [NEW FEATURE] Scheduled Purge URLs feature.
243
+ * [NEW FEATURE] Added buffer callback to improve compatibility with some plugins that force buffer cleaning.
244
+ * [NEW FEATURE] Hide purge_all admin bar quick link if cache is disabled.
245
+ * [NEW FEATURE] Required htaccess rules are now displayed when .htaccess is not writable.
246
+ * [NEW FEATURE] Debug log features: filter log support; heartbeat control; log file size limit; log viewer.
247
+ * [IMPROVEMENT] Separate crawler access log.
248
+ * [IMPROVEMENT] Lazy PURGE requests made after output are now queued and working.
249
+ * [IMPROVEMENT] Improved readme.txt with keywords relating to our compatible plugins list.
250
+ * [UPDATE] 'ExpiresDefault' conflict msg is now closeable and only appears in the .htaccess edit screen.
251
+ * [UPDATE] Improved debug log formatting.
252
+ * [INTEGRATION] Compatibility with MainWP plugin.
253
+ * [BUGFIX] Fixed Woocommerce order not purging product stock quantity.
254
+ * [BUGFIX] Fixed Woocommerce scheduled sale price not updating issue.
255
+ * [REFACTOR] Combined cache_enable functions into a single function.
256
+
257
+ = 1.1.4 - August 1 2017 =
258
+ * [IMPROVEMENT] Unexpected rewrite rules will now show an error message.
259
+ * [IMPROVEMENT] Added Cache Tag Prefix setting info in the Env Report and Info page.
260
+ * [IMPROVEMENT] LSCWP setting link is now displayed in the plugin list.
261
+ * [IMPROVEMENT] Improved performance when setting cache control.
262
+ * [UPDATE] Added backward compatibility for v1.1.2.2 API calls. (used by 3rd-party plugins)
263
+ * [BUGFIX] Fixed WPCLI purge tag/category never succeeding.
264
+
265
+ = 1.1.3 - July 31 2017 =
266
+ * [NEW FEATURE] New LiteSpeed_Cache_API class and documentation for 3rd party integration.
267
+ * [NEW FEATURE] New API function litespeed_purge_single_post($post_id).
268
+ * [NEW FEATURE] PHP CLI support for crawler.
269
+ * [IMPROVEMENT] Set 'no cache' for same location 301 redirects.
270
+ * [IMPROVEMENT] Improved LiteSpeed footer comment compatibility.
271
+ * [UPDATE] Removed 'cache tag prefix' setting.
272
+ * [BUGFIX] Fixed a bug involving CLI purge all.
273
+ * [BUGFIX] Crawler now honors X-LiteSpeed-Cache-Control for the 'no-cache' header.
274
+ * [BUGFIX] Cache/rewrite rules are now cleared when the plugin is uninstalled.
275
+ * [BUGFIX] Prevent incorrect removal of the advanced-cache.php on deactivation if it was added by another plugin.
276
+ * [BUGFIX] Fixed subfolder WP installations being unable to Purge By URL using a full URL path.
277
+ * [REFACTOR] Reorganized existing code for an upcoming ESI release.
278
+
279
+ = 1.1.2.2 - July 13 2017 =
280
+ * [BUGFIX] Fixed blank page in Hebrew language post editor by removing unused font-awesome and jquery-ui css libraries.
281
+
282
+ = 1.1.2.1 - July 5 2017 =
283
+ * [UPDATE] Improved compatibility with WooCommerce v3.1.0.
284
+
285
+ = 1.1.2 - June 20 2017 =
286
+ * [BUGFIX] Fixed missing form close tag.
287
+ * [UPDATE] Added a wiki link for enabling the crawler.
288
+ * [UPDATE] Improved Site IP description.
289
+ * [UPDATE] Added an introduction to the crawler on the Information page.
290
+ * [REFACTOR] Added more detailed error messages for Site IP and Custom Sitemap settings.
291
+
292
+ = 1.1.1.1 - June 15 2017 =
293
+ * [BUGFIX] Hotfix for insufficient validation of site IP value in crawler settings.
294
+
295
+ = 1.1.1 - June 15 2017 =
296
+ * [NEW] As of LiteSpeed Web Server v.5.1.16, the crawler can now be enabled/disabled at the server level.
297
+ * [NEW] Added the ability to provide a custom sitemap for crawling.
298
+ * [NEW] Added ability to use site IP address directly in crawler settings.
299
+ * [NEW] Crawler performance improved with the use of new custom user agent 'lsrunner'.
300
+ * [NEW] "Purge By URLs" now supports full URL paths.
301
+ * [NEW] Added thirdparty WP-PostRatings compatibility.
302
+ * [BUGFIX] Cache is now cleared when changing post status from published to draft.
303
+ * [BUGFIX] WHM activation message no longer continues to reappear after being dismissed.
304
+ * [COSMETIC] Display recommended values for settings.
305
+
306
+ = 1.1.0.1 - June 8 2017 =
307
+ * [UPDATE] Improved default crawler interval setting.
308
+ * [UPDATE] Tested up to WP 4.8.
309
+ * [BUGFIX] Fixed compatibility with plugins that output json data.
310
+ * [BUGFIX] Fixed tab switching bug.
311
+ * [BUGFIX] Removed occasional duplicated messages on save.
312
+ * [COSMETIC] Improved crawler tooltips and descriptions.
313
+
314
+ = 1.1.0 - June 6 2017 =
315
+ * [NEW] Added a crawler - this includes configuration options and a dedicated admin page. Uses wp-cron
316
+ * [NEW] Added integration for WPLister
317
+ * [NEW] Added integration for Avada
318
+ * [UPDATE] General structure of the plugin revamped
319
+ * [UPDATE] Improved look of admin pages
320
+ * [BUGFIX] Fix any/all wp-content path retrieval issues
321
+ * [BUGFIX] Use realpath to clear symbolic link when determining .htaccess paths
322
+ * [BUGFIX] Fixed a bug where upgrading multiple plugins did not trigger a purge all
323
+ * [BUGFIX] Fixed a bug where cli import_options did not actually update the options.
324
+ * [REFACTOR] Most of the files in the code were split into more, smaller files
325
+
326
+ = 1.0.15 - April 20 2017 =
327
+ * [NEW] Added Purge Pages and Purge Recent Posts Widget pages options.
328
+ * [NEW] Added wp-cli command for setting and getting options.
329
+ * [NEW] Added an import/export options cli command.
330
+ * [NEW] Added wpForo integration.
331
+ * [NEW] Added Theme My Login integration.
332
+ * [UPDATE] Purge adjacent posts when publish a new post.
333
+ * [UPDATE] Change environment report file to .php and increase security.
334
+ * [UPDATE] Added new purgeby option to wp-cli.
335
+ * [UPDATE] Remove nag for multiple sites.
336
+ * [UPDATE] Only inject LiteSpeed javascripts in LiteSpeed pages.
337
+ * [REFACTOR] Properly check for zero in ttl settings.
338
+ * [BUGFIX] Fixed the 404 issue that can be caused by some certain plugins when save the settings.
339
+ * [BUGFIX] Fixed mu-plugin compatibility.
340
+ * [BUGFIX] Fixed problem with creating zip backup.
341
+ * [BUGFIX] Fixed conflict with jetpack.
342
+
343
+ = 1.0.14.1 - January 31 2017 =
344
+ * [UPDATE] Removed Freemius integration due to feedback.
345
+
346
+ = 1.0.14 - January 30 2017 =
347
+ * [NEW] Added error page caching. Currently supports 403, 404, 500s.
348
+ * [NEW] Added a purge errors action.
349
+ * [NEW] Added wp-cli integration.
350
+ * [UPDATE] Added support for multiple varies.
351
+ * [UPDATE] Reorganize the admin interface to be less cluttered.
352
+ * [UPDATE] Add support for LiteSpeed Web ADC.
353
+ * [UPDATE] Add Freemius integration.
354
+ * [REFACTOR] Made some changes so that the rewrite rules are a little more consistent.
355
+ * [BUGFIX] Check member type before adding purge all button.
356
+ * [BUGFIX] Fixed a bug where activating/deactivating the plugin quickly caused the WP_CACHE error to show up.
357
+ * [BUGFIX] Handle more characters in the rewrite parser.
358
+ * [BUGFIX] Correctly purge posts when they are made public/private.
359
+
360
+ = 1.0.13.1 - November 30 2016 =
361
+ * [BUGFIX] Fixed a bug where a global was being used without checking existence first, causing unnecessary log entries.
362
+
363
+ = 1.0.13 - November 28 2016 =
364
+ * [NEW] Add an Empty Entire Cache button.
365
+ * [NEW] Add stale logic to certain purge actions.
366
+ * [NEW] Add option to use primary site settings for all subsites in a multisite environment.
367
+ * [NEW] Add support for Aelia CurrencySwitcher
368
+ * [UPDATE] Add logic to allow third party vary headers
369
+ * [UPDATE] Handle password protected pages differently.
370
+ * [BUGFIX] Fixed bug caused by saving settings.
371
+ * [BUGFIX] FIxed bug when searching for advanced-cache.php
372
+
373
+ = 1.0.12 - November 14 2016 =
374
+ * [NEW] Added logic to generate environment reports.
375
+ * [NEW] Created a notice that will be triggered when the WHM Plugin installs this plugin. This will notify users when the plugin is installed by their server admin.
376
+ * [NEW] Added the option to cache 404 pages via 404 Page TTL setting.
377
+ * [NEW] Reworked log system to be based on selection of yes or no instead of log level.
378
+ * [NEW] Added support for Autoptimize.
379
+ * [NEW] Added Better WP Minify integration.
380
+ * [UPDATE] On plugin disable, clear .htaccess.
381
+ * [UPDATE] Introduced URL tag. Changed Purge by URL to use this new tag.
382
+ * [BUGFIX] Fixed a bug triggered when .htaccess files were empty.
383
+ * [BUGFIX] Correctly determine when to clear files in multisite environments (wp-config, advanced-cache, etc.).
384
+ * [BUGFIX] When disabling the cache, settings changed in the same save will now be saved.
385
+ * [BUGFIX] Various bugs from setting changes and multisite fixed.
386
+ * [BUGFIX] Fixed two bugs with the .htaccess path search.
387
+ * [BUGFIX] Do not alter $_GET in add_quick_purge. This may cause issues for functionality occurring later in the same request.
388
+ * [BUGFIX] Right to left radio settings were incorrectly displayed. The radio buttons themselves were the opposite direction of the associated text.
389
+
390
+ = 1.0.11 - October 11 2016 =
391
+ * [NEW] The plugin will now set cachelookup public on.
392
+ * [NEW] New option - check advanced-cache.php. This enables users to have two caching plugins enabled at the same time as long as the other plugin is not used for caching purposes. For example, using another cache plugin for css/js minification.
393
+ * [UPDATE] Rules added by the plugin will now be inserted into an LSCACHE START/END PLUGIN comment block.
394
+ * [UPDATE] For woocommerce pages, if a user visits a non-cached page with a non-empty cart, do not cache the page.
395
+ * [UPDATE] If woocommerce needs to display any notice, do not cache the page.
396
+ * [UPDATE] Single site settings are now in both the litespeed cache submenu and the settings submenu.
397
+ * [BUGFIX] Multisite network options were not updated on upgrade. This is now corrected.
398
+
399
+ = 1.0.10 - September 16 2016 =
400
+ * Added a check for LSCACHE_NO_CACHE definition.
401
+ * Added a Purge All button to the admin bar.
402
+ * Added logic to purge the cache when upgrading a plugin or theme. By default this is enabled on single site installations and disabled on multisite installations.
403
+ * Added support for WooCommerce Versions < 2.5.0.
404
+ * Added .htaccess backup rotation. Every 10 backups, an .htaccess archive will be created. If one already exists, it will be overwritten.
405
+ * Moved some settings to the new Specific Pages tab to reduce clutter in the General tab.
406
+ * The .htaccess editor is now disabled if DISALLOW_FILE_EDIT is set.
407
+ * After saving the Cache Tag Prefix setting, all cache will be purged.
408
+
409
+ = 1.0.9.1 - August 26 2016 =
410
+ * Fixed a bug where an error displayed on the configuration screen despite not being an error.
411
+ * Change logic to check .htaccess file less often.
412
+
413
+ = 1.0.9 - August 25 2016 =
414
+ * [NEW] Added functionality to cache and purge feeds.
415
+ * [NEW] Added cache tag prefix setting to avoid conflicts when using LiteSpeed Cache for WordPress with LiteSpeed Cache for XenForo and LiteMage.
416
+ * [NEW] Added hooks to allow third party plugins to create config options.
417
+ * [NEW] Added WooCommerce config options.
418
+ * The plugin now also checks for wp-config in the parent directory.
419
+ * Improved WooCommerce support.
420
+ * Changed .htaccess backup process. Will create a .htaccess_lscachebak_orig file if one does not exist. If it does already exist, creates a backup using the date and timestamp.
421
+ * Fixed a bug where get_home_path() sometimes returned an invalid path.
422
+ * Fixed a bug where if the .htaccess was removed from a WordPress subdirectory, it was not handled properly.
423
+
424
+ = 1.0.8.1 - July 28 2016 =
425
+ * Fixed a bug where check cacheable was sometimes not hit.
426
+ * Fixed a bug where extra slashes in clear rules were stripped.
427
+
428
+ = 1.0.8 - July 25 2016 =
429
+ * Added purge all on update check to purge by post id logic.
430
+ * Added uninstall logic.
431
+ * Added configuration for caching favicons.
432
+ * Added configuration for caching the login page.
433
+ * Added configuration for caching php resources (scripts/stylesheets accessed as .php).
434
+ * Set login cookie if user is logged in and it isn’t set.
435
+ * Improved NextGenGallery support to include new actions.
436
+ * Now displays a notice on the network admin if WP_CACHE is not set.
437
+ * Fixed a few php syntax issues.
438
+ * Fixed a bug where purge by pid didn’t work.
439
+ * Fixed a bug where the Network Admin settings were shown when the plugin was active in a subsite, but not network active.
440
+ * Fixed a bug where the Advanced Cache check would sometimes not work.
441
+
442
+ = 1.0.7.1 - May 26 2016 =
443
+ * Fixed a bug where enabling purge all in the auto purge on update settings page did not purge the correct blogs.
444
+ * Fixed a bug reported by user wpc on our forums where enabling purge all in the auto purge on update settings page caused nothing to be cached.
445
+
446
+ = 1.0.7 - May 24 2016 =
447
+ * Added login cookie configuration to the Advanced Settings page.
448
+ * Added support for WPTouch plugin.
449
+ * Added support for WP-Polls plugin.
450
+ * Added Like Dislike Counter third party integration.
451
+ * Added support for Admin IP Query String Actions.
452
+ * Added confirmation pop up for purge all.
453
+ * Refactor: LiteSpeed_Cache_Admin is now split into LiteSpeed_Cache_Admin, LiteSpeed_Cache_Admin_Display, and LiteSpeed_Cache_Admin_Rules
454
+ * Refactor: Rename functions to accurately represent their functionality
455
+ * Fixed a bug that sometimes caused a “no valid header” error message.
456
+
457
+ = 1.0.6 - May 5 2016 =
458
+ * Fixed a bug reported by Knut Sparhell that prevented dashboard widgets from being opened or closed.
459
+ * Fixed a bug reported by Knut Sparhell that caused problems with https support for admin pages.
460
+
461
+ = 1.0.5 - April 26 2016 =
462
+ * [BETA] Added NextGen Gallery plugin support.
463
+ * Added third party plugin integration.
464
+ * Improved cache tag system.
465
+ * Improved formatting for admin settings pages.
466
+ * Converted bbPress to use the new third party integration system.
467
+ * Converted WooCommerce to use the new third party integration system.
468
+ * If .htaccess is not writable, disable separate mobile view and do not cache cookies/user agents.
469
+ * Cache is now automatically purged when disabled.
470
+ * Fixed a bug where .htaccess was not checked properly when adding common rules.
471
+ * Fixed a bug where multisite setups would be completely purged when one site requested a purge all.
472
+
473
+ = 1.0.4 - April 7 2016 =
474
+ * Added logic to cache commenters.
475
+ * Added htaccess backup to the install script.
476
+ * Added an htaccess editor in the wp-admin dashboard.
477
+ * Added do not cache user agents.
478
+ * Added do not cache cookies.
479
+ * Created new LiteSpeed Cache Settings submenu entries.
480
+ * Implemented Separate Mobile View.
481
+ * Modified WP_CACHE not defined message to only show up for users who can manage options.
482
+ * Moved enabled all/disable all from network management to network settings.
483
+ * Fixed a bug where WP_CACHE was not defined on activation if it was commented out.
484
+
485
+ = 1.0.3 - March 23 2016 =
486
+ * Added a Purge Front Page button to the LiteSpeed Cache Management page.
487
+ * Added a Default Front Page TTL option to the general settings.
488
+ * Added ability to define web application specific cookie names through rewrite rules to handle logged-in cookie conflicts when using multiple web applications. <strong>[Requires LSWS 5.0.15+]</strong>
489
+ * Improved WooCommerce handling.
490
+ * Fixed a bug where activating lscwp sets the “enable cache” radio button to enabled, but the cache was not enabled by default.
491
+ * Refactored code to make it cleaner.
492
+ * Updated readme.txt.
493
+
494
+ = 1.0.2 - March 11 2016 =
495
+ * Added a "Use Network Admin Setting" option for "Enable LiteSpeed Cache". For single sites, this choice will default to enabled.
496
+ * Added enable/disable all buttons for network admin. This controls the setting of all managed sites with "Use Network Admin Setting" selected for "Enable LiteSpeed Cache".
497
+ * Exclude by Category/Tag are now text areas to avoid slow load times on the LiteSpeed Cache Settings page for sites with a large number of categories/tags.
498
+ * Added a new line to advanced-cache.php to allow identification as a LiteSpeed Cache file.
499
+ * Activation/Deactivation are now better handled in multi-site environments.
500
+ * Enable LiteSpeed Cache setting is now a radio button selection instead of a single checkbox.
501
+ * Can now add '$' to the end of a URL in Exclude URI to perform an exact match.
502
+ * The _lscache_vary cookie will now be deleted upon logout.
503
+ * Fixed a bug in multi-site setups that would cause a "function already defined" error.
504
+
505
+ = 1.0.1 - March 8 2016 =
506
+ * Added Do Not Cache by URI, by Category, and by Tag. URI is a prefix/string equals match.
507
+ * Added a help tab for plugin compatibilities.
508
+ * Created logic for other plugins to purge a single post if updated.
509
+ * Fixed a bug where woocommerce pages that display the cart were cached.
510
+ * Fixed a bug where admin menus in multi-site setups were not correctly displayed.
511
+ * Fixed a bug where logged in users were served public cached pages.
512
+ * Fixed a compatibility bug with bbPress. If there is a new forum/topic/reply, the parent pages will now be purged as well.
513
+ * Fixed a bug that didn't allow cron job to update scheduled posts.
514
+
515
+ = 1.0.0 - January 20 2016 =
516
+ * Initial Release.
517
+
thirdparty/lscwp-3rd-aelia-currencyswitcher.cls.php ADDED
@@ -0,0 +1,89 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * The Third Party integration with the Aelia CurrencySwitcher plugin.
5
+ *
6
+ * @since 1.0.13
7
+ * @package LiteSpeed_Cache
8
+ * @subpackage LiteSpeed_Cache/thirdparty
9
+ * @author LiteSpeed Technologies <info@litespeedtech.com>
10
+ */
11
+ if ( ! defined('ABSPATH') ) {
12
+ die() ;
13
+ }
14
+
15
+ LiteSpeed_Cache_API::register('LiteSpeed_Cache_ThirdParty_Aelia_CurrencySwitcher') ;
16
+
17
+ class LiteSpeed_Cache_ThirdParty_Aelia_CurrencySwitcher
18
+ {
19
+ private static $_cookies = array(
20
+ 'aelia_cs_selected_currency',
21
+ 'aelia_customer_country',
22
+ 'aelia_customer_state',
23
+ 'aelia_tax_exempt',
24
+ ) ;
25
+
26
+ /**
27
+ * Detects if WooCommerce is installed.
28
+ *
29
+ * @since 1.0.13
30
+ * @access public
31
+ * @global $GLOBALS;
32
+ */
33
+ public static function detect()
34
+ {
35
+ if ( defined('WOOCOMMERCE_VERSION') && isset($GLOBALS['woocommerce-aelia-currencyswitcher']) && is_object($GLOBALS['woocommerce-aelia-currencyswitcher']) ) {
36
+ LiteSpeed_Cache_API::hook_control('LiteSpeed_Cache_ThirdParty_Aelia_CurrencySwitcher::check_cookies') ;
37
+ LiteSpeed_Cache_API::hook_vary('LiteSpeed_Cache_ThirdParty_Aelia_CurrencySwitcher::get_vary') ;
38
+ }
39
+ }
40
+
41
+ /**
42
+ * If the page is not a woocommerce page, ignore the logic.
43
+ * Else check cookies. If cookies are set, set the vary headers, else do not cache the page.
44
+ *
45
+ * @since 1.0.13
46
+ * @access public
47
+ */
48
+ public static function check_cookies()
49
+ {
50
+ if ( LiteSpeed_Cache_API::not_cacheable() ) {
51
+ return ;
52
+ }
53
+
54
+ // NOTE: is_cart and is_checkout should also be checked, but will be checked by woocommerce anyway.
55
+ if ( ! is_woocommerce() ) {
56
+ return ;
57
+ }
58
+
59
+ if ( isset($_COOKIE) && ! empty($_COOKIE) ) {
60
+ foreach (self::$_cookies as $cookie) {
61
+ if ( ! empty($_COOKIE[$cookie]) ) {
62
+ LiteSpeed_Cache_API::vary_add(self::$_cookies) ;
63
+ return ;
64
+ }
65
+ }
66
+ }
67
+
68
+ LiteSpeed_Cache_API::set_nocache() ;
69
+ }
70
+
71
+ /**
72
+ * Hooked to the litespeed_cache_get_vary filter.
73
+ *
74
+ * If Aelia Currency Switcher is enabled, will need to add their cookies
75
+ * to the vary array.
76
+ *
77
+ * @since 1.0.14
78
+ * @access public
79
+ * @param array $vary_arr The current list of vary cookies.
80
+ * @return array The updated list of vary cookies.
81
+ */
82
+ public static function get_vary($vary_arr)
83
+ {
84
+ if ( ! is_array($vary_arr) ) {
85
+ return $vary_arr ;
86
+ }
87
+ return array_merge($vary_arr, self::$_cookies) ;
88
+ }
89
+ }
thirdparty/lscwp-3rd-autoptimize.cls.php ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * The Third Party integration with the Autoptimize plugin.
5
+ *
6
+ * @since 1.0.12
7
+ * @package LiteSpeed_Cache
8
+ * @subpackage LiteSpeed_Cache/thirdparty
9
+ * @author LiteSpeed Technologies <info@litespeedtech.com>
10
+ */
11
+ if ( ! defined('ABSPATH') ) {
12
+ die() ;
13
+ }
14
+ LiteSpeed_Cache_API::register('LiteSpeed_Cache_ThirdParty_Autoptimize') ;
15
+
16
+ class LiteSpeed_Cache_ThirdParty_Autoptimize
17
+ {
18
+ /**
19
+ * Detects if Autoptimize is active.
20
+ *
21
+ *@since 1.0.12
22
+ *@access public
23
+ */
24
+ public static function detect()
25
+ {
26
+ if ( defined('AUTOPTIMIZE_PLUGIN_DIR') ) {
27
+ LiteSpeed_Cache_API::hook_purge('LiteSpeed_Cache_ThirdParty_Autoptimize::purge') ;
28
+ }
29
+ }
30
+
31
+ /**
32
+ * Purges the cache when Autoptimize's cache is purged.
33
+ *
34
+ * @since 1.0.12
35
+ * @access public
36
+ */
37
+ public static function purge()
38
+ {
39
+ if ( defined('AUTOPTIMIZE_PURGE') || has_action('shutdown', 'autoptimize_do_cachepurged_action', 11) ) {
40
+ LiteSpeed_Cache_API::purge_all() ;
41
+ }
42
+ }
43
+ }
thirdparty/lscwp-3rd-avada.cls.php ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * The Third Party integration with the Avada plugin.
5
+ *
6
+ * @since 1.1.0
7
+ * @package LiteSpeed_Cache
8
+ * @subpackage LiteSpeed_Cache/thirdparty
9
+ * @author LiteSpeed Technologies <info@litespeedtech.com>
10
+ */
11
+ if (!defined('ABSPATH')) {
12
+ die();
13
+ }
14
+ LiteSpeed_Cache_API::register('LiteSpeed_Cache_ThirdParty_Avada') ;
15
+
16
+ class LiteSpeed_Cache_ThirdParty_Avada
17
+ {
18
+ /**
19
+ * Detects if Avada is installed.
20
+ *
21
+ * @since 1.1.0
22
+ * @access public
23
+ */
24
+ public static function detect()
25
+ {
26
+ if ( ! defined('AVADA_VERSION') ) {
27
+ return ;
28
+ }
29
+
30
+ add_action('update_option_avada_dynamic_css_posts', 'LiteSpeed_Cache_ThirdParty_Avada::flush') ;
31
+ add_action('update_option_fusion_options', 'LiteSpeed_Cache_ThirdParty_Avada::flush') ;
32
+ }
33
+
34
+ /**
35
+ * Purges the cache
36
+ *
37
+ * @since 1.1.0
38
+ * @access public
39
+ */
40
+ public static function flush()
41
+ {
42
+ LiteSpeed_Cache_API::purge_all() ;
43
+ }
44
+
45
+ }
46
+
thirdparty/lscwp-3rd-bbpress.cls.php ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * The Third Party integration with the bbPress plugin.
5
+ *
6
+ * @since 1.0.5
7
+ * @package LiteSpeed_Cache
8
+ * @subpackage LiteSpeed_Cache/thirdparty
9
+ * @author LiteSpeed Technologies <info@litespeedtech.com>
10
+ */
11
+ if ( ! defined('ABSPATH') ) {
12
+ die() ;
13
+ }
14
+ LiteSpeed_Cache_API::register('LiteSpeed_Cache_ThirdParty_BBPress') ;
15
+
16
+ class LiteSpeed_Cache_ThirdParty_BBPress
17
+ {
18
+ /**
19
+ * Detect if bbPress is installed and if the page is a bbPress page.
20
+ *
21
+ * @since 1.0.5
22
+ * @access public
23
+ */
24
+ public static function detect()
25
+ {
26
+ if ( function_exists('is_bbpress') ) {
27
+ LiteSpeed_Cache_API::hook_purge_post('LiteSpeed_Cache_ThirdParty_BBPress::on_purge') ;
28
+ }
29
+ }
30
+
31
+ /**
32
+ * When a bbPress page is purged, need to purge the forums list and
33
+ * any/all ancestor pages.
34
+ *
35
+ * @since 1.0.5
36
+ * @access public
37
+ * @param integer $post_id The post id of the page being purged.
38
+ */
39
+ public static function on_purge($post_id)
40
+ {
41
+ if ( ! is_bbpress() && ! bbp_is_forum($post_id) && ! bbp_is_topic($post_id) && ! bbp_is_reply($post_id) ) {
42
+ return ;
43
+ }
44
+
45
+ // Need to purge base forums page, bbPress page was updated.
46
+ LiteSpeed_Cache_API::purge(LiteSpeed_Cache_API::TYPE_ARCHIVE_POSTTYPE . bbp_get_forum_post_type()) ;
47
+ $ancestors = get_post_ancestors($post_id) ;
48
+
49
+ // If there are ancestors, need to purge them as well.
50
+ if ( ! empty($ancestors) ) {
51
+ foreach ($ancestors as $ancestor) {
52
+ LiteSpeed_Cache_API::purge(LiteSpeed_Cache_API::TYPE_POST . $ancestor) ;
53
+ }
54
+ }
55
+
56
+ global $wp_widget_factory;
57
+ if ( bbp_is_reply($post_id) && ! is_null($wp_widget_factory->widgets['BBP_Replies_Widget']) ) {
58
+ LiteSpeed_Cache_API::purge(LiteSpeed_Cache_API::TYPE_WIDGET . $wp_widget_factory->widgets['BBP_Replies_Widget']->id) ;
59
+ }
60
+ if (bbp_is_topic($post_id) && ! is_null($wp_widget_factory->widgets['BBP_Topics_Widget']) ) {
61
+ LiteSpeed_Cache_API::purge(LiteSpeed_Cache_API::TYPE_WIDGET . $wp_widget_factory->widgets['BBP_Topics_Widget']->id) ;
62
+ }
63
+ }
64
+ }
65
+
thirdparty/lscwp-3rd-betterwp-minify.cls.php ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The Third Party integration with the Better WP Minify plugin.
4
+ *
5
+ * @since 1.0.12
6
+ * @package LiteSpeed_Cache
7
+ * @subpackage LiteSpeed_Cache/thirdparty
8
+ * @author LiteSpeed Technologies <info@litespeedtech.com>
9
+ */
10
+ if ( ! defined('ABSPATH') ) {
11
+ die() ;
12
+ }
13
+ LiteSpeed_Cache_API::register('LiteSpeed_Cache_ThirdParty_Better_WP_Minify') ;
14
+
15
+ class LiteSpeed_Cache_ThirdParty_Better_WP_Minify
16
+ {
17
+ /**
18
+ * Detects if Better WP Minify is active.
19
+ *
20
+ * @since 1.0.12
21
+ * @access public
22
+ *
23
+ */
24
+ public static function detect()
25
+ {
26
+ if ( class_exists('BWP_MINIFY') ) {
27
+ add_action('toplevel_page_bwp_minify_general', 'LiteSpeed_Cache_ThirdParty_Better_WP_Minify::maybe_flush', 9) ;
28
+ }
29
+ }
30
+
31
+ /**
32
+ * Hooked to the toplevel_page_bwp_minify_general action.
33
+ *
34
+ * Will check parts of the request to see if the cache should be flushed.
35
+ * Will register functions to purge the cache if needed.
36
+ *
37
+ * @since 1.0.12
38
+ * @access public
39
+ */
40
+ public static function maybe_flush()
41
+ {
42
+ if ( ! empty($_POST) && (isset($_POST['flush_cache']) || isset($_POST['save_flush'])) && ! BWP_MINIFY::is_normal_admin() ) {
43
+ add_action('check_admin_referer', 'LiteSpeed_Cache_ThirdParty_Better_WP_Minify::flush') ;
44
+ add_action('bwp_option_action_before_submit_button', 'LiteSpeed_Cache_ThirdParty_Better_WP_Minify::clear_flush') ;
45
+ }
46
+ }
47
+
48
+ /**
49
+ * Purges the cache when Better WP Minify needs to purge.
50
+ *
51
+ * @since 1.0.12
52
+ * @access public
53
+ */
54
+ public static function flush()
55
+ {
56
+ LiteSpeed_Cache_API::purge_all() ;
57
+ self::clear_flush() ;
58
+ }
59
+
60
+ /**
61
+ * Clears the flush cache callbacks.
62
+ *
63
+ * @since 1.0.12
64
+ * @access public
65
+ */
66
+ public static function clear_flush()
67
+ {
68
+ remove_action('check_admin_referer', 'LiteSpeed_Cache_ThirdParty_Better_WP_Minify::flush') ;
69
+ remove_action('bwp_option_action_before_submit_button', 'LiteSpeed_Cache_ThirdParty_Better_WP_Minify::clear_flush') ;
70
+ }
71
+
72
+ }
thirdparty/lscwp-3rd-like-dislike-counter.cls.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * The Third Party integration with the Like Dislike Counter plugin.
5
+ *
6
+ * @since 1.0.7
7
+ * @package LiteSpeed_Cache
8
+ * @subpackage LiteSpeed_Cache/thirdparty
9
+ * @author LiteSpeed Technologies <info@litespeedtech.com>
10
+ */
11
+ if ( ! defined('ABSPATH') ) {
12
+ die() ;
13
+ }
14
+
15
+ /**
16
+ * NOTICE: Since this plugin doesn't set the DOING_AJAX global during its
17
+ * Ajax request, we do not know when the request is an ajax request.
18
+ *
19
+ * This solution works for now, but is not the optimal way of handling this.
20
+ */
21
+ if ( function_exists('ldclite_get_version') && $_POST && isset($_POST['up_type']) ) {
22
+ LiteSpeed_Cache_API::hook_purge('LiteSpeed_Cache_ThirdParty_Like_Dislike_Counter::purge') ;
23
+ }
24
+
25
+ class LiteSpeed_Cache_ThirdParty_Like_Dislike_Counter
26
+ {
27
+ /**
28
+ * Need to purge the post after someone 'likes' or 'dislikes' the post.
29
+ */
30
+ public static function purge()
31
+ {
32
+ if ( isset($_POST['post_id']) ) {
33
+ LiteSpeed_Cache_API::purge(LiteSpeed_Cache_API::TYPE_POST . $_POST['post_id']) ;
34
+ }
35
+ }
36
+
37
+ }
38
+
thirdparty/lscwp-3rd-nextgengallery.cls.php ADDED
@@ -0,0 +1,215 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * The Third Party integration with the NextGen Gallery plugin.
5
+ *
6
+ * @since 1.0.5
7
+ * @package LiteSpeed_Cache
8
+ * @subpackage LiteSpeed_Cache/thirdparty
9
+ * @author LiteSpeed Technologies <info@litespeedtech.com>
10
+ */
11
+ if ( ! defined('ABSPATH') ) {
12
+ die() ;
13
+ }
14
+ add_action('load_nextgen_gallery_modules', 'LiteSpeed_Cache_ThirdParty_NextGenGallery::detect') ;
15
+
16
+ class LiteSpeed_Cache_ThirdParty_NextGenGallery
17
+ {
18
+ const CACHETAG_ALBUMS = 'NGG_A.' ;
19
+ const CACHETAG_GALLERIES = 'NGG_G.' ;
20
+ const CACHETAG_TAGS = 'NGG_T.' ;
21
+
22
+ /**
23
+ * Detect is triggered at the load_nextgen_gallery_modules action.
24
+ *
25
+ * If this action is triggered, assume NextGen Gallery is used.
26
+ *
27
+ * @since 1.0.5
28
+ * @access public
29
+ */
30
+ public static function detect()
31
+ {
32
+ add_action('ngg_added_new_image', 'LiteSpeed_Cache_ThirdParty_NextGenGallery::add_image') ;
33
+ add_action('ngg_ajax_image_save', 'LiteSpeed_Cache_ThirdParty_NextGenGallery::update_image') ;
34
+ add_action('ngg_delete_picture', 'LiteSpeed_Cache_ThirdParty_NextGenGallery::delete_image') ;
35
+ add_action('ngg_moved_images', 'LiteSpeed_Cache_ThirdParty_NextGenGallery::move_image', 10, 3) ;
36
+ add_action('ngg_copied_images', 'LiteSpeed_Cache_ThirdParty_NextGenGallery::copy_image', 10, 3) ;
37
+ add_action('ngg_generated_image', 'LiteSpeed_Cache_ThirdParty_NextGenGallery::gen_image') ;
38
+ add_action('ngg_recovered_image', 'LiteSpeed_Cache_ThirdParty_NextGenGallery::gen_image') ;
39
+
40
+ add_action('ngg_gallery_sort', 'LiteSpeed_Cache_ThirdParty_NextGenGallery::update_gallery') ;
41
+ add_action('ngg_delete_gallery', 'LiteSpeed_Cache_ThirdParty_NextGenGallery::update_gallery') ;
42
+
43
+ add_action('ngg_update_album', 'LiteSpeed_Cache_ThirdParty_NextGenGallery::update_album') ;
44
+ add_action('ngg_delete_album', 'LiteSpeed_Cache_ThirdParty_NextGenGallery::update_album') ;
45
+
46
+ add_filter('ngg_displayed_gallery_cache_params', 'LiteSpeed_Cache_ThirdParty_NextGenGallery::add_container') ;
47
+ }
48
+
49
+ /**
50
+ * When an image is added, need to purge all pages that displays its gallery.
51
+ *
52
+ * @since 1.0.5
53
+ * @access public
54
+ * @param string $image The image object added.
55
+ */
56
+ public static function add_image($image)
57
+ {
58
+ if ( ! $image ) {
59
+ return ;
60
+ }
61
+ $gallery = $image->get_gallery() ;
62
+ if ( $gallery && $gallery->pageid ) {
63
+ LiteSpeed_Cache_API::purge(self::CACHETAG_GALLERIES . $gallery->pageid) ;
64
+ }
65
+ }
66
+
67
+ /**
68
+ * When an image is updated, need to purge all pages that displays its gallery.
69
+ *
70
+ * @since 1.0.5
71
+ * @access public
72
+ */
73
+ public static function update_image()
74
+ {
75
+ if ( isset( $_GET['gallery_id'] ) ) {
76
+ LiteSpeed_Cache_API::purge( self::CACHETAG_GALLERIES . $_GET['gallery_id'] ) ;
77
+ return ;
78
+ }
79
+
80
+ if ( isset($_POST['id']) ) {
81
+ $id = $_POST['id'] ;
82
+ }
83
+ elseif ( isset($_POST['image']) ) {
84
+ $id = $_POST['image'] ;
85
+ }
86
+ elseif ( isset($_GET['pid']) ) {
87
+ $id = $_GET['pid'] ;
88
+ }
89
+ else {
90
+ error_log('LiteSpeed_Cache hit ngg_ajax_image_save with no post image id.') ;
91
+ return ;
92
+ }
93
+ $image = C_Image_Mapper::get_instance()->find($id) ;
94
+ if ( $image ) {
95
+ LiteSpeed_Cache_API::purge(self::CACHETAG_GALLERIES . $image->galleryid) ;
96
+ }
97
+ }
98
+
99
+ /**
100
+ * When an image is deleted, need to purge all pages that displays its gallery.
101
+ *
102
+ * @since 1.0.5
103
+ * @access public
104
+ */
105
+ public static function delete_image()
106
+ {
107
+ if ( isset($_GET['gid']) ) {
108
+ LiteSpeed_Cache_API::purge(self::CACHETAG_GALLERIES . $_GET['gid']) ;
109
+ }
110
+ }
111
+
112
+ /**
113
+ * When an image is moved, need to purge all old galleries and the new gallery.
114
+ *
115
+ * @since 1.0.8
116
+ * @access public
117
+ * @param array $images unused
118
+ * @param array $old_gallery_ids Source gallery ids for the images.
119
+ * @param integer $new_gallery_id Destination gallery id.
120
+ */
121
+ public static function move_image($images, $old_gallery_ids, $new_gallery_id)
122
+ {
123
+ foreach ($old_gallery_ids as $gid) {
124
+ LiteSpeed_Cache_API::purge(self::CACHETAG_GALLERIES . $gid) ;
125
+ }
126
+ LiteSpeed_Cache_API::purge(self::CACHETAG_GALLERIES . $new_gallery_id) ;
127
+ }
128
+
129
+ /**
130
+ * When an image is copied, need to purge the destination gallery.
131
+ *
132
+ * @param array $image_pid_map unused
133
+ * @param array $old_gallery_ids unused
134
+ * @param integer $new_gallery_id Destination gallery id.
135
+ */
136
+ public static function copy_image($image_pid_map, $old_gallery_ids, $new_gallery_id)
137
+ {
138
+ LiteSpeed_Cache_API::purge(self::CACHETAG_GALLERIES . $new_gallery_id) ;
139
+ }
140
+
141
+ /**
142
+ * When an image is re-generated, need to purge the gallery it belongs to.
143
+ * Also applies to recovered images.
144
+ *
145
+ * @param Image $image The re-generated image.
146
+ */
147
+ public static function gen_image($image)
148
+ {
149
+ LiteSpeed_Cache_API::purge(self::CACHETAG_GALLERIES . $image->galleryid) ;
150
+ }
151
+
152
+ /**
153
+ * When a gallery is updated, need to purge all pages that display the gallery.
154
+ *
155
+ * @since 1.0.5
156
+ * @access public
157
+ * @param integer $gid The gallery id of the gallery updated.
158
+ */
159
+ public static function update_gallery($gid)
160
+ {
161
+ LiteSpeed_Cache_API::purge(self::CACHETAG_GALLERIES . $gid) ;
162
+ }
163
+
164
+ /**
165
+ * When an album is updated, need to purge all pages that display the album.
166
+ *
167
+ * @since 1.0.5
168
+ * @access public
169
+ * @param integer $aid The album id of the album updated.
170
+ */
171
+ public static function update_album($aid)
172
+ {
173
+ LiteSpeed_Cache_API::purge(self::CACHETAG_ALBUMS . $aid) ;
174
+ }
175
+
176
+ /**
177
+ * When rendering a page, if the page has a gallery, album or tag cloud,
178
+ * it needs to be tagged appropriately.
179
+ *
180
+ * @since 1.0.5
181
+ * @access public
182
+ * @param object $render_parms Parameters used to render the associated part of the page.
183
+ * @return mixed Null if passed in null, $render_parms otherwise.
184
+ */
185
+ public static function add_container($render_parms)
186
+ {
187
+ // Check if null. If it is null, can't continue.
188
+ if ( is_null($render_parms) ) {
189
+ return null ;
190
+ }
191
+ $src = $render_parms[0]->source ;
192
+ $container_ids = $render_parms[0]->container_ids ;
193
+ // Can switch on first char if we end up with more sources.
194
+ switch ($src) {
195
+ case 'albums':
196
+ $tag = self::CACHETAG_ALBUMS ;
197
+ break ;
198
+ case 'galleries':
199
+ $tag = self::CACHETAG_GALLERIES ;
200
+ break ;
201
+ case 'tags':
202
+ $tag = self::CACHETAG_TAGS ;
203
+ break ;
204
+ default:
205
+ return $render_parms ;
206
+ }
207
+
208
+ foreach ($container_ids as $id) {
209
+ LiteSpeed_Cache_API::tag_add($tag . $id) ;
210
+ }
211
+
212
+ return $render_parms ;
213
+ }
214
+ }
215
+
thirdparty/lscwp-3rd-theme-my-login.cls.php ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The Third Party integration with the Theme My Login plugin.
4
+ *
5
+ * @since 1.0.15
6
+ * @package LiteSpeed_Cache
7
+ * @subpackage LiteSpeed_Cache/thirdparty
8
+ * @author LiteSpeed Technologies <info@litespeedtech.com>
9
+ */
10
+ if ( ! defined('ABSPATH') ) {
11
+ die() ;
12
+ }
13
+ LiteSpeed_Cache_API::register('LiteSpeed_Cache_ThirdParty_Theme_My_Login') ;
14
+
15
+ class LiteSpeed_Cache_ThirdParty_Theme_My_Login
16
+ {
17
+ /**
18
+ * Detects if Better Theme My Login is active.
19
+ *
20
+ * @since 1.0.15
21
+ * @access public
22
+ *
23
+ */
24
+ public static function detect()
25
+ {
26
+ if ( defined('THEME_MY_LOGIN_PATH') ) {
27
+ LiteSpeed_Cache_API::hook_control('LiteSpeed_Cache_ThirdParty_Theme_My_Login::set_control') ;
28
+ }
29
+ }
30
+
31
+ /**
32
+ * This filter is used to let the cache know if a page is cacheable.
33
+ *
34
+ * @access public
35
+ * @since 1.0.15
36
+ */
37
+ public static function set_control()
38
+ {
39
+ if ( LiteSpeed_Cache_API::not_cacheable() ) {
40
+ return ;
41
+ }
42
+
43
+ // check if this page is TML page or not
44
+ if ( class_exists('Theme_My_Login') && Theme_My_Login::is_tml_page() ) {
45
+ LiteSpeed_Cache_API::set_nocache() ;
46
+ }
47
+ }
48
+
49
+ }
50
+
thirdparty/lscwp-3rd-woocommerce.cls.php ADDED
@@ -0,0 +1,725 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The Third Party integration with the WooCommerce plugin.
4
+ *
5
+ * @since 1.0.5
6
+ * @package LiteSpeed_Cache
7
+ * @subpackage LiteSpeed_Cache/thirdparty
8
+ * @author LiteSpeed Technologies <info@litespeedtech.com>
9
+ */
10
+ if ( ! defined('ABSPATH') ) {
11
+ die() ;
12
+ }
13
+ LiteSpeed_Cache_API::register('LiteSpeed_Cache_ThirdParty_WooCommerce') ;
14
+
15
+ class LiteSpeed_Cache_ThirdParty_WooCommerce
16
+ {
17
+ const CACHETAG_SHOP = 'WC_S' ;
18
+ const CACHETAG_TERM = 'WC_T.' ;
19
+ const OPTION_UPDATE_INTERVAL = 'wc_update_interval' ;
20
+ const OPTION_SHOP_FRONT_TTL = 'wc_shop_use_front_ttl' ;
21
+ const OPT_PQS_CS = 0 ; // flush product on quantity + stock change, categories on stock change
22
+ const OPT_PS_CS = 1 ; // flush product and categories on stock change
23
+ const OPT_PS_CN = 2 ; // flush product on stock change, categories no flush
24
+ const OPT_PQS_CQS = 3 ; // flush product and categories on quantity + stock change
25
+
26
+ const ESI_PARAM_ARGS = 'wc_args' ;
27
+ const ESI_PARAM_POSTID = 'wc_post_id' ;
28
+ const ESI_PARAM_NAME = 'wc_name' ;
29
+ const ESI_PARAM_PATH = 'wc_path' ;
30
+ const ESI_PARAM_LOCATED = 'wc_located' ;
31
+
32
+ /**
33
+ * Detects if WooCommerce is installed.
34
+ *
35
+ * @since 1.0.5
36
+ * @access public
37
+ */
38
+ public static function detect()
39
+ {
40
+ if ( ! defined('WOOCOMMERCE_VERSION') ) {
41
+ return ;
42
+ }
43
+ LiteSpeed_Cache_API::hook_control('LiteSpeed_Cache_ThirdParty_WooCommerce::set_control') ;
44
+ LiteSpeed_Cache_API::hook_tag('LiteSpeed_Cache_ThirdParty_WooCommerce::set_tag') ;
45
+
46
+ // Purging a product on stock change should only occur during product purchase. This function will add the purging callback when an order is complete.
47
+ add_action('woocommerce_product_set_stock', 'LiteSpeed_Cache_ThirdParty_WooCommerce::purge_product') ;
48
+
49
+ LiteSpeed_Cache_API::hook_get_options('LiteSpeed_Cache_ThirdParty_WooCommerce::get_config') ;
50
+ add_action('comment_post', 'LiteSpeed_Cache_ThirdParty_WooCommerce::add_review', 10, 3) ;
51
+
52
+ if ( LSWCP_ESI_SUPPORT && LiteSpeed_Cache::config(LiteSpeed_Cache_Config::OPID_ESI_ENABLE) ) {
53
+ if ( !is_shop() ) {
54
+ LiteSpeed_Cache_API::hook_tpl_not_esi('LiteSpeed_Cache_ThirdParty_WooCommerce::set_block_template') ;
55
+ LiteSpeed_Cache_API::hook_tpl_esi('wc-add-to-cart-form', 'LiteSpeed_Cache_ThirdParty_WooCommerce::load_add_to_cart_form_block') ;
56
+ LiteSpeed_Cache_API::hook_tpl_esi('storefront-cart-header', 'LiteSpeed_Cache_ThirdParty_WooCommerce::load_cart_header') ;
57
+ LiteSpeed_Cache_API::hook_tpl_esi('widget', 'LiteSpeed_Cache_ThirdParty_WooCommerce::register_post_view') ;
58
+ }
59
+
60
+ if ( is_product() ) {
61
+ LiteSpeed_Cache_API::hook_esi_param('widget', 'LiteSpeed_Cache_ThirdParty_WooCommerce::add_post_id') ;
62
+ }
63
+
64
+ LiteSpeed_Cache_API::hook_tpl_not_esi('LiteSpeed_Cache_ThirdParty_WooCommerce::set_swap_header_cart') ;
65
+ }
66
+
67
+ if ( is_admin() ) {
68
+ LiteSpeed_Cache_API::hook_purge_post('LiteSpeed_Cache_ThirdParty_WooCommerce::backend_purge') ;
69
+ add_action('delete_term_relationships', 'LiteSpeed_Cache_ThirdParty_WooCommerce::delete_rel', 10, 2) ;
70
+ LiteSpeed_Cache_API::hook_setting_tab('LiteSpeed_Cache_ThirdParty_WooCommerce::add_config', 10, 3) ;
71
+ LiteSpeed_Cache_API::hook_setting_save('LiteSpeed_Cache_ThirdParty_WooCommerce::save_config', 10, 2) ;
72
+ LiteSpeed_Cache_API::hook_widget_default_options('LiteSpeed_Cache_ThirdParty_WooCommerce::wc_widget_default', 10, 2) ;
73
+ }
74
+ }
75
+
76
+ /**
77
+ * Hooked to the litespeed_cache_is_not_esi_template action.
78
+ * If the request is not an esi request, I want to set my own hook
79
+ * in woocommerce_before_template_part to see if it's something I can ESI.
80
+ *
81
+ * @since 1.1.0
82
+ * @access public
83
+ */
84
+ public static function set_block_template()
85
+ {
86
+ add_action('woocommerce_before_template_part', 'LiteSpeed_Cache_ThirdParty_WooCommerce::block_template', 999, 4) ;
87
+ }
88
+
89
+ /**
90
+ * Hooked to the litespeed_cache_is_not_esi_template action.
91
+ * If the request is not an esi request, I want to set my own hook
92
+ * in storefront_header to see if it's something I can ESI.
93
+ *
94
+ * Will remove storefront_header_cart in storefront_header.
95
+ *
96
+ * @since 1.1.0
97
+ * @access public
98
+ */
99
+ public static function set_swap_header_cart()
100
+ {
101
+ $priority = has_action('storefront_header', 'storefront_header_cart') ;
102
+ if ( $priority !== false ) {
103
+ remove_action('storefront_header', 'storefront_header_cart', $priority) ;
104
+ add_action('storefront_header', 'LiteSpeed_Cache_ThirdParty_WooCommerce::esi_cart_header', $priority) ;
105
+ }
106
+ }
107
+
108
+ /**
109
+ * Hooked to the woocommerce_before_template_part action.
110
+ * Checks if the template contains 'add-to-cart'. If so, and if I
111
+ * want to ESI the request, block it and build my esi code block.
112
+ *
113
+ * The function parameters will be passed to the esi request.
114
+ *
115
+ * @since 1.1.0
116
+ * @access public
117
+ * @global type $post Needed for post id
118
+ * @param type $template_name
119
+ * @param type $template_path
120
+ * @param type $located
121
+ * @param type $args
122
+ */
123
+ public static function block_template($template_name, $template_path, $located, $args)
124
+ {
125
+ if ( strpos($template_name, 'add-to-cart') === false ) {
126
+ if ( strpos($template_name, 'related.php') !== false ) {
127
+ remove_action('woocommerce_before_template_part', 'LiteSpeed_Cache_ThirdParty_WooCommerce::block_template', 999) ;
128
+ add_filter('woocommerce_related_products_args', 'LiteSpeed_Cache_ThirdParty_WooCommerce::add_related_tags') ;
129
+ add_action('woocommerce_after_template_part', 'LiteSpeed_Cache_ThirdParty_WooCommerce::end_template', 999) ;
130
+ }
131
+ return ;
132
+ }
133
+ global $post ;
134
+ $params = array(
135
+ self::ESI_PARAM_ARGS => $args,
136
+ self::ESI_PARAM_NAME => $template_name,
137
+ self::ESI_PARAM_POSTID => $post->ID,
138
+ self::ESI_PARAM_PATH => $template_path,
139
+ self::ESI_PARAM_LOCATED => $located
140
+ ) ;
141
+ add_action('woocommerce_after_add_to_cart_form', 'LiteSpeed_Cache_ThirdParty_WooCommerce::end_form') ;
142
+ add_action('woocommerce_after_template_part', 'LiteSpeed_Cache_ThirdParty_WooCommerce::end_form', 999) ;
143
+ LiteSpeed_Cache_API::esi_url('wc-add-to-cart-form', 'WC_CART_FORM', $params) ;
144
+ ob_start() ;
145
+ }
146
+
147
+ /**
148
+ * Hooked to the woocommerce_after_add_to_cart_form action.
149
+ * If this is hit first, clean the buffer and remove this function and
150
+ * end_template.
151
+ *
152
+ * @since 1.1.0
153
+ * @access public
154
+ */
155
+ public static function end_form($template_name = '')
156
+ {
157
+ if ( ! empty($template_name) && strpos($template_name, 'add-to-cart') === false ) {
158
+ return ;
159
+ }
160
+ ob_clean() ;
161
+ remove_action('woocommerce_after_add_to_cart_form', 'LiteSpeed_Cache_ThirdParty_WooCommerce::end_form') ;
162
+ remove_action('woocommerce_after_template_part', 'LiteSpeed_Cache_ThirdParty_WooCommerce::end_form', 999) ;
163
+ }
164
+
165
+ /**
166
+ * If related products are loaded, need to add the extra product ids.
167
+ *
168
+ * The page will be purged if any of the products are changed.
169
+ *
170
+ * @since 1.1.0
171
+ * @access public
172
+ * @param array $args The arguments used to build the related products section.
173
+ * @return array The unchanged arguments.
174
+ */
175
+ public static function add_related_tags($args)
176
+ {
177
+ if ( empty($args) || ! isset($args['post__in']) ) {
178
+ return $args ;
179
+ }
180
+ $related_posts = $args['post__in'] ;
181
+ foreach ( $related_posts as $related ) {
182
+ LiteSpeed_Cache_API::tag_add(LiteSpeed_Cache_API::TYPE_POST . $related) ;
183
+ }
184
+ return $args ;
185
+ }
186
+
187
+ /**
188
+ * Hooked to the woocommerce_after_template_part action.
189
+ * If the template contains 'add-to-cart', clean the buffer.
190
+ *
191
+ * @since 1.1.0
192
+ * @access public
193
+ * @param type $template_name
194
+ */
195
+ public static function end_template($template_name)
196
+ {
197
+ if ( strpos($template_name, 'related.php') !== false ) {
198
+ remove_action('woocommerce_after_template_part', 'LiteSpeed_Cache_ThirdParty_WooCommerce::end_template', 999) ;
199
+ self::set_block_template() ;
200
+ }
201
+ }
202
+
203
+ /**
204
+ * Hooked to the storefront_header header.
205
+ * If I want to ESI the request, block it and build my esi code block.
206
+ *
207
+ * @since 1.1.0
208
+ * @access public
209
+ */
210
+ public static function esi_cart_header()
211
+ {
212
+ LiteSpeed_Cache_API::esi_url('storefront-cart-header', 'STOREFRONT_CART_HEADER') ;
213
+ }
214
+
215
+ /**
216
+ * Hooked to the litespeed_cache_load_esi_block-storefront-cart-header action.
217
+ * Generates the cart header for esi display.
218
+ *
219
+ * @since 1.1.0
220
+ * @access public
221
+ */
222
+ public static function load_cart_header()
223
+ {
224
+ storefront_header_cart() ;
225
+ }
226
+
227
+ /**
228
+ * Hooked to the litespeed_cache_load_esi_block-wc-add-to-cart-form action.
229
+ * Parses the esi input parameters and generates the add to cart form
230
+ * for esi display.
231
+ *
232
+ * @since 1.1.0
233
+ * @access public
234
+ * @global type $post
235
+ * @global type $wp_query
236
+ * @param type $params
237
+ */
238
+ public static function load_add_to_cart_form_block($params)
239
+ {
240
+ global $post, $wp_query ;
241
+ $post = get_post($params[self::ESI_PARAM_POSTID]) ;
242
+ $wp_query->setup_postdata($post) ;
243
+ wc_get_template($params[self::ESI_PARAM_NAME], $params[self::ESI_PARAM_ARGS], $params[self::ESI_PARAM_PATH]) ;
244
+ }
245
+
246
+ /**
247
+ * Update woocommerce when someone visits a product and has the
248
+ * recently viewed products widget.
249
+ *
250
+ * Currently, this widget should not be cached.
251
+ *
252
+ * @since 1.1.0
253
+ * @access public
254
+ * @param array $params Widget parameter array
255
+ */
256
+ public static function register_post_view($params)
257
+ {
258
+ if ( $params[LiteSpeed_Cache_API::PARAM_NAME] !== 'WC_Widget_Recently_Viewed' ) {
259
+ return ;
260
+ }
261
+ if ( ! isset($params[self::ESI_PARAM_POSTID]) ) {
262
+ return ;
263
+ }
264
+ $id = $params[self::ESI_PARAM_POSTID] ;
265
+ $esi_post = get_post($id) ;
266
+ $product = wc_get_product($esi_post) ;
267
+
268
+ if ( empty($product) ) {
269
+ return ;
270
+ }
271
+
272
+ global $post ;
273
+ $post = $esi_post ;
274
+ wc_track_product_view() ;
275
+ }
276
+
277
+ /**
278
+ * Adds the post id to the widget ESI parameters for the Recently Viewed widget.
279
+ *
280
+ * This is needed in the esi request to update the cookie properly.
281
+ *
282
+ * @since 1.1.0
283
+ * @access public
284
+ * @param array $params The current ESI parameters.
285
+ * @return array The updated esi parameters.
286
+ */
287
+ public static function add_post_id($params)
288
+ {
289
+ if ( ! isset($params) || ! isset($params[LiteSpeed_Cache_API::PARAM_NAME]) || $params[LiteSpeed_Cache_API::PARAM_NAME] !== 'WC_Widget_Recently_Viewed' ) {
290
+ return $params ;
291
+ }
292
+ $params[self::ESI_PARAM_POSTID] = get_the_ID() ;
293
+ return $params ;
294
+ }
295
+
296
+ /**
297
+ * Hooked to the litespeed_cache_widget_default_options filter.
298
+ *
299
+ * The recently viewed widget must be esi to function properly.
300
+ * This function will set it to enable and no cache by default.
301
+ *
302
+ * @since 1.1.0
303
+ * @access public
304
+ * @param array $options The current default widget options.
305
+ * @param type $widget The current widget to configure.
306
+ * @return array The updated default widget options.
307
+ */
308
+ public static function wc_widget_default($options, $widget)
309
+ {
310
+ if ( ! is_array($options) ) {
311
+ return $options ;
312
+ }
313
+ $widget_name = get_class($widget) ;
314
+ if ( $widget_name === 'WC_Widget_Recently_Viewed' ) {
315
+ $options[LiteSpeed_Cache_API::WIDGET_OPID_ESIENABLE] = true ;
316
+ $options[LiteSpeed_Cache_API::WIDGET_OPID_TTL] = 0 ;
317
+ }
318
+ elseif ( $widget_name === 'WC_Widget_Recent_Reviews' ) {
319
+ $options[LiteSpeed_Cache_API::WIDGET_OPID_ESIENABLE] = true ;
320
+ $options[LiteSpeed_Cache_API::WIDGET_OPID_TTL] = 86400 ;
321
+ }
322
+ return $options ;
323
+ }
324
+
325
+ /**
326
+ * Check and set shop front page ttl
327
+ *
328
+ * @access private
329
+ * @since 1.1.3
330
+ */
331
+ private static function set_ttl()
332
+ {
333
+ if ( is_shop() ) {
334
+ if ( LiteSpeed_Cache_API::config( self::OPTION_SHOP_FRONT_TTL ) ) {
335
+ LiteSpeed_Cache_API::set_use_frontpage_ttl() ;
336
+ }
337
+ }
338
+ }
339
+
340
+ /**
341
+ * Set WooCommerce cache tags based on page type.
342
+ *
343
+ * @access public
344
+ * @since 1.0.9
345
+ */
346
+ public static function set_tag()
347
+ {
348
+ $id = get_the_ID() ;
349
+ if ( $id === false ) {
350
+ return ;
351
+ }
352
+
353
+ // Check if product has a cache ttl limit or not
354
+ $sale_from = get_post_meta( $id, '_sale_price_dates_from', true ) ;
355
+ $sale_to = get_post_meta( $id, '_sale_price_dates_to', true ) ;
356
+ $now = current_time( 'timestamp' ) ;
357
+ $ttl = false ;
358
+ if ( $sale_from && $now < $sale_from ) {
359
+ $ttl = $sale_from - $now ;
360
+ }
361
+ elseif ( $sale_to && $now < $sale_to ) {
362
+ $ttl = $sale_to - $now ;
363
+ }
364
+ if ( $ttl && $ttl < LiteSpeed_Cache_API::get_ttl() ) {
365
+ LiteSpeed_Cache_API::debug( "WooCommerce set scheduled TTL to $ttl" ) ;
366
+ LiteSpeed_Cache_API::set_ttl( $ttl ) ;
367
+ }
368
+
369
+ if ( is_shop() ) {
370
+ LiteSpeed_Cache_API::tag_add(self::CACHETAG_SHOP) ;
371
+ }
372
+ if ( ! is_product_taxonomy() ) {
373
+ return ;
374
+ }
375
+ if ( isset($GLOBALS['product_cat']) ) {
376
+ $term = get_term_by('slug', $GLOBALS['product_cat'], 'product_cat') ;
377
+ }
378
+ elseif ( isset($GLOBALS['product_tag']) ) {
379
+ $term = get_term_by('slug', $GLOBALS['product_tag'], 'product_tag') ;
380
+ }
381
+ else {
382
+ $term = false ;
383
+ }
384
+
385
+ if ( $term === false ) {
386
+ return ;
387
+ }
388
+ while ( isset($term) ) {
389
+ LiteSpeed_Cache_API::tag_add(self::CACHETAG_TERM . $term->term_id) ;
390
+ if ( $term->parent == 0 ) {
391
+ break ;
392
+ }
393
+ $term = get_term($term->parent) ;
394
+ }
395
+ }
396
+
397
+ /**
398
+ * Check if the page is cacheable according to WooCommerce.
399
+ *
400
+ * @since 1.0.5
401
+ * @access public
402
+ * @param string $esi_id The ESI block id if a request is an ESI request.
403
+ * @return boolean True if cacheable, false if not.
404
+ */
405
+ public static function set_control($esi_id)
406
+ {
407
+ if ( LiteSpeed_Cache_API::not_cacheable() ) {
408
+ return ;
409
+ }
410
+
411
+ $woocom = WC() ;
412
+ if ( ! isset($woocom) ) {
413
+ return ;
414
+ }
415
+ self::set_ttl() ;
416
+
417
+ // For later versions, DONOTCACHEPAGE should be set.
418
+ // No need to check uri/qs.
419
+ if ( version_compare($woocom->version, '1.4.2', '>=') ) {
420
+ if ( defined('DONOTCACHEPAGE') && DONOTCACHEPAGE ) {
421
+ LiteSpeed_Cache_API::debug('3rd party woocommerce not cache by constant') ;
422
+ LiteSpeed_Cache_API::set_nocache() ;
423
+ return ;
424
+ }
425
+ elseif ( version_compare($woocom->version, '2.1.0', '>=') ) {
426
+ $err = false ;
427
+ if ( is_null($woocom->cart) ) {
428
+ $err = 'null cart' ;
429
+ }
430
+ elseif ( $woocom->cart->get_cart_contents_count() !== 0 ) {//$esi_id === 'storefront-cart-header' &&
431
+ $err = 'cart is not empty' ;
432
+ }
433
+ elseif ( wc_notice_count() > 0 ) {
434
+ $err = 'has wc notice' ;
435
+ }
436
+
437
+ if ( $err ) {
438
+ LiteSpeed_Cache_API::debug('3rd party woocommerce not cache due to ' . $err) ;
439
+ LiteSpeed_Cache_API::set_nocache() ;
440
+ return ;
441
+ }
442
+ }
443
+ return ;
444
+ }
445
+
446
+ $uri = esc_url($_SERVER["REQUEST_URI"]) ;
447
+ $uri_len = strlen($uri) ;
448
+ if ( $uri_len < 5 ) {
449
+ return ;
450
+ }
451
+
452
+ if ( in_array($uri, array('cart/', 'checkout/', 'my-account/', 'addons/', 'logout/', 'lost-password/', 'product/')) ) {
453
+ LiteSpeed_Cache_API::set_nocache() ;
454
+ return ;
455
+ }
456
+
457
+ $qs = sanitize_text_field($_SERVER["QUERY_STRING"]) ;
458
+ $qs_len = strlen($qs) ;
459
+ if ( ! empty($qs) && $qs_len >= 12 && strncmp($qs, 'add-to-cart=', 12) == 0 ) {
460
+ LiteSpeed_Cache_API::set_nocache() ;
461
+ return ;
462
+ }
463
+ }
464
+
465
+ /**
466
+ * Purge a product page and related pages (based on settings) on checkout.
467
+ *
468
+ * @access public
469
+ * @since 1.0.9
470
+ * @param WC_Product $product
471
+ */
472
+ public static function purge_product($product)
473
+ {
474
+ $config = LiteSpeed_Cache_API::config(self::OPTION_UPDATE_INTERVAL) ;
475
+ if ( is_null($config) ) {
476
+ $config = self::OPT_PQS_CS ;
477
+ }
478
+
479
+ if ( $config === self::OPT_PQS_CQS ) {
480
+ self::backend_purge($product->get_id()) ;
481
+ }
482
+ elseif ( $config !== self::OPT_PQS_CS && $product->is_in_stock() ) {
483
+ return ;
484
+ }
485
+ elseif ( $config !== self::OPT_PS_CN && ! $product->is_in_stock() ) {
486
+ self::backend_purge($product->get_id()) ;
487
+ }
488
+
489
+ LiteSpeed_Cache_API::purge(LiteSpeed_Cache_API::TYPE_POST . $product->get_id()) ;
490
+ }
491
+
492
+ /**
493
+ * Delete object-term relationship. If the post is a product and
494
+ * the term ids array is not empty, will add purge tags to the deleted
495
+ * terms.
496
+ *
497
+ * @access public
498
+ * @since 1.0.9
499
+ * @param int $post_id Object ID.
500
+ * @param array $term_ids An array of term taxonomy IDs.
501
+ */
502
+ public static function delete_rel($post_id, $term_ids)
503
+ {
504
+ if ( empty($term_ids) || wc_get_product($post_id) === false ) {
505
+ return ;
506
+ }
507
+ foreach ( $term_ids as $term_id ) {
508
+ LiteSpeed_Cache_API::purge(self::CACHETAG_TERM . $term_id) ;
509
+ }
510
+ }
511
+
512
+ /**
513
+ * Purge a product's categories and tags pages in case they are affected.
514
+ *
515
+ * @access public
516
+ * @since 1.0.9
517
+ * @param int $post_id Post id that is about to be purged
518
+ */
519
+ public static function backend_purge($post_id)
520
+ {
521
+ if ( ! isset($post_id) || wc_get_product($post_id) === false ) {
522
+ return ;
523
+ }
524
+
525
+ $cats = self::get_cats($post_id) ;
526
+ if ( ! empty($cats) ) {
527
+ foreach ( $cats as $cat ) {
528
+ LiteSpeed_Cache_API::purge(self::CACHETAG_TERM . $cat) ;
529
+ }
530
+ }
531
+
532
+ $tags = wc_get_product_terms($post_id, 'product_tag', array('fields' => 'ids')) ;
533
+ if ( ! empty($tags) ) {
534
+ foreach ( $tags as $tag ) {
535
+ LiteSpeed_Cache_API::purge(self::CACHETAG_TERM . $tag) ;
536
+ }
537
+ }
538
+ }
539
+
540
+ /**
541
+ * When a product has a new review added, purge the recent reviews widget.
542
+ *
543
+ * @since 1.1.0
544
+ * @access public
545
+ * @param $unused
546
+ * @param integer $comment_approved Whether the comment is approved or not.
547
+ * @param array $commentdata Information about the comment.
548
+ */
549
+ public static function add_review($unused, $comment_approved, $commentdata)
550
+ {
551
+ $post_id = $commentdata['comment_post_ID'] ;
552
+ if ( $comment_approved !== 1 || ! isset($post_id) || wc_get_product($post_id) === false ) {
553
+ return ;
554
+ }
555
+ global $wp_widget_factory ;
556
+ $recent_reviews = $wp_widget_factory->widgets['WC_Widget_Recent_Reviews'] ;
557
+ if ( ! is_null($recent_reviews) ) {
558
+ LiteSpeed_Cache_API::tag_add(LiteSpeed_Cache_API::TYPE_WIDGET . $recent_reviews->id) ;
559
+ }
560
+ }
561
+
562
+ /**
563
+ * Hooked to the litespeed_cache_get_options filter.
564
+ * This will return the option names needed as well as the default options.
565
+ *
566
+ * @param array $configs
567
+ * @return array
568
+ */
569
+ public static function get_config($configs)
570
+ {
571
+ if ( ! is_array($configs) ) {
572
+ return $configs ;
573
+ }
574
+ $configs[self::OPTION_UPDATE_INTERVAL] = self::OPT_PQS_CS ;
575
+ $configs[self::OPTION_SHOP_FRONT_TTL] = true ;
576
+
577
+ return $configs ;
578
+ }
579
+
580
+ /**
581
+ * Hooked to the litespeed_cache_add_config_tab filter.
582
+ * Adds the integration configuration options (currently, to determine
583
+ * purge rules)
584
+ *
585
+ * @param array $tabs Third party tabs added.
586
+ * @param array $options Current options used.
587
+ * @param string $option_group The option group to surround the option id.
588
+ * @return mixed False on failure, updated tabs otherwise.
589
+ */
590
+ public static function add_config($tabs, $options, $option_group)
591
+ {
592
+ $_title = __('WooCommerce', 'litespeed-cache') ;
593
+ $_slug = 'woocom' ;
594
+ $seloptions = array(
595
+ __('Purge product on changes to the quantity or stock status.', 'litespeed-cache')
596
+ . ' ' . __('Purge categories only when stock status changes.', 'litespeed-cache'),
597
+ __('Purge product and categories only when the stock status changes.', 'litespeed-cache'),
598
+ __('Purge product only when the stock status changes.', 'litespeed-cache')
599
+ . ' ' . __('Do not purge categories on changes to the quantity or stock status.', 'litespeed-cache'),
600
+ __('Always purge both product and categories on changes to the quantity or stock status.', 'litespeed-cache'),
601
+ ) ;
602
+ $update_desc =
603
+ __('Determines how changes in product quantity and product stock status affect product pages and their associated category pages.', 'litespeed-cache') ;
604
+ $ttl_desc = __('Checking this option will force the shop page to use the front page TTL setting.', 'litespeed-cache')
605
+ . ' ' . sprintf(__('For example, if the homepage for the site is located at %1$s, the shop page may be located at %2$s.', 'litespeed-cache'),
606
+ 'https://www.example.com', 'https://www.example.com/shop') ;
607
+
608
+ if ($tabs === false) {
609
+ return false ;
610
+ }
611
+
612
+ $selected_value = self::OPT_PQS_CS ;
613
+ if (isset($options)) {
614
+ if (isset($options[self::OPTION_UPDATE_INTERVAL])) {
615
+ $selected_value = $options[self::OPTION_UPDATE_INTERVAL] ;
616
+ }
617
+ }
618
+
619
+ $update_intval_html = '' ;
620
+ $id = self::OPTION_UPDATE_INTERVAL ;
621
+ foreach ($seloptions as $val => $title) {
622
+ $checked = $selected_value == $val ? ' checked="checked" ' : '';
623
+ $update_intval_html .= "<div class='litespeed-radio cross litespeed-top10'>
624
+ <input type='radio' name='{$option_group}[$id]' id='conf_{$id}_$val' value='$val' $checked />
625
+ <label for='conf_{$id}_$val'>$title</label>
626
+ </div>" ;
627
+ }
628
+
629
+ $content = "<h3 class='litespeed-title'>{$_title}</h3>
630
+ <table class='form-table'><tbody>
631
+ <tr>
632
+ <th>" . __('Product Update Interval', 'litespeed-cache') . "</th>
633
+ <td>
634
+ $update_intval_html
635
+ <div class='litespeed-desc'>$update_desc</div>
636
+ </td>
637
+ </tr>
638
+ <tr>
639
+ <th>" . __('Use Front Page TTL for the Shop Page', 'litespeed-cache') . "</th>
640
+ <td>
641
+ " . LiteSpeed_Cache_API::build_switch(self::OPTION_SHOP_FRONT_TTL, false, true) . "
642
+ <div class='litespeed-desc'>$ttl_desc</div>
643
+ </td>
644
+ </tr>
645
+ </tbody></table>
646
+ <div class='litespeed-callout litespeed-callout-warning'>
647
+ <h4>" . __('Note:', 'litespeed-cache') . "</h4>
648
+ <i>
649
+ " . __('After verifying that the cache works in general, please test the cart.', 'litespeed-cache') . "
650
+ " . sprintf(__('To test the cart, visit the %s.', 'litespeed-cache'), '<a href=' . get_admin_url() . 'admin.php?page=lscache-info>FAQ</a>') . "
651
+ </i>
652
+ </div>
653
+
654
+ " ;
655
+
656
+ $tab = array(
657
+ 'title' => $_title,
658
+ 'slug' => $_slug,
659
+ 'content' => $content,
660
+ ) ;
661
+
662
+ $tabs[] = $tab ;
663
+
664
+ return $tabs ;
665
+ }
666
+
667
+ /**
668
+ * Hooked to the litespeed_cache_save_options filter.
669
+ * Parses the input for this integration's options and updates
670
+ * the options array accordingly.
671
+ *
672
+ * @param array $options The saved options array.
673
+ * @param array $input The input options array.
674
+ * @return mixed false on failure, updated $options otherwise.
675
+ */
676
+ public static function save_config($options, $input)
677
+ {
678
+ if ( ! isset($options) ) {
679
+ return $options ;
680
+ }
681
+ if ( isset($input[self::OPTION_UPDATE_INTERVAL]) ) {
682
+ $update_val_in = $input[self::OPTION_UPDATE_INTERVAL] ;
683
+ switch ($update_val_in) {
684
+ case self::OPT_PQS_CS:
685
+ case self::OPT_PS_CS:
686
+ case self::OPT_PS_CN:
687
+ case self::OPT_PQS_CQS:
688
+ $options[self::OPTION_UPDATE_INTERVAL] = intval($update_val_in) ;
689
+ break ;
690
+ default:
691
+ // add error message?
692
+ break ;
693
+ }
694
+ }
695
+
696
+ $options[ self::OPTION_SHOP_FRONT_TTL ] = LiteSpeed_Cache_API::parse_onoff( $input, self::OPTION_SHOP_FRONT_TTL ) ;
697
+
698
+ return $options ;
699
+ }
700
+
701
+ /**
702
+ * Helper function to select the function(s) to use to get the product
703
+ * category ids.
704
+ *
705
+ * @since 1.0.10
706
+ * @access private
707
+ * @param int $product_id The product id
708
+ * @return array An array of category ids.
709
+ */
710
+ private static function get_cats($product_id)
711
+ {
712
+ $woocom = WC() ;
713
+ if ( isset($woocom) && version_compare($woocom->version, '2.5.0', '>=') ) {
714
+ return wc_get_product_cat_ids($product_id) ;
715
+ }
716
+ $product_cats = wp_get_post_terms($product_id, 'product_cat', array("fields" => "ids")) ;
717
+ foreach ( $product_cats as $product_cat ) {
718
+ $product_cats = array_merge($product_cats, get_ancestors($product_cat, 'product_cat')) ;
719
+ }
720
+
721
+ return $product_cats ;
722
+ }
723
+
724
+ }
725
+
thirdparty/lscwp-3rd-wp-polls.cls.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * The Third Party integration with the WP-Polls plugin.
5
+ *
6
+ * @since 1.0.7
7
+ * @package LiteSpeed_Cache
8
+ * @subpackage LiteSpeed_Cache/thirdparty
9
+ * @author LiteSpeed Technologies <info@litespeedtech.com>
10
+ */
11
+ if ( ! defined('ABSPATH') ) {
12
+ die() ;
13
+ }
14
+ add_filter('wp_polls_display_pollvote', 'LiteSpeed_Cache_ThirdParty_Wp_Polls::set_control') ;
15
+ add_filter('wp_polls_display_pollresult', 'LiteSpeed_Cache_ThirdParty_Wp_Polls::set_control') ;
16
+
17
+ class LiteSpeed_Cache_ThirdParty_Wp_Polls
18
+ {
19
+ public static function set_control()
20
+ {
21
+ LiteSpeed_Cache_API::set_nocache() ;
22
+ }
23
+ }
24
+
thirdparty/lscwp-3rd-wp-postratings.cls.php ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * The Third Party integration with the WP-PostRatings plugin.
5
+ *
6
+ * @since 1.1.1
7
+ * @package LiteSpeed_Cache
8
+ * @subpackage LiteSpeed_Cache/thirdparty
9
+ * @author LiteSpeed Technologies <info@litespeedtech.com>
10
+ */
11
+ if ( ! defined('ABSPATH') ) {
12
+ die() ;
13
+ }
14
+ LiteSpeed_Cache_API::register('LiteSpeed_Cache_ThirdParty_WP_PostRatings') ;
15
+
16
+ class LiteSpeed_Cache_ThirdParty_WP_PostRatings
17
+ {
18
+
19
+ /**
20
+ * Detects if plugin is installed.
21
+ *
22
+ * @since 1.1.1
23
+ * @access public
24
+ */
25
+ public static function detect()
26
+ {
27
+ if ( defined('WP_POSTRATINGS_VERSION') ) {
28
+ add_action('rate_post', 'LiteSpeed_Cache_ThirdParty_WP_PostRatings::flush', 10, 3) ;
29
+ }
30
+ }
31
+
32
+ /**
33
+ * Purges the cache
34
+ *
35
+ * @since 1.1.1
36
+ * @access public
37
+ */
38
+ public static function flush($uid, $post_id, $post_ratings_score)
39
+ {
40
+ LiteSpeed_Cache_API::purge(LiteSpeed_Cache_API::TYPE_POST . $post_id) ;
41
+ }
42
+
43
+ }
thirdparty/lscwp-3rd-wpforo.cls.php ADDED
@@ -0,0 +1,157 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * The Third Party integration with the wpForo plugin.
5
+ *
6
+ * @since 1.0.15
7
+ * @package LiteSpeed_Cache
8
+ * @subpackage LiteSpeed_Cache/thirdparty
9
+ * @author LiteSpeed Technologies <info@litespeedtech.com>
10
+ */
11
+ if ( ! defined('ABSPATH') ) {
12
+ die() ;
13
+ }
14
+
15
+ LiteSpeed_Cache_API::register('LiteSpeed_Cache_ThirdParty_WpForo') ;
16
+ if ( defined('WPFORO_VERSION') ) {
17
+ add_action('wpforo_actions', 'LiteSpeed_Cache_ThirdParty_WpForo::purge_tag') ;
18
+ }
19
+
20
+ class LiteSpeed_Cache_ThirdParty_WpForo
21
+ {
22
+ const CACHETAG_COMMON = 'WF' ;
23
+ const CACHETAG_FRONTPAGE = 'WF_F' ;
24
+ const CACHETAG_FORUM = 'WF_F.' ;
25
+ const CACHETAG_TOPIC = 'WF_T.' ;
26
+
27
+ /**
28
+ * Detects if wpForo is installed.
29
+ *
30
+ * @since 1.0.15
31
+ * @access public
32
+ */
33
+ public static function detect()
34
+ {
35
+ if ( defined('WPFORO_VERSION') ) {
36
+ LiteSpeed_Cache_API::hook_tag('LiteSpeed_Cache_ThirdParty_WpForo::cache_tags') ;
37
+ }
38
+ }
39
+
40
+ /**
41
+ * Purge tags based on hooks
42
+ */
43
+ public static function purge_tag()
44
+ {
45
+ if( ! empty($_POST) ) {
46
+ add_action('wpforo_after_add_topic', 'LiteSpeed_Cache_ThirdParty_WpForo::purge_tag_topic_add') ;
47
+ add_action('wpforo_start_edit_topic', 'LiteSpeed_Cache_ThirdParty_WpForo::purge_tag_topic_update') ;
48
+ add_action('wpforo_after_delete_topic', 'LiteSpeed_Cache_ThirdParty_WpForo::purge_tag_topic_update') ;
49
+
50
+ add_action('wpforo_after_add_post', 'LiteSpeed_Cache_ThirdParty_WpForo::purge_tag_post_add', 10, 2) ;
51
+ add_action('wpforo_after_edit_post', 'LiteSpeed_Cache_ThirdParty_WpForo::purge_tag_topic_update') ;
52
+ add_action('wpforo_after_delete_post', 'LiteSpeed_Cache_ThirdParty_WpForo::purge_tag_topic_update') ;
53
+ }
54
+ // for those which doesn't have hooks
55
+ add_action('shutdown', 'LiteSpeed_Cache_ThirdParty_WpForo::wpforo_hook_when_shutdown', -1) ;// use -1 to make evoked before send tag header
56
+ }
57
+
58
+ /**
59
+ * Shutdown purge
60
+ */
61
+ public static function wpforo_hook_when_shutdown() {
62
+ global $wpforo ;
63
+ // admin forum actions
64
+ if ( wpforo_is_admin() && isset($_GET['page']) && $_GET['page'] == 'wpforo-forums' ) {
65
+ if( (isset($_POST['wpforo_submit']) && isset($_REQUEST['forum']) && isset($_GET['action']))
66
+ || (isset($_POST['wpforo_delete']) && $_GET['action'] == 'del')
67
+ || (isset($_POST['forums_hierarchy_submit'])) ) {
68
+ LiteSpeed_Cache_API::purge(self::CACHETAG_COMMON) ;
69
+ }
70
+ }
71
+
72
+ ##Moderation
73
+ if( wpforo_is_admin() && isset($_GET['page']) && $_GET['page'] == 'wpforo-moderations' ) {
74
+ $pids = array() ;
75
+ if( !empty($_GET['id']) && ($pid = wpforo_bigintval($_GET['id'])) ){
76
+ $pids = (array) $pid ;
77
+ }
78
+ elseif( !empty($_GET['ids']) && ($ids = trim($_GET['ids'])) ){
79
+ $ids = explode(',', urldecode($ids)) ;
80
+ $pids = array_map('wpforo_bigintval', array_filter($ids)) ;
81
+ }
82
+ $pids = array_diff($pids, (array) $wpforo->current_userid) ;
83
+ if( ! empty($pids) ) {
84
+ foreach ($pids as $pid){
85
+ $post = $wpforo->post->get_post($pid) ;
86
+ $topicid = $post['topicid'] ;
87
+ self::purge_tag_topic($topicid) ;
88
+ }
89
+ }
90
+
91
+ }
92
+ }
93
+
94
+ /**
95
+ * Purge current topic, and all forums/parent forums/forum homepage
96
+ */
97
+ public static function purge_tag_topic($topicid)
98
+ {
99
+ LiteSpeed_Cache_API::purge(self::CACHETAG_TOPIC . $topicid) ;
100
+ LiteSpeed_Cache_API::purge(self::CACHETAG_FORUM) ;
101
+ LiteSpeed_Cache_API::purge(self::CACHETAG_FRONTPAGE) ;
102
+ }
103
+
104
+ /**
105
+ * Purge topic when a topic is added
106
+ */
107
+ public static function purge_tag_topic_add($args)
108
+ {
109
+ // LiteSpeed_Cache_API::purge(self::CACHETAG_FORUM . $args['forumid']) ;
110
+ LiteSpeed_Cache_API::purge(self::CACHETAG_FORUM) ;
111
+ LiteSpeed_Cache_API::purge(self::CACHETAG_FRONTPAGE) ;
112
+ }
113
+
114
+ /**
115
+ * Purge topic when a topic is modified
116
+ */
117
+ public static function purge_tag_topic_update($args)
118
+ {
119
+ if( ! empty($args['topicid']) ) {
120
+ self::purge_tag_topic($args['topicid']) ;
121
+ }
122
+ }
123
+
124
+ /**
125
+ * Purge topic when a post is added
126
+ */
127
+ public static function purge_tag_post_add($post, $topic)
128
+ {
129
+ if( ! empty($topic['topicid']) ) {
130
+ self::purge_tag_topic($topic['topicid']) ;
131
+ }
132
+ }
133
+
134
+ /**
135
+ * Send cache tags for current page
136
+ */
137
+ public static function cache_tags()
138
+ {
139
+ global $wpforo ;
140
+ if( ! empty($wpforo->current_object['template']) ) {
141
+ if( $wpforo->current_object['template'] == 'forum' ) {
142
+ LiteSpeed_Cache_API::tag_add(self::CACHETAG_FRONTPAGE) ;
143
+ LiteSpeed_Cache_API::tag_add(self::CACHETAG_COMMON) ;
144
+ }
145
+ if( $wpforo->current_object['template'] == 'topic' ) {
146
+ LiteSpeed_Cache_API::tag_add(self::CACHETAG_FORUM . $wpforo->current_object['forum']['forumid']) ;
147
+ LiteSpeed_Cache_API::tag_add(self::CACHETAG_FORUM) ;
148
+ LiteSpeed_Cache_API::tag_add(self::CACHETAG_COMMON) ;
149
+ }
150
+ if( $wpforo->current_object['template'] == 'post' ) {
151
+ LiteSpeed_Cache_API::tag_add(self::CACHETAG_TOPIC . $wpforo->current_object['topic']['topicid']) ;
152
+ LiteSpeed_Cache_API::tag_add(self::CACHETAG_COMMON) ;
153
+ }
154
+ }
155
+ }
156
+
157
+ }
thirdparty/lscwp-3rd-wplister.cls.php ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The Third Party integration with the WPLister plugin.
4
+ *
5
+ * @since 1.1.0
6
+ * @package LiteSpeed_Cache
7
+ * @subpackage LiteSpeed_Cache/thirdparty
8
+ * @author LiteSpeed Technologies <info@litespeedtech.com>
9
+ */
10
+ if ( ! defined('ABSPATH') ) {
11
+ die() ;
12
+ }
13
+
14
+ LiteSpeed_Cache_API::register('LiteSpeed_Cache_ThirdParty_WPLister') ;
15
+
16
+ class LiteSpeed_Cache_ThirdParty_WPLister
17
+ {
18
+ /**
19
+ * Detects if WooCommerce and WPLister are installed.
20
+ *
21
+ * @since 1.1.0
22
+ * @access public
23
+ */
24
+ public static function detect()
25
+ {
26
+ if ( defined('WOOCOMMERCE_VERSION') && defined('WPLISTER_VERSION') ) {
27
+ // User reported this will sync correctly.
28
+ add_action('wplister_revise_inventory_status', 'LiteSpeed_Cache_ThirdParty_WooCommerce::backend_purge') ;
29
+ // Added as a safety measure for WPLister Pro only.
30
+ add_action('wplister_inventory_status_changed', 'LiteSpeed_Cache_ThirdParty_WooCommerce::backend_purge') ;
31
+ }
32
+ }
33
+
34
+ }
thirdparty/lscwp-3rd-wptouch.cls.php ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The Third Party integration with the WPTouch Mobile plugin.
4
+ *
5
+ * @since 1.0.7
6
+ * @package LiteSpeed_Cache
7
+ * @subpackage LiteSpeed_Cache/thirdparty
8
+ * @author LiteSpeed Technologies <info@litespeedtech.com>
9
+ */
10
+ if ( ! defined('ABSPATH') ) {
11
+ die() ;
12
+ }
13
+
14
+ LiteSpeed_Cache_API::register('LiteSpeed_Cache_ThirdParty_WpTouch') ;
15
+
16
+ class LiteSpeed_Cache_ThirdParty_WpTouch
17
+ {
18
+ /**
19
+ * Detects if WPTouch is installed.
20
+ *
21
+ * @since 1.0.7
22
+ * @access public
23
+ */
24
+ public static function detect()
25
+ {
26
+ global $wptouch_pro ;
27
+ if ( isset($wptouch_pro) ) {
28
+ LiteSpeed_Cache_API::hook_control('LiteSpeed_Cache_ThirdParty_WpTouch::set_control') ;
29
+ }
30
+ }
31
+
32
+ /**
33
+ * Check if the device is mobile. If so, set mobile.
34
+ *
35
+ * @since 1.0.7
36
+ * @access public
37
+ */
38
+ public static function set_control()
39
+ {
40
+ global $wptouch_pro ;
41
+ if ( $wptouch_pro->is_mobile_device ) {
42
+ LiteSpeed_Cache_API::set_mobile() ;
43
+ }
44
+ }
45
+
46
+ }
47
+
thirdparty/lscwp-3rd-yith-wishlist.cls.php ADDED
@@ -0,0 +1,97 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * The Third Party integration with the YITH WooCommerce Wishlist plugin.
5
+ *
6
+ * @since 1.1.0
7
+ * @package LiteSpeed_Cache
8
+ * @subpackage LiteSpeed_Cache/thirdparty
9
+ * @author LiteSpeed Technologies <info@litespeedtech.com>
10
+ */
11
+ if ( ! defined('ABSPATH') ) {
12
+ die() ;
13
+ }
14
+
15
+ LiteSpeed_Cache_API::register('LiteSpeed_Cache_ThirdParty_Yith_Wishlist') ;
16
+
17
+ class LiteSpeed_Cache_ThirdParty_Yith_Wishlist
18
+ {
19
+ const ESI_PARAM_ATTS = 'yith_wcwl_atts' ;
20
+ const ESI_PARAM_POSTID = 'yith_wcwl_post_id' ;
21
+ private static $atts = null ; // Not currently used. Depends on how YITH adds attributes
22
+
23
+ /**
24
+ * Detects if YITH WooCommerce Wishlist and WooCommerce are installed.
25
+ *
26
+ * @since 1.1.0
27
+ * @access public
28
+ */
29
+ public static function detect()
30
+ {
31
+ if ( ! defined('WOOCOMMERCE_VERSION') || ! defined('YITH_WCWL') ) {
32
+ return ;
33
+ }
34
+ if ( LSWCP_ESI_SUPPORT && LiteSpeed_Cache::config( LiteSpeed_Cache_Config::OPID_ESI_ENABLE ) ) {
35
+ LiteSpeed_Cache_API::hook_tpl_not_esi('LiteSpeed_Cache_ThirdParty_Yith_Wishlist::is_not_esi') ;
36
+ LiteSpeed_Cache_API::hook_tpl_esi('yith-wcwl-add', 'LiteSpeed_Cache_ThirdParty_Yith_Wishlist::load_add_to_wishlist') ;
37
+ }
38
+ }
39
+
40
+ /**
41
+ * Hooked to the litespeed_cache_is_not_esi_template action.
42
+ *
43
+ * If the request is not an ESI request, hook to the add to wishlist button
44
+ * filter to replace it as an esi block.
45
+ *
46
+ * @since 1.1.0
47
+ * @access public
48
+ */
49
+ public static function is_not_esi()
50
+ {
51
+ add_filter('yith_wcwl_add_to_wishlisth_button_html', 'LiteSpeed_Cache_ThirdParty_Yith_Wishlist::sub_add_to_wishlist', 999) ;
52
+
53
+ }
54
+
55
+ /**
56
+ * Hooked to the yith_wcwl_add_to_wishlisth_button_html filter.
57
+ *
58
+ * The add to wishlist button displays a different output when the item
59
+ * is already in the wishlist/cart. For this reason, the button must be
60
+ * an ESI block. This function replaces the normal html with the ESI
61
+ * block.
62
+ *
63
+ * @since 1.1.0
64
+ * @access public
65
+ * @param $template unused
66
+ * @return string The html for future callbacks to filter.
67
+ */
68
+ public static function sub_add_to_wishlist( $template )
69
+ {
70
+ global $post ;
71
+ $params = array(
72
+ self::ESI_PARAM_POSTID => $post->ID
73
+ ) ;
74
+ LiteSpeed_Cache_API::esi_url( 'yith-wcwl-add', 'YITH ADD TO WISHLIST', $params ) ;
75
+ return '' ;
76
+ }
77
+
78
+ /**
79
+ * Hooked to the litespeed_cache_load_esi_block-yith-wcwl-add action.
80
+ *
81
+ * This will load the add to wishlist button html for output.
82
+ *
83
+ * @since 1.1.0
84
+ * @access public
85
+ * @global $post, $wp_query
86
+ * @param array $params The input ESI parameters.
87
+ */
88
+ public static function load_add_to_wishlist($params)
89
+ {
90
+ global $post, $wp_query ;
91
+ $post = get_post($params[self::ESI_PARAM_POSTID]) ;
92
+ $wp_query->setup_postdata($post) ;
93
+ echo YITH_WCWL_Shortcode::add_to_wishlist(/*$params[self::ESI_PARAM_ATTS]*/array()) ;
94
+ LiteSpeed_Cache_API::set_cache_private();
95
+ }
96
+
97
+ }
thirdparty/lscwp-registry-3rd.php ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * The registry for Third Party Plugins Integration files.
5
+ *
6
+ * This file is only used to include the integration files/classes.
7
+ * This works as an entry point for the initial add_action for the
8
+ * detect function.
9
+ *
10
+ * It is not required to add all integration files here, this just provides
11
+ * a common place for plugin authors to append their file to.
12
+ *
13
+ */
14
+ if ( ! defined('ABSPATH') ) {
15
+ die() ;
16
+ }
17
+
18
+ $thirdparty_list = array(
19
+ 'aelia-currencyswitcher',
20
+ 'autoptimize',
21
+ 'bbpress',
22
+ 'betterwp-minify',
23
+ 'nextgengallery',
24
+ 'theme-my-login',
25
+ 'woocommerce',
26
+ 'wp-polls',
27
+ 'wplister',
28
+ 'wptouch',
29
+ 'yith-wishlist',
30
+ 'wpforo',
31
+ 'avada',
32
+ 'wp-postratings',
33
+ ) ;
34
+
35
+ foreach ($thirdparty_list as $val) {
36
+ include_once(LSWCP_DIR . 'thirdparty/lscwp-3rd-' . $val . '.cls.php') ;
37
+ }