LiteSpeed Cache - Version 3.2.4

Version Description

  • Jul 8 2020 =
  • Object New installations no longer get custom data.ini reset, as this could cause lost configuration. (@Eric)
  • ESI Now using svar to load nonces more quickly. (@Lauren)
  • ESI Fixed the conflicts between nonces in inline JS and ESI Nonces when Inline JS Deferred is enabled. (@JesseDistad)
  • ESI Fixed Fetch Latest Predefined Nonce button.
  • Cache Fixed an issue where mobile visits were not being cached when Cache Mobile was disabled.
  • CDN Bypass CDN constant LITESPEED_BYPASS_CDN now will apply to all CDN replacements.
  • Router Dropped Router::get_uid() function.
  • Crawler Updated role simulator function for future UCSS usage.
  • GUI Textarea will now automatically adjust the height based on the number of rows input.
  • CLI Fixed an issue that caused WP-Cron to exit when a task errored out. (@DovidLevine @MatthewJohnson)
  • Cloud No longer communcate with QUIC.cloud when Domain Key is not set and Debug is enabled.
  • Cloud Score banner no longer automatically fetches a new score. (@LucasRolff)
Download this release

Release Info

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

Code changes from version 3.2.3.2 to 3.2.4

data/const.default.ini CHANGED
@@ -224,6 +224,15 @@ optm-css_comb_priority = false
224
  ; O_OPTM_CSS_UNIQUE
225
  optm-css_unique = false
226
 
 
 
 
 
 
 
 
 
 
227
  ; O_OPTM_CSS_HTTP2
228
  optm-css_http2 = false
229
 
224
  ; O_OPTM_CSS_UNIQUE
225
  optm-css_unique = false
226
 
227
+ ; O_OPTM_UCSS
228
+ optm-ucss = false
229
+
230
+ ; O_OPTM_UCSS_ASYNC
231
+ optm-ucss_async = false
232
+
233
+ ; O_OPTM_UCSS_WHITELIST
234
+ optm-ucss_whitelist = false
235
+
236
  ; O_OPTM_CSS_HTTP2
237
  optm-css_http2 = false
238
 
data/esi.nonce.txt CHANGED
@@ -1,5 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  cmreg_registration_nonce private
2
  role_nonce private
3
 
4
- # Woocommerce Delivery Area Pro #16843635
5
  wdap-call-nonce private
1
+ ## Predefined elsewhere so not needed here:
2
+
3
+ ## WordPress core
4
+ #stats_nonce
5
+ #subscribe_nonce
6
+
7
+ # Divi Theme Builder
8
+ #et-pb-contact-form-submit
9
+ #et_frontend_nonce
10
+ #et_ab_log_nonce
11
+
12
+ # WooCommerce PayPal Checkout
13
+ #_wc_ppec_update_shipping_costs_nonce private
14
+ #_wc_ppec_start_checkout_nonce private
15
+ #_wc_ppec_generate_cart_nonce private
16
+
17
+ # User Switching
18
+ #switch_to_olduser_'<ID>'
19
+
20
+ # Caldera Forms
21
+ #caldera_forms_front_*
22
+
23
+ ## Predefined list of ESI nonces:
24
+
25
+ # CM Registration Pro
26
  cmreg_registration_nonce private
27
  role_nonce private
28
 
29
+ # WooCommerce Delivery Area Pro #16843635
30
  wdap-call-nonce private
litespeed-cache.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: LiteSpeed Cache
4
  * Plugin URI: https://www.litespeedtech.com/products/cache-plugins/wordpress-acceleration
5
  * Description: High-performance page caching and site optimization from LiteSpeed
6
- * Version: 3.2.3.2
7
  * Author: LiteSpeed Technologies
8
  * Author URI: https://www.litespeedtech.com
9
  * License: GPLv3
@@ -33,7 +33,7 @@ if ( class_exists( 'LiteSpeed\Core' ) || defined( 'LSCWP_DIR' ) ) {
33
  return;
34
  }
35
 
36
- ! defined( 'LSCWP_V' ) && define( 'LSCWP_V', '3.2.3.2' );
37
 
38
  ! defined( 'LSCWP_CONTENT_DIR' ) && define( 'LSCWP_CONTENT_DIR', WP_CONTENT_DIR ) ;
39
  ! defined( 'LSCWP_DIR' ) && define( 'LSCWP_DIR', __DIR__ . '/' ) ;// Full absolute path '/var/www/html/***/wp-content/plugins/litespeed-cache/' or MU
@@ -132,7 +132,7 @@ if ( ! function_exists( 'litespeed_define_nonce_func' ) ) {
132
  $params = array(
133
  'action' => $action,
134
  );
135
- return \LiteSpeed\ESI::sub_esi_block( 'nonce', 'wp_create_nonce ' . $action, $params, $control, true, true );
136
  }
137
  }
138
 
@@ -144,8 +144,7 @@ if ( ! function_exists( 'litespeed_define_nonce_func' ) ) {
144
  * Ori WP wp_create_nonce
145
  */
146
  function wp_create_nonce_litespeed_esi( $action = -1 ) {
147
- $user = wp_get_current_user();
148
- $uid = (int) $user->ID;
149
  if ( ! $uid ) {
150
  /** This filter is documented in wp-includes/pluggable.php */
151
  $uid = apply_filters( 'nonce_user_logged_out', $uid, $action );
3
  * Plugin Name: LiteSpeed Cache
4
  * Plugin URI: https://www.litespeedtech.com/products/cache-plugins/wordpress-acceleration
5
  * Description: High-performance page caching and site optimization from LiteSpeed
6
+ * Version: 3.2.4
7
  * Author: LiteSpeed Technologies
8
  * Author URI: https://www.litespeedtech.com
9
  * License: GPLv3
33
  return;
34
  }
35
 
36
+ ! defined( 'LSCWP_V' ) && define( 'LSCWP_V', '3.2.4' );
37
 
38
  ! defined( 'LSCWP_CONTENT_DIR' ) && define( 'LSCWP_CONTENT_DIR', WP_CONTENT_DIR ) ;
39
  ! defined( 'LSCWP_DIR' ) && define( 'LSCWP_DIR', __DIR__ . '/' ) ;// Full absolute path '/var/www/html/***/wp-content/plugins/litespeed-cache/' or MU
132
  $params = array(
133
  'action' => $action,
134
  );
135
+ return \LiteSpeed\ESI::sub_esi_block( 'nonce', 'wp_create_nonce ' . $action, $params, $control, true, true, true );
136
  }
137
  }
138
 
144
  * Ori WP wp_create_nonce
145
  */
146
  function wp_create_nonce_litespeed_esi( $action = -1 ) {
147
+ $uid = get_current_user_id();
 
148
  if ( ! $uid ) {
149
  /** This filter is documented in wp-includes/pluggable.php */
150
  $uid = apply_filters( 'nonce_user_logged_out', $uid, $action );
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: LiteSpeedTech
3
  Tags: caching, optimize, performance, pagespeed, seo, speed, image optimize, compress, object cache, redis, memcached, database cleaner
4
  Requires at least: 4.0
5
  Tested up to: 5.4.2
6
- Stable tag: 3.2.3.2
7
  License: GPLv3
8
  License URI: http://www.gnu.org/licenses/gpl.html
9
 
@@ -16,9 +16,9 @@ LiteSpeed Cache for WordPress (LSCWP) is an all-in-one site acceleration plugin,
16
  LSCWP supports WordPress Multisite and is compatible with most popular plugins, including WooCommerce, bbPress, and Yoast SEO.
17
 
18
  == Requirements ==
19
- **General Features** may be used by anyone with any web server (LiteSpeed, Apache, NGiNX, etc.).
20
 
21
- **LiteSpeed Exclusive Features** require one of the following: OpenLiteSpeed, commercial LiteSpeed products, LiteSpeed-powered hosting, or QUIc.cloud CDN. [Why?](https://docs.litespeedtech.com/lscache/lscwp/faq/#why-do-the-cache-features-require-a-litespeed-server)
22
 
23
  == Plugin Features ==
24
 
@@ -42,9 +42,8 @@ LSCWP supports WordPress Multisite and is compatible with most popular plugins,
42
  * HTTP/2 Push for CSS/JS (on web servers that support it)
43
  * DNS Prefetch
44
  * Cloudflare API
45
- * Single Site and Multi Site (Network) support
46
  * Import/Export settings
47
- * Basic/Advanced setting view
48
  * Attractive, easy-to-understand interface
49
  * WebP image format support
50
  * Heartbeat control
@@ -58,7 +57,7 @@ LSCWP supports WordPress Multisite and is compatible with most popular plugins,
58
  * Separate caching of desktop and mobile views
59
  * Ability to schedule purge for specified URLs
60
  * WooCommerce and bbPress support
61
- * [WordPress CLI](https://docs.litespeedtech.com/lscache/lscwp/admin/#wordpress-cli) commands
62
  * API system for easy cache integration
63
  * Exclude from cache by URI, Category, Tag, Cookie, User Agent
64
  * Smart preload crawler with support for SEO-friendly sitemap
@@ -109,13 +108,13 @@ LSCWP supports WordPress Multisite and is compatible with most popular plugins,
109
  = Notes for LiteSpeed Web Server Enterprise =
110
 
111
  * Make sure that your license includes the LSCache module. 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.
112
- * 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) for instructions. Otherwise, please request that the server admin configure the cache root for the server.
113
 
114
  = Notes for OpenLiteSpeed =
115
 
116
  * This integration utilizes OpenLiteSpeed's cache module.
117
- * 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.
118
- * If OLS and WordPress are both already installed, please follow the instructions in [How To Set Up LSCache For WordPress](http://open.litespeedtech.com/mediawiki/index.php/Help:How_To_Set_Up_LSCache_For_WordPress).
119
 
120
  == Third Party Compatibility ==
121
 
@@ -191,11 +190,11 @@ In short, yes. However, for some WooCommerce themes, the cart may not be updated
191
 
192
  = Are my images optimized? =
193
 
194
- Images are not optimized automatically unless you set **LiteSpeed Cache > Image Optimization > Image Optimization Settings > Auto Request Cron** to `ON`. You may also optimiza your images manually. [Learn more](https://docs.litespeedtech.com/lscache/lscwp/imageopt/).
195
 
196
  = How do I make a WP nonce cacheable in my third-party plugin? =
197
 
198
- Our API includes a function that uses ESI to "punch a hole" in a cached page for a nonce. This allows the nonce to be cached for 12 hours, regardless of the TTL of the page it is on. Learn more in [the API documentation](https://docs.litespeedtech.com/lscache/lscwp/api/).
199
 
200
  = How do I enable the crawler? =
201
 
@@ -227,7 +226,7 @@ For more detailed information about crawler setup, please see [the Crawler docum
227
  * [WP-PostRatings](https://wordpress.org/plugins/wp-postratings/)
228
  * [Avada 5.1 RC1+](https://avada.theme-fusion.com/)
229
  * [Elegant Themes Divi 3.0.67+](https://www.elegantthemes.com/gallery/divi/)
230
- * [Elegant Divi Builder] (https://www.elegantthemes.com/plugins/divi-builder/)
231
  * [Caldera Forms](https://wordpress.org/plugins/caldera-forms/) 1.5.6.2+
232
  * Login With Ajax
233
  * [Ninja Forms](https://wordpress.org/plugins/ninja-forms/)
@@ -244,8 +243,22 @@ The vast majority of plugins and themes are compatible with LiteSpeed Cache. The
244
 
245
  == Changelog ==
246
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
247
  = 3.2.3.2 - Jun 19 2020 =
248
- * 🔥🐞**Page Optimize** Hotfix for CSS/JS minify/combine.
249
 
250
  = 3.2.3.1 - Jun 18 2020 =
251
  * **API** New filter `litespeed_buffer_before` and `litespeed_buffer_after`. (#PR243 @joejordanbrown)
@@ -282,7 +295,7 @@ The vast majority of plugins and themes are compatible with LiteSpeed Cache. The
282
  * **GUI** Moved Use Primary Site Configuration to General menu. (@joshua)
283
 
284
  = 3.2 - May 27 2020 =
285
- * **Image Optimize** Major improvements in queue management, scalability, and speed. (@Lucas Rolff)
286
  * **Cloud** Implemented a series of communication enhancements. (@Lucas Rolff)
287
  * **Crawler** Enhanced PHP 5.3 compatibility. (@JTS-FIN #230)
288
  * **Page Optimize** Appended image template in wpDiscuz script into default lazyload image exclude list. (@philipfaster @szmigieldesign)
3
  Tags: caching, optimize, performance, pagespeed, seo, speed, image optimize, compress, object cache, redis, memcached, database cleaner
4
  Requires at least: 4.0
5
  Tested up to: 5.4.2
6
+ Stable tag: 3.2.4
7
  License: GPLv3
8
  License URI: http://www.gnu.org/licenses/gpl.html
9
 
16
  LSCWP supports WordPress Multisite and is compatible with most popular plugins, including WooCommerce, bbPress, and Yoast SEO.
17
 
18
  == Requirements ==
19
+ **General Features** may be used by anyone with any web server (LiteSpeed, Apache, NGINX, etc.).
20
 
21
+ **LiteSpeed Exclusive Features** require one of the following: OpenLiteSpeed, commercial LiteSpeed products, LiteSpeed-powered hosting, or QUIC.cloud CDN. [Why?](https://docs.litespeedtech.com/lscache/lscwp/faq/#why-do-the-cache-features-require-a-litespeed-server)
22
 
23
  == Plugin Features ==
24
 
42
  * HTTP/2 Push for CSS/JS (on web servers that support it)
43
  * DNS Prefetch
44
  * Cloudflare API
45
+ * Single Site and Multisite (Network) support
46
  * Import/Export settings
 
47
  * Attractive, easy-to-understand interface
48
  * WebP image format support
49
  * Heartbeat control
57
  * Separate caching of desktop and mobile views
58
  * Ability to schedule purge for specified URLs
59
  * WooCommerce and bbPress support
60
+ * [WordPress CLI](https://docs.litespeedtech.com/lscache/lscwp/cli/) commands
61
  * API system for easy cache integration
62
  * Exclude from cache by URI, Category, Tag, Cookie, User Agent
63
  * Smart preload crawler with support for SEO-friendly sitemap
108
  = Notes for LiteSpeed Web Server Enterprise =
109
 
110
  * Make sure that your license includes the LSCache module. 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.
111
+ * The server must be configured to have caching enabled. If you are the server admin, [click here](https://docs.litespeedtech.com/lscache/lscwp/overview/#configure-cache-root) for instructions. Otherwise, please request that the server admin configure the cache root for the server.
112
 
113
  = Notes for OpenLiteSpeed =
114
 
115
  * This integration utilizes OpenLiteSpeed's cache module.
116
+ * If it is a fresh OLS installation, the easiest way to integrate is to use [ols1clk](https://openlitespeed.org/kb/1-click-install/). If using an existing WordPress installation, use the `--wordpresspath` parameter.
117
+ * If OLS and WordPress are both already installed, please follow the instructions in [How To Set Up LSCache For WordPress](https://openlitespeed.org/kb/how-to-setup-lscache-for-wordpress/).
118
 
119
  == Third Party Compatibility ==
120
 
190
 
191
  = Are my images optimized? =
192
 
193
+ Images are not optimized automatically unless you set **LiteSpeed Cache > Image Optimization > Image Optimization Settings > Auto Request Cron** to `ON`. You may also optimize your images manually. [Learn more](https://docs.litespeedtech.com/lscache/lscwp/imageopt/).
194
 
195
  = How do I make a WP nonce cacheable in my third-party plugin? =
196
 
197
+ Our API includes a function that uses ESI to "punch a hole" in a cached page for a nonce. This allows the nonce to be cached separately, regardless of the TTL of the page it is on. Learn more in [the API documentation](https://docs.litespeedtech.com/lscache/lscwp/api/#esi). We also welcome contributions to our predefined list of known third party plugin nonces that users can optionally include via [the plugin's ESI settings](https://docs.litespeedtech.com/lscache/lscwp/cache/#esi-nonce).
198
 
199
  = How do I enable the crawler? =
200
 
226
  * [WP-PostRatings](https://wordpress.org/plugins/wp-postratings/)
227
  * [Avada 5.1 RC1+](https://avada.theme-fusion.com/)
228
  * [Elegant Themes Divi 3.0.67+](https://www.elegantthemes.com/gallery/divi/)
229
+ * [Elegant Divi Builder](https://www.elegantthemes.com/plugins/divi-builder/)
230
  * [Caldera Forms](https://wordpress.org/plugins/caldera-forms/) 1.5.6.2+
231
  * Login With Ajax
232
  * [Ninja Forms](https://wordpress.org/plugins/ninja-forms/)
243
 
244
  == Changelog ==
245
 
246
+ = 3.2.4 - Jul 8 2020 =
247
+ * **Object** New installations no longer get custom data.ini reset, as this could cause lost configuration. (@Eric)
248
+ * **ESI** Now using `svar` to load nonces more quickly. (@Lauren)
249
+ * **ESI** Fixed the conflicts between nonces in inline JS and ESI Nonces when Inline JS Deferred is enabled. (@JesseDistad)
250
+ * 🐞**ESI** Fixed Fetch Latest Predefined Nonce button.
251
+ * 🐞**Cache** Fixed an issue where mobile visits were not being cached when Cache Mobile was disabled.
252
+ * **CDN** Bypass CDN constant `LITESPEED_BYPASS_CDN` now will apply to all CDN replacements.
253
+ * **Router** Dropped `Router::get_uid()` function.
254
+ * **Crawler** Updated role simulator function for future UCSS usage.
255
+ * **GUI** Textarea will now automatically adjust the height based on the number of rows input.
256
+ * **CLI** Fixed an issue that caused WP-Cron to exit when a task errored out. (@DovidLevine @MatthewJohnson)
257
+ * **Cloud** No longer communcate with QUIC.cloud when Domain Key is not set and Debug is enabled.
258
+ * **Cloud** Score banner no longer automatically fetches a new score. (@LucasRolff)
259
+
260
  = 3.2.3.2 - Jun 19 2020 =
261
+ * 🔥🐞**Page Optimize** Hotfix for CSS/JS minify/combine. (@jdelgadoesteban @martin_bailey)
262
 
263
  = 3.2.3.1 - Jun 18 2020 =
264
  * **API** New filter `litespeed_buffer_before` and `litespeed_buffer_after`. (#PR243 @joejordanbrown)
295
  * **GUI** Moved Use Primary Site Configuration to General menu. (@joshua)
296
 
297
  = 3.2 - May 27 2020 =
298
+ * **Image Optimize** Major improvements in queue management, scalability, and speed. (@LucasRolff)
299
  * **Cloud** Implemented a series of communication enhancements. (@Lucas Rolff)
300
  * **Crawler** Enhanced PHP 5.3 compatibility. (@JTS-FIN #230)
301
  * **Page Optimize** Appended image template in wpDiscuz script into default lazyload image exclude list. (@philipfaster @szmigieldesign)
src/admin-display.cls.php CHANGED
@@ -231,7 +231,7 @@ class Admin_Display extends Base
231
  $localize_data[ 'ajax_url_getIP' ] = function_exists( 'get_rest_url' ) ? get_rest_url( null, 'litespeed/v1/tool/check_ip' ) : '/';
232
  $localize_data[ 'nonce' ] = wp_create_nonce( 'wp_rest' );
233
  }
234
- if ( ( $pagenow == 'admin.php' && ! empty( $_GET[ 'page' ] ) && $_GET[ 'page' ] == 'litespeed-crawler' )
235
  || ( $pagenow == 'options-general.php' && ! empty( $_GET[ 'page' ] ) && $_GET[ 'page' ] == 'litespeed-cache-options' )
236
  ) {
237
  $localize_data[ 'ajax_url_fetch_esi_nonce' ] = function_exists( 'get_rest_url' ) ? get_rest_url( null, 'litespeed/v1/fetch_esi_nonce' ) : '/';
@@ -398,7 +398,7 @@ class Admin_Display extends Base
398
  if ( defined( 'WP_CLI' ) && WP_CLI ) {
399
  $msg = strip_tags( $msg );
400
  if ( $color == self::NOTICE_RED ) {
401
- \WP_CLI::error( $msg );
402
  }
403
  else {
404
  \WP_CLI::success( $msg );
@@ -431,8 +431,7 @@ class Admin_Display extends Base
431
  * @since 1.1.0
432
  * @access public
433
  */
434
- public function display_messages()
435
- {
436
  if ( GUI::has_whm_msg() ) {
437
  $this->show_display_installed();
438
  }
@@ -452,12 +451,12 @@ class Admin_Display extends Base
452
  // Added for popup links
453
  if ( strpos( $msg, 'TB_iframe' ) && ! $added_thickbox ) {
454
  add_thickbox();
455
- $added_thickbox = true ;
456
  }
457
- echo $msg ;
458
  }
459
  }
460
- self::delete_option( self::DB_MSG ) ;
461
 
462
  if( empty( $_GET[ 'page' ] ) || strpos( $_GET[ 'page' ], 'litespeed' ) !== 0 ) {
463
  global $pagenow;
@@ -482,7 +481,7 @@ class Admin_Display extends Base
482
  * Check promo msg first
483
  * @since 2.9
484
  */
485
- GUI::get_instance()->show_promo() ;
486
 
487
  // Show version news
488
  Cloud::get_instance()->news();
@@ -693,23 +692,31 @@ class Admin_Display extends Base
693
  * @since 1.1.0
694
  * @access public
695
  */
696
- public function build_textarea( $id, $cols = false, $val = null )
697
- {
698
  if ( $val === null ) {
699
- $val = Conf::val( $id, true ) ;
700
 
701
  if ( is_array( $val ) ) {
702
- $val = implode( "\n", $val ) ;
703
  }
704
  }
705
 
706
  if ( ! $cols ) {
707
- $cols = 80 ;
708
  }
709
 
710
- $this->enroll( $id ) ;
 
 
 
 
 
 
 
 
 
711
 
712
- echo "<textarea name='$id' rows='5' cols='$cols'>" . esc_textarea( $val ) . "</textarea>" ;
713
 
714
  $this->_check_overwritten( $id );
715
  }
@@ -762,7 +769,7 @@ class Admin_Display extends Base
762
  if ( $checked === null && Conf::val( $id, true ) ) {
763
  $checked = true;
764
  }
765
- $checked = $checked ? ' checked ' : '' ;
766
 
767
  $label_id = preg_replace( '|\W|', '', $id ) ;
768
 
231
  $localize_data[ 'ajax_url_getIP' ] = function_exists( 'get_rest_url' ) ? get_rest_url( null, 'litespeed/v1/tool/check_ip' ) : '/';
232
  $localize_data[ 'nonce' ] = wp_create_nonce( 'wp_rest' );
233
  }
234
+ if ( ( $pagenow == 'admin.php' && ! empty( $_GET[ 'page' ] ) && $_GET[ 'page' ] == 'litespeed-cache' )
235
  || ( $pagenow == 'options-general.php' && ! empty( $_GET[ 'page' ] ) && $_GET[ 'page' ] == 'litespeed-cache-options' )
236
  ) {
237
  $localize_data[ 'ajax_url_fetch_esi_nonce' ] = function_exists( 'get_rest_url' ) ? get_rest_url( null, 'litespeed/v1/fetch_esi_nonce' ) : '/';
398
  if ( defined( 'WP_CLI' ) && WP_CLI ) {
399
  $msg = strip_tags( $msg );
400
  if ( $color == self::NOTICE_RED ) {
401
+ \WP_CLI::error( $msg, false );
402
  }
403
  else {
404
  \WP_CLI::success( $msg );
431
  * @since 1.1.0
432
  * @access public
433
  */
434
+ public function display_messages() {
 
435
  if ( GUI::has_whm_msg() ) {
436
  $this->show_display_installed();
437
  }
451
  // Added for popup links
452
  if ( strpos( $msg, 'TB_iframe' ) && ! $added_thickbox ) {
453
  add_thickbox();
454
+ $added_thickbox = true;
455
  }
456
+ echo $msg;
457
  }
458
  }
459
+ self::delete_option( self::DB_MSG );
460
 
461
  if( empty( $_GET[ 'page' ] ) || strpos( $_GET[ 'page' ], 'litespeed' ) !== 0 ) {
462
  global $pagenow;
481
  * Check promo msg first
482
  * @since 2.9
483
  */
484
+ GUI::get_instance()->show_promo();
485
 
486
  // Show version news
487
  Cloud::get_instance()->news();
692
  * @since 1.1.0
693
  * @access public
694
  */
695
+ public function build_textarea( $id, $cols = false, $val = null ) {
 
696
  if ( $val === null ) {
697
+ $val = Conf::val( $id, true );
698
 
699
  if ( is_array( $val ) ) {
700
+ $val = implode( "\n", $val );
701
  }
702
  }
703
 
704
  if ( ! $cols ) {
705
+ $cols = 80;
706
  }
707
 
708
+ $rows = 5;
709
+ $lines = substr_count( $val, "\n" ) + 2;
710
+ if ( $lines > $rows ) {
711
+ $rows = $lines;
712
+ }
713
+ if ( $rows > 40 ) {
714
+ $rows = 40;
715
+ }
716
+
717
+ $this->enroll( $id );
718
 
719
+ echo "<textarea name='$id' rows='$rows' cols='$cols'>" . esc_textarea( $val ) . "</textarea>";
720
 
721
  $this->_check_overwritten( $id );
722
  }
769
  if ( $checked === null && Conf::val( $id, true ) ) {
770
  $checked = true;
771
  }
772
+ $checked = $checked ? ' checked ' : '';
773
 
774
  $label_id = preg_replace( '|\W|', '', $id ) ;
775
 
src/api.cls.php CHANGED
@@ -128,7 +128,7 @@ class API extends Base {
128
  // API::hook_vary_finalize( $hook ) -> Filter `litespeed_vary`
129
  add_action( 'litespeed_vary_no', __NAMESPACE__ . '\Control::set_no_vary' ); // API::set_cache_no_vary() -> Action `litespeed_vary_no` // Set cache status to no vary
130
 
131
- add_filter( 'litespeed_is_mobile', __NAMESPACE__ . '\Control::is_mobile' ); // API::set_mobile() -> Filter `litespeed_is_mobile`
132
 
133
  /**
134
  * Cloud
128
  // API::hook_vary_finalize( $hook ) -> Filter `litespeed_vary`
129
  add_action( 'litespeed_vary_no', __NAMESPACE__ . '\Control::set_no_vary' ); // API::set_cache_no_vary() -> Action `litespeed_vary_no` // Set cache status to no vary
130
 
131
+ // add_filter( 'litespeed_is_mobile', __NAMESPACE__ . '\Control::is_mobile' ); // API::set_mobile() -> Filter `litespeed_is_mobile`
132
 
133
  /**
134
  * Cloud
src/base.cls.php CHANGED
@@ -125,6 +125,9 @@ class Base extends Instance {
125
  const O_OPTM_CSS_COMB = 'optm-css_comb';
126
  const O_OPTM_CSS_COMB_PRIO = 'optm-css_comb_priority';
127
  const O_OPTM_CSS_UNIQUE = 'optm-css_unique';
 
 
 
128
  const O_OPTM_CSS_HTTP2 = 'optm-css_http2';
129
  const O_OPTM_CSS_EXC = 'optm-css_exc';
130
  const O_OPTM_JS_MIN = 'optm-js_min';
@@ -419,6 +422,9 @@ class Base extends Instance {
419
  self::O_OPTM_CSS_COMB => false,
420
  self::O_OPTM_CSS_COMB_PRIO => false,
421
  self::O_OPTM_CSS_UNIQUE => false,
 
 
 
422
  self::O_OPTM_CSS_HTTP2 => false,
423
  self::O_OPTM_CSS_EXC => array(),
424
  self::O_OPTM_JS_MIN => false,
125
  const O_OPTM_CSS_COMB = 'optm-css_comb';
126
  const O_OPTM_CSS_COMB_PRIO = 'optm-css_comb_priority';
127
  const O_OPTM_CSS_UNIQUE = 'optm-css_unique';
128
+ const O_OPTM_UCSS = 'optm-ucss';
129
+ const O_OPTM_UCSS_ASYNC = 'optm-ucss_async';
130
+ const O_OPTM_UCSS_WHITELIST = 'optm-ucss_whitelist';
131
  const O_OPTM_CSS_HTTP2 = 'optm-css_http2';
132
  const O_OPTM_CSS_EXC = 'optm-css_exc';
133
  const O_OPTM_JS_MIN = 'optm-js_min';
422
  self::O_OPTM_CSS_COMB => false,
423
  self::O_OPTM_CSS_COMB_PRIO => false,
424
  self::O_OPTM_CSS_UNIQUE => false,
425
+ self::O_OPTM_UCSS => false,
426
+ self::O_OPTM_UCSS_ASYNC => false,
427
+ // self::O_OPTM_UCSS_WHITELIST => array(),
428
  self::O_OPTM_CSS_HTTP2 => false,
429
  self::O_OPTM_CSS_EXC => array(),
430
  self::O_OPTM_JS_MIN => false,
src/cdn.cls.php CHANGED
@@ -37,18 +37,22 @@ class CDN extends Instance
37
  * @since 1.2.3
38
  * @access protected
39
  */
40
- protected function __construct()
41
- {
42
- Debug2::debug2( '[CDN] init' ) ;
 
 
 
 
43
 
44
  if ( ! Router::can_cdn() ) {
45
  if ( ! defined( self::BYPASS ) ) {
46
- define( self::BYPASS, true ) ;
47
  }
48
- return ;
49
  }
50
 
51
- $this->__cfg = Conf::get_instance() ;
52
 
53
  /**
54
  * Remotely load jQuery
@@ -57,93 +61,93 @@ class CDN extends Instance
57
  */
58
  $this->_cfg_cdn_remote_jquery = Conf::val( Base::O_CDN_REMOTE_JQ );
59
  if ( $this->_cfg_cdn_remote_jquery ) {
60
- $this->_load_jquery_remotely() ;
61
  }
62
 
63
- $this->_cfg_cdn = Conf::val( Base::O_CDN ) ;
64
  if ( ! $this->_cfg_cdn ) {
65
  if ( ! defined( self::BYPASS ) ) {
66
- define( self::BYPASS, true ) ;
67
  }
68
- return ;
69
  }
70
 
71
- $this->_cfg_url_ori = Conf::val( Base::O_CDN_ORI ) ;
72
  // Parse cdn mapping data to array( 'filetype' => 'url' )
73
  $mapping_to_check = array(
74
  Base::CDN_MAPPING_INC_IMG,
75
  Base::CDN_MAPPING_INC_CSS,
76
  Base::CDN_MAPPING_INC_JS
77
- ) ;
78
  foreach ( Conf::val( Base::O_CDN_MAPPING ) as $v ) {
79
  if ( ! $v[ Base::CDN_MAPPING_URL ] ) {
80
- continue ;
81
  }
82
- $this_url = $v[ Base::CDN_MAPPING_URL ] ;
83
- $this_host = parse_url( $this_url, PHP_URL_HOST ) ;
84
  // Check img/css/js
85
  foreach ( $mapping_to_check as $to_check ) {
86
  if ( $v[ $to_check ] ) {
87
- Debug2::debug2( '[CDN] mapping ' . $to_check . ' -> ' . $this_url ) ;
88
 
89
  // If filetype to url is one to many, make url be an array
90
- $this->_append_cdn_mapping( $to_check, $this_url ) ;
91
 
92
  if ( ! in_array( $this_host, $this->cdn_mapping_hosts ) ) {
93
- $this->cdn_mapping_hosts[] = $this_host ;
94
  }
95
  }
96
  }
97
  // Check file types
98
  if ( $v[ Base::CDN_MAPPING_FILETYPE ] ) {
99
  foreach ( $v[ Base::CDN_MAPPING_FILETYPE ] as $v2 ) {
100
- $this->_cfg_cdn_mapping[ Base::CDN_MAPPING_FILETYPE ] = true ;
101
 
102
  // If filetype to url is one to many, make url be an array
103
- $this->_append_cdn_mapping( $v2, $this_url ) ;
104
 
105
  if ( ! in_array( $this_host, $this->cdn_mapping_hosts ) ) {
106
- $this->cdn_mapping_hosts[] = $this_host ;
107
  }
108
  }
109
- Debug2::debug2( '[CDN] mapping ' . implode( ',', $v[ Base::CDN_MAPPING_FILETYPE ] ) . ' -> ' . $this_url ) ;
110
  }
111
  }
112
 
113
  if ( ! $this->_cfg_url_ori || ! $this->_cfg_cdn_mapping ) {
114
  if ( ! defined( self::BYPASS ) ) {
115
- define( self::BYPASS, true ) ;
116
  }
117
- return ;
118
  }
119
 
120
- $this->_cfg_ori_dir = Conf::val( Base::O_CDN_ORI_DIR ) ;
121
  // In case user customized upload path
122
  if ( defined( 'UPLOADS' ) ) {
123
- $this->_cfg_ori_dir[] = UPLOADS ;
124
  }
125
 
126
  // Check if need preg_replace
127
  $this->_cfg_url_ori = Utility::wildcard2regex( $this->_cfg_url_ori );
128
 
129
- $this->_cfg_cdn_exclude = Conf::val( Base::O_CDN_EXC ) ;
130
 
131
  if ( ! empty( $this->_cfg_cdn_mapping[ Base::CDN_MAPPING_INC_IMG ] ) ) {
132
  // Hook to srcset
133
  if ( function_exists( 'wp_calculate_image_srcset' ) ) {
134
- add_filter( 'wp_calculate_image_srcset', array( $this, 'srcset' ), 999 ) ;
135
  }
136
  // Hook to mime icon
137
- add_filter( 'wp_get_attachment_image_src', array( $this, 'attach_img_src' ), 999 ) ;
138
- add_filter( 'wp_get_attachment_url', array( $this, 'url_img' ), 999 ) ;
139
  }
140
 
141
  if ( ! empty( $this->_cfg_cdn_mapping[ Base::CDN_MAPPING_INC_CSS ] ) ) {
142
- add_filter( 'style_loader_src', array( $this, 'url_css' ), 999 ) ;
143
  }
144
 
145
  if ( ! empty( $this->_cfg_cdn_mapping[ Base::CDN_MAPPING_INC_JS ] ) ) {
146
- add_filter( 'script_loader_src', array( $this, 'url_js' ), 999 ) ;
147
  }
148
 
149
  }
37
  * @since 1.2.3
38
  * @access protected
39
  */
40
+ protected function __construct() {
41
+ Debug2::debug2( '[CDN] init' );
42
+
43
+ if ( defined( self::BYPASS ) ) {
44
+ Debug2::debug2( 'CDN bypass' );
45
+ return;
46
+ }
47
 
48
  if ( ! Router::can_cdn() ) {
49
  if ( ! defined( self::BYPASS ) ) {
50
+ define( self::BYPASS, true );
51
  }
52
+ return;
53
  }
54
 
55
+ $this->__cfg = Conf::get_instance();
56
 
57
  /**
58
  * Remotely load jQuery
61
  */
62
  $this->_cfg_cdn_remote_jquery = Conf::val( Base::O_CDN_REMOTE_JQ );
63
  if ( $this->_cfg_cdn_remote_jquery ) {
64
+ $this->_load_jquery_remotely();
65
  }
66
 
67
+ $this->_cfg_cdn = Conf::val( Base::O_CDN );
68
  if ( ! $this->_cfg_cdn ) {
69
  if ( ! defined( self::BYPASS ) ) {
70
+ define( self::BYPASS, true );
71
  }
72
+ return;
73
  }
74
 
75
+ $this->_cfg_url_ori = Conf::val( Base::O_CDN_ORI );
76
  // Parse cdn mapping data to array( 'filetype' => 'url' )
77
  $mapping_to_check = array(
78
  Base::CDN_MAPPING_INC_IMG,
79
  Base::CDN_MAPPING_INC_CSS,
80
  Base::CDN_MAPPING_INC_JS
81
+ );
82
  foreach ( Conf::val( Base::O_CDN_MAPPING ) as $v ) {
83
  if ( ! $v[ Base::CDN_MAPPING_URL ] ) {
84
+ continue;
85
  }
86
+ $this_url = $v[ Base::CDN_MAPPING_URL ];
87
+ $this_host = parse_url( $this_url, PHP_URL_HOST );
88
  // Check img/css/js
89
  foreach ( $mapping_to_check as $to_check ) {
90
  if ( $v[ $to_check ] ) {
91
+ Debug2::debug2( '[CDN] mapping ' . $to_check . ' -> ' . $this_url );
92
 
93
  // If filetype to url is one to many, make url be an array
94
+ $this->_append_cdn_mapping( $to_check, $this_url );
95
 
96
  if ( ! in_array( $this_host, $this->cdn_mapping_hosts ) ) {
97
+ $this->cdn_mapping_hosts[] = $this_host;
98
  }
99
  }
100
  }
101
  // Check file types
102
  if ( $v[ Base::CDN_MAPPING_FILETYPE ] ) {
103
  foreach ( $v[ Base::CDN_MAPPING_FILETYPE ] as $v2 ) {
104
+ $this->_cfg_cdn_mapping[ Base::CDN_MAPPING_FILETYPE ] = true;
105
 
106
  // If filetype to url is one to many, make url be an array
107
+ $this->_append_cdn_mapping( $v2, $this_url );
108
 
109
  if ( ! in_array( $this_host, $this->cdn_mapping_hosts ) ) {
110
+ $this->cdn_mapping_hosts[] = $this_host;
111
  }
112
  }
113
+ Debug2::debug2( '[CDN] mapping ' . implode( ',', $v[ Base::CDN_MAPPING_FILETYPE ] ) . ' -> ' . $this_url );
114
  }
115
  }
116
 
117
  if ( ! $this->_cfg_url_ori || ! $this->_cfg_cdn_mapping ) {
118
  if ( ! defined( self::BYPASS ) ) {
119
+ define( self::BYPASS, true );
120
  }
121
+ return;
122
  }
123
 
124
+ $this->_cfg_ori_dir = Conf::val( Base::O_CDN_ORI_DIR );
125
  // In case user customized upload path
126
  if ( defined( 'UPLOADS' ) ) {
127
+ $this->_cfg_ori_dir[] = UPLOADS;
128
  }
129
 
130
  // Check if need preg_replace
131
  $this->_cfg_url_ori = Utility::wildcard2regex( $this->_cfg_url_ori );
132
 
133
+ $this->_cfg_cdn_exclude = Conf::val( Base::O_CDN_EXC );
134
 
135
  if ( ! empty( $this->_cfg_cdn_mapping[ Base::CDN_MAPPING_INC_IMG ] ) ) {
136
  // Hook to srcset
137
  if ( function_exists( 'wp_calculate_image_srcset' ) ) {
138
+ add_filter( 'wp_calculate_image_srcset', array( $this, 'srcset' ), 999 );
139
  }
140
  // Hook to mime icon
141
+ add_filter( 'wp_get_attachment_image_src', array( $this, 'attach_img_src' ), 999 );
142
+ add_filter( 'wp_get_attachment_url', array( $this, 'url_img' ), 999 );
143
  }
144
 
145
  if ( ! empty( $this->_cfg_cdn_mapping[ Base::CDN_MAPPING_INC_CSS ] ) ) {
146
+ add_filter( 'style_loader_src', array( $this, 'url_css' ), 999 );
147
  }
148
 
149
  if ( ! empty( $this->_cfg_cdn_mapping[ Base::CDN_MAPPING_INC_JS ] ) ) {
150
+ add_filter( 'script_loader_src', array( $this, 'url_js' ), 999 );
151
  }
152
 
153
  }
src/cloud.cls.php CHANGED
@@ -470,7 +470,7 @@ class Cloud extends Base
470
  }
471
  else {
472
  // For all other requests, if is under debug mode, will always allow
473
- if ( Conf::val( Base::O_DEBUG ) ) {
474
  return true;
475
  }
476
  }
470
  }
471
  else {
472
  // For all other requests, if is under debug mode, will always allow
473
+ if ( Conf::val( Base::O_DEBUG ) && $this->_api_key ) {
474
  return true;
475
  }
476
  }
src/conf.cls.php CHANGED
@@ -89,6 +89,11 @@ class Conf extends Base
89
  if ( ! is_admin() && ! defined( 'LITESPEED_CLI' ) ) {
90
  $this->_options = $this->load_default_vals();
91
  $this->_try_load_site_options();
 
 
 
 
 
92
  return;
93
  }
94
  }
89
  if ( ! is_admin() && ! defined( 'LITESPEED_CLI' ) ) {
90
  $this->_options = $this->load_default_vals();
91
  $this->_try_load_site_options();
92
+
93
+ // Disable new installation auto upgrade to avoid overwritten to customized data.ini
94
+ if ( ! $ver ) {
95
+ ! defined( 'LITESPEED_BYPASS_AUTO_V' ) && define( 'LITESPEED_BYPASS_AUTO_V', true );
96
+ }
97
  return;
98
  }
99
  }
src/control.cls.php CHANGED
@@ -667,12 +667,12 @@ class Control extends Instance
667
  }
668
 
669
  if ( isset( $_SERVER[ 'LSCACHE_VARY_VALUE' ] ) && strpos( $_SERVER[ 'LSCACHE_VARY_VALUE' ], 'ismobile' ) !== false ) {
670
- if ( ! $is_mobile ) {
671
  self::set_nocache( 'is not mobile' );
672
  return;
673
  }
674
  }
675
- elseif ( $is_mobile ) {
676
  self::set_nocache( 'is mobile' );
677
  return;
678
  }
667
  }
668
 
669
  if ( isset( $_SERVER[ 'LSCACHE_VARY_VALUE' ] ) && strpos( $_SERVER[ 'LSCACHE_VARY_VALUE' ], 'ismobile' ) !== false ) {
670
+ if ( ! wp_is_mobile() && ! $is_mobile ) {
671
  self::set_nocache( 'is not mobile' );
672
  return;
673
  }
674
  }
675
+ elseif ( wp_is_mobile() || $is_mobile ) {
676
  self::set_nocache( 'is mobile' );
677
  return;
678
  }
src/core.cls.php CHANGED
@@ -132,7 +132,9 @@ class Core extends Instance
132
  do_action( 'litespeed_init' );
133
 
134
  // in `after_setup_theme`, before `init` hook
135
- Activation::auto_update();
 
 
136
 
137
  if( is_admin() ) {
138
  Admin::get_instance();
@@ -154,6 +156,7 @@ class Core extends Instance
154
  * @since 2.9
155
  */
156
  if ( ! empty( $_GET[ Router::ACTION ] ) && $_GET[ Router::ACTION ] == 'before_optm' ) {
 
157
  ! defined( 'LITESPEED_BYPASS_OPTM' ) && define( 'LITESPEED_BYPASS_OPTM', true );
158
  }
159
 
@@ -187,7 +190,7 @@ class Core extends Instance
187
  */
188
  public function after_user_init()
189
  {
190
- Router::get_instance()->is_crawler_role_simulation();
191
 
192
  if ( ! is_admin() && $result = $this->__cfg->in_optm_exc_roles() ) {
193
  Debug2::debug( '[Core] ⛑️ bypass_optm: hit Role Excludes setting: ' . $result );
@@ -385,8 +388,6 @@ class Core extends Instance
385
  // Hook to modify buffer before
386
  $buffer = apply_filters('litespeed_buffer_before', $buffer);
387
 
388
- // Replace ESI preserved list
389
- $buffer = ESI::finalize( $buffer );
390
 
391
  if ( ! defined( 'LITESPEED_BYPASS_OPTM' ) ) {
392
  // Image lazy load check
@@ -406,6 +407,12 @@ class Core extends Instance
406
  $buffer = CDN::finalize( $buffer );
407
  }
408
 
 
 
 
 
 
 
409
  $this->send_headers( true );
410
 
411
  if ( $this->footer_comment ) {
132
  do_action( 'litespeed_init' );
133
 
134
  // in `after_setup_theme`, before `init` hook
135
+ if ( ! defined( 'LITESPEED_BYPASS_AUTO_V' ) ) {
136
+ Activation::auto_update();
137
+ }
138
 
139
  if( is_admin() ) {
140
  Admin::get_instance();
156
  * @since 2.9
157
  */
158
  if ( ! empty( $_GET[ Router::ACTION ] ) && $_GET[ Router::ACTION ] == 'before_optm' ) {
159
+ Debug2::debug( '[Core] ⛑️ bypass_optm due to QS CTRL' );
160
  ! defined( 'LITESPEED_BYPASS_OPTM' ) && define( 'LITESPEED_BYPASS_OPTM', true );
161
  }
162
 
190
  */
191
  public function after_user_init()
192
  {
193
+ Router::get_instance()->is_role_simulation();
194
 
195
  if ( ! is_admin() && $result = $this->__cfg->in_optm_exc_roles() ) {
196
  Debug2::debug( '[Core] ⛑️ bypass_optm: hit Role Excludes setting: ' . $result );
388
  // Hook to modify buffer before
389
  $buffer = apply_filters('litespeed_buffer_before', $buffer);
390
 
 
 
391
 
392
  if ( ! defined( 'LITESPEED_BYPASS_OPTM' ) ) {
393
  // Image lazy load check
407
  $buffer = CDN::finalize( $buffer );
408
  }
409
 
410
+ /**
411
+ * Replace ESI preserved list
412
+ * @since 3.3 Replace this in the end to avoid `Inline JS Defer` or other Page Optm features encoded ESI tags wrongly, which caused LSWS can't recognize ESI
413
+ */
414
+ $buffer = ESI::finalize( $buffer );
415
+
416
  $this->send_headers( true );
417
 
418
  if ( $this->footer_comment ) {
src/crawler.cls.php CHANGED
@@ -20,7 +20,6 @@ class Crawler extends Base
20
  const USER_AGENT = 'lscache_walker';
21
  const FAST_USER_AGENT = 'lscache_runner';
22
  const CHUNKS = 10000;
23
- const ITEM_HASH = 'hash';
24
 
25
  protected static $_instance;
26
 
@@ -684,9 +683,7 @@ class Crawler extends Base
684
  * Append hash to cookie for validation
685
  * @since 1.9.1
686
  */
687
- $hash = Str::rrand( 6 );
688
- self::update_option( Crawler::ITEM_HASH, $hash );
689
- $this->_crawler_conf[ 'cookies' ][ 'litespeed_hash' ] = $hash;
690
 
691
  $cookies = array();
692
  foreach ( $this->_crawler_conf[ 'cookies' ] as $k => $v ) {
20
  const USER_AGENT = 'lscache_walker';
21
  const FAST_USER_AGENT = 'lscache_runner';
22
  const CHUNKS = 10000;
 
23
 
24
  protected static $_instance;
25
 
683
  * Append hash to cookie for validation
684
  * @since 1.9.1
685
  */
686
+ $this->_crawler_conf[ 'cookies' ][ 'litespeed_hash' ] = Router::get_hash();
 
 
687
 
688
  $cookies = array();
689
  foreach ( $this->_crawler_conf[ 'cookies' ] as $k => $v ) {
src/css.cls.php CHANGED
@@ -3,19 +3,14 @@
3
  * The optimize css class.
4
  *
5
  * @since 2.3
6
- * @package LiteSpeed
7
- * @subpackage LiteSpeed/inc
8
- * @author LiteSpeed Technologies <info@litespeedtech.com>
9
  */
10
- namespace LiteSpeed ;
 
11
 
12
- defined( 'WPINC' ) || exit ;
 
13
 
14
- class CSS extends Base
15
- {
16
- protected static $_instance ;
17
-
18
- const TYPE_GENERATE_CRITICAL = 'generate_critical' ;
19
 
20
  protected $_summary;
21
 
@@ -41,12 +36,12 @@ class CSS extends Base
41
  {
42
  // Get critical css for current page
43
  // Note: need to consider mobile
44
- $rules = self::get_instance()->_ccss() ;
45
 
46
  // Append default critical css
47
- $rules .= Conf::val( Base::O_OPTM_CCSS_CON ) ;
48
 
49
- $html_head = '<style id="litespeed-optm-css-rules">' . $rules . '</style>' . $html_head ;
50
 
51
  return $html_head ;
52
  }
@@ -93,6 +88,12 @@ class CSS extends Base
93
  Debug2::debug2( '[CSS] Cleared ccss queue' ) ;
94
  }
95
 
 
 
 
 
 
 
96
  /**
97
  * The critical css content of the current page
98
  *
@@ -153,7 +154,7 @@ class CSS extends Base
153
  */
154
  private function _separate_mobile_ccss()
155
  {
156
- return apply_filters( 'litespeed_is_mobile', false ) && Conf::val( Base::O_CACHE_MOBILE ) ;
157
  }
158
 
159
  /**
@@ -251,6 +252,105 @@ class CSS extends Base
251
  return $ccss ;
252
  }
253
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
254
  /**
255
  * Pop up the current request and save
256
  *
3
  * The optimize css class.
4
  *
5
  * @since 2.3
 
 
 
6
  */
7
+ namespace LiteSpeed;
8
+ defined( 'WPINC' ) || exit;
9
 
10
+ class CSS extends Base {
11
+ protected static $_instance;
12
 
13
+ const TYPE_GENERATE_CRITICAL = 'generate_critical';
 
 
 
 
14
 
15
  protected $_summary;
16
 
36
  {
37
  // Get critical css for current page
38
  // Note: need to consider mobile
39
+ $rules = self::get_instance()->_ccss();
40
 
41
  // Append default critical css
42
+ $rules .= Conf::val( Base::O_OPTM_CCSS_CON );
43
 
44
+ $html_head = '<style id="litespeed-optm-css-rules">' . $rules . '</style>' . $html_head;
45
 
46
  return $html_head ;
47
  }
88
  Debug2::debug2( '[CSS] Cleared ccss queue' ) ;
89
  }
90
 
91
+
92
+ public function gen_ucss( $page_url, $ua ) {
93
+ return $this->_generate_ucss( $page_url, $ua );
94
+ }
95
+
96
+
97
  /**
98
  * The critical css content of the current page
99
  *
154
  */
155
  private function _separate_mobile_ccss()
156
  {
157
+ return ( wp_is_mobile() || apply_filters( 'litespeed_is_mobile', false ) ) && Conf::val( Base::O_CACHE_MOBILE ) ;
158
  }
159
 
160
  /**
252
  return $ccss ;
253
  }
254
 
255
+ /**
256
+ * Send to QC API to generate UCSS
257
+ *
258
+ * @since 3.3
259
+ * @access private
260
+ */
261
+ private function _generate_ucss( $request_url, $user_agent ) {
262
+ // Check if has credit to push
263
+ $allowance = Cloud::get_instance()->allowance( Cloud::SVC_CCSS );
264
+ if ( ! $allowance ) {
265
+ Debug2::debug( '[UCSS] ❌ No credit' );
266
+ Admin_Display::error( Error::msg( 'lack_of_quota' ) );
267
+ return;
268
+ }
269
+
270
+ // Update UCSS request status
271
+ $this->_summary[ 'curr_request_ucss' ] = time();
272
+ self::save_summary();
273
+
274
+ // Generate UCSS
275
+ $data = array(
276
+ 'type' => 'ucss',
277
+ 'url' => $request_url,
278
+ 'whitelist' => $this->_filter_whitelist(),
279
+ 'user_agent' => $user_agent,
280
+ 'is_mobile' => $this->_separate_mobile_ccss(),
281
+ );
282
+
283
+ // Append cookie for roles auth
284
+ if ( $uid = get_current_user_id() ) {
285
+ // Get role simulation vary name
286
+ $vary_inst = Vary::get_instance();
287
+ $vary_name = $vary_inst->get_vary_name();
288
+ $vary_val = $vary_inst->finalize_default_vary( $uid );
289
+ $data[ 'cookies' ] = array();
290
+ $data[ 'cookies' ][ $vary_name ] = $vary_val;
291
+ $data[ 'cookies' ][ 'litespeed_role' ] = $uid;
292
+ $data[ 'cookies' ][ 'litespeed_hash' ] = Router::get_hash();
293
+ }
294
+
295
+ Debug2::debug( '[UCSS] Generating UCSS: ', $data );
296
+
297
+ $json = Cloud::post( Cloud::SVC_CCSS, $data, 180 ) ;
298
+ if ( ! is_array( $json ) ) {
299
+ return false;
300
+ }
301
+
302
+ if ( empty( $json[ 'ucss' ] ) ) {
303
+ Debug2::debug( '[UCSS] ❌ empty ucss' );
304
+ // $this->_popup_and_save( $ccss_type, $request_url );
305
+ return false;
306
+ }
307
+
308
+ $ucss = $json[ 'ucss' ];
309
+ Debug2::debug2( '[UCSS] ucss con: ' . $ucss );
310
+
311
+ if ( substr( $ucss, 0, 2 ) == '/*' && substr( $ucss, -2 ) == '*/' ) {
312
+ $ucss = '';
313
+ }
314
+ // Add filters
315
+ $ucss = apply_filters( 'litespeed_ucss', $ucss, $request_url );
316
+
317
+ // Write to file
318
+ // File::save( $ucss_file, $ucss, true );
319
+
320
+ // Save summary data
321
+ $this->_summary[ 'last_spent_ucss' ] = time() - $this->_summary[ 'curr_request_ucss' ];
322
+ $this->_summary[ 'last_request_ucss' ] = $this->_summary[ 'curr_request_ucss' ];
323
+ $this->_summary[ 'curr_request_ucss' ] = 0;
324
+ self::save_summary();
325
+ // $this->_popup_and_save( $ccss_type, $request_url );
326
+
327
+ // Debug2::debug( '[UCSS] saved ucss ' . $ucss_file );
328
+
329
+ return $ucss;
330
+ }
331
+
332
+ /**
333
+ * Filter the comment content, add quotes to selector from whitelist. Return the json
334
+ *
335
+ * @since 3.3
336
+ */
337
+ private function _filter_whitelist() {
338
+ $whitelist = array();
339
+ $val = Conf::val( Base::O_OPTM_UCSS_WHITELIST );
340
+ foreach ( $val as $k => $v ) {
341
+ if ( substr( $v, 0, 2 ) === '//' ) {
342
+ continue;
343
+ }
344
+ // Wrap in quotes for selectors
345
+ if ( substr( $v, 0, 1 ) !== '/' && strpos( $v, '"' ) === false && strpos( $v, "'" ) === false ) {
346
+ // $v = "'$v'";
347
+ }
348
+ $whitelist[] = $v;
349
+ }
350
+
351
+ return $whitelist;
352
+ }
353
+
354
  /**
355
  * Pop up the current request and save
356
  *
src/esi.cls.php CHANGED
@@ -890,22 +890,39 @@ class ESI extends Instance {
890
  * @since 2.6
891
  * @access public
892
  */
893
- public static function finalize( $buffer )
894
- {
895
- $instance = self::get_instance() ;
896
 
897
  // Bypass if no preserved list to be replaced
898
  if ( ! $instance->_esi_preserve_list ) {
899
- return $buffer ;
900
  }
901
 
902
- $keys = array_keys( $instance->_esi_preserve_list ) ;
 
 
903
 
904
- Debug2::debug( '[ESI] replacing preserved blocks', $keys ) ;
905
 
906
- $buffer = str_replace( $keys , $instance->_esi_preserve_list, $buffer ) ;
 
907
 
908
- return $buffer ;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
909
  }
910
 
911
  }
890
  * @since 2.6
891
  * @access public
892
  */
893
+ public static function finalize( $buffer ) {
894
+ $instance = self::get_instance();
 
895
 
896
  // Bypass if no preserved list to be replaced
897
  if ( ! $instance->_esi_preserve_list ) {
898
+ return $buffer;
899
  }
900
 
901
+ $keys = array_keys( $instance->_esi_preserve_list );
902
+
903
+ Debug2::debug( '[ESI] replacing preserved blocks', $keys );
904
 
905
+ $buffer = str_replace( $keys, $instance->_esi_preserve_list, $buffer );
906
 
907
+ return $buffer;
908
+ }
909
 
910
+ /**
911
+ * Check if the content contains preserved list or not
912
+ *
913
+ * @since 3.3
914
+ */
915
+ public function contain_preserve_esi( $content ) {
916
+ $hit_list = array();
917
+ foreach ( $this->_esi_preserve_list as $k => $v ) {
918
+ if ( strpos( $content, '"' . $k . '"' ) !== false ) {
919
+ $hit_list[] = '"' . $k . '"';
920
+ }
921
+ if ( strpos( $content, "'" . $k . "'" ) !== false ) {
922
+ $hit_list[] = "'" . $k . "'";
923
+ }
924
+ }
925
+ return $hit_list;
926
  }
927
 
928
  }
src/gui.cls.php CHANGED
@@ -293,86 +293,71 @@ class GUI extends Base
293
  * @since 2.1
294
  * @access public
295
  */
296
- public function show_promo( $check_only = false )
297
- {
298
- $is_litespeed_page = $this->_is_litespeed_page() ;
299
 
300
  // Bypass showing info banner if disabled all in debug
301
  if ( defined( 'LITESPEED_DISABLE_ALL' ) ) {
302
  if ( $is_litespeed_page && ! $check_only ) {
303
- include_once LSCWP_DIR . "tpl/inc/disabled_all.php" ;
304
  }
305
 
306
- return false ;
307
  }
308
 
309
  if ( file_exists( ABSPATH . '.litespeed_no_banner' ) ) {
310
- defined( 'LSCWP_LOG' ) && Debug2::debug( '[GUI] Bypass banners due to silence file' ) ;
311
- return false ;
312
  }
313
 
314
  foreach ( $this->_promo_list as $promo_tag => $v ) {
315
- list( $delay_days, $litespeed_page_only ) = $v ;
316
 
317
  if ( $litespeed_page_only && ! $is_litespeed_page ) {
318
- continue ;
319
  }
320
 
321
  // first time check
322
  if ( empty( $this->_summary[ $promo_tag ] ) ) {
323
- $this->_summary[ $promo_tag ] = time() + 86400 * $delay_days ;
324
- self::save_summary() ;
325
 
326
- continue ;
327
  }
328
 
329
- $promo_timestamp = $this->_summary[ $promo_tag ] ;
330
 
331
  // was ticked as done
332
  if ( $promo_timestamp == 'done' ) {
333
- continue ;
334
  }
335
 
336
  // Not reach the dateline yet
337
  if ( time() < $promo_timestamp ) {
338
- continue ;
339
  }
340
 
341
  // try to load, if can pass, will set $this->_promo_true = true
342
- $this->_promo_true = false ;
343
- include LSCWP_DIR . "tpl/banner/$promo_tag.php" ;
344
 
345
  // If not defined, means it didn't pass the display workflow in tpl.
346
  if ( ! $this->_promo_true ) {
347
- continue ;
348
  }
349
 
350
  if ( $check_only ) {
351
- return $promo_tag ;
352
  }
353
 
354
- defined( 'LSCWP_LOG' ) && Debug2::debug( '[GUI] Show promo ' . $promo_tag ) ;
355
 
356
  // Only contain one
357
- break ;
358
 
359
  }
360
 
361
- return false ;
362
- }
363
-
364
- /**
365
- * Enqueue ajax call for score updating
366
- *
367
- * @since 2.9
368
- * @access private
369
- */
370
- private function _enqueue_score_req_ajax()
371
- {
372
- $this->_summary[ 'score.last_check' ] = time() ;
373
- self::save_summary() ;
374
-
375
- include_once LSCWP_DIR . "tpl/banner/ajax.php" ;
376
  }
377
 
378
  /**
293
  * @since 2.1
294
  * @access public
295
  */
296
+ public function show_promo( $check_only = false ) {
297
+ $is_litespeed_page = $this->_is_litespeed_page();
 
298
 
299
  // Bypass showing info banner if disabled all in debug
300
  if ( defined( 'LITESPEED_DISABLE_ALL' ) ) {
301
  if ( $is_litespeed_page && ! $check_only ) {
302
+ include_once LSCWP_DIR . "tpl/inc/disabled_all.php";
303
  }
304
 
305
+ return false;
306
  }
307
 
308
  if ( file_exists( ABSPATH . '.litespeed_no_banner' ) ) {
309
+ defined( 'LSCWP_LOG' ) && Debug2::debug( '[GUI] Bypass banners due to silence file' );
310
+ return false;
311
  }
312
 
313
  foreach ( $this->_promo_list as $promo_tag => $v ) {
314
+ list( $delay_days, $litespeed_page_only ) = $v;
315
 
316
  if ( $litespeed_page_only && ! $is_litespeed_page ) {
317
+ continue;
318
  }
319
 
320
  // first time check
321
  if ( empty( $this->_summary[ $promo_tag ] ) ) {
322
+ $this->_summary[ $promo_tag ] = time() + 86400 * $delay_days;
323
+ self::save_summary();
324
 
325
+ continue;
326
  }
327
 
328
+ $promo_timestamp = $this->_summary[ $promo_tag ];
329
 
330
  // was ticked as done
331
  if ( $promo_timestamp == 'done' ) {
332
+ continue;
333
  }
334
 
335
  // Not reach the dateline yet
336
  if ( time() < $promo_timestamp ) {
337
+ continue;
338
  }
339
 
340
  // try to load, if can pass, will set $this->_promo_true = true
341
+ $this->_promo_true = false;
342
+ include LSCWP_DIR . "tpl/banner/$promo_tag.php";
343
 
344
  // If not defined, means it didn't pass the display workflow in tpl.
345
  if ( ! $this->_promo_true ) {
346
+ continue;
347
  }
348
 
349
  if ( $check_only ) {
350
+ return $promo_tag;
351
  }
352
 
353
+ defined( 'LSCWP_LOG' ) && Debug2::debug( '[GUI] Show promo ' . $promo_tag );
354
 
355
  // Only contain one
356
+ break;
357
 
358
  }
359
 
360
+ return false;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
361
  }
362
 
363
  /**
src/lang.cls.php CHANGED
@@ -103,7 +103,10 @@ class Lang extends Base
103
  self::O_CACHE_EXC_ROLES => __( 'Do Not Cache Roles', 'litespeed-cache' ),
104
  self::O_OPTM_CSS_MIN => __( 'CSS Minify', 'litespeed-cache' ),
105
  self::O_OPTM_CSS_COMB => __( 'CSS Combine', 'litespeed-cache' ),
106
- self::O_OPTM_CSS_UNIQUE => __( 'Unique CSS', 'litespeed-cache' ),
 
 
 
107
  self::O_OPTM_CSS_HTTP2 => __( 'CSS HTTP/2 Push', 'litespeed-cache' ),
108
  self::O_OPTM_JS_MIN => __( 'JS Minify', 'litespeed-cache' ),
109
  self::O_OPTM_JS_COMB => __( 'JS Combine', 'litespeed-cache' ),
@@ -174,7 +177,7 @@ class Lang extends Base
174
  self::O_ESI => __( 'Enable ESI', 'litespeed-cache' ),
175
  self::O_ESI_CACHE_ADMBAR => __( 'Cache Admin Bar', 'litespeed-cache' ),
176
  self::O_ESI_CACHE_COMMFORM => __( 'Cache Comment Form', 'litespeed-cache' ),
177
- self::O_ESI_NONCE => __( 'ESI Nonce', 'litespeed-cache' ),
178
  self::O_CACHE_VARY_GROUP => __( 'Vary Group', 'litespeed-cache' ),
179
  self::O_PURGE_HOOK_ALL => __( 'Purge All Hooks', 'litespeed-cache' ),
180
  self::O_UTIL_NO_HTTPS_VARY => __( 'Improve HTTP/HTTPS Compatibility', 'litespeed-cache' ),
103
  self::O_CACHE_EXC_ROLES => __( 'Do Not Cache Roles', 'litespeed-cache' ),
104
  self::O_OPTM_CSS_MIN => __( 'CSS Minify', 'litespeed-cache' ),
105
  self::O_OPTM_CSS_COMB => __( 'CSS Combine', 'litespeed-cache' ),
106
+ self::O_OPTM_CSS_UNIQUE => __( 'Unique CSS File', 'litespeed-cache' ),
107
+ self::O_OPTM_UCSS => __( 'Generate UCSS', 'litespeed-cache' ),
108
+ self::O_OPTM_UCSS_ASYNC => __( 'Generate UCSS in Background', 'litespeed-cache' ),
109
+ self::O_OPTM_UCSS_WHITELIST => __( 'UCSS Whitelist Selector', 'litespeed-cache' ),
110
  self::O_OPTM_CSS_HTTP2 => __( 'CSS HTTP/2 Push', 'litespeed-cache' ),
111
  self::O_OPTM_JS_MIN => __( 'JS Minify', 'litespeed-cache' ),
112
  self::O_OPTM_JS_COMB => __( 'JS Combine', 'litespeed-cache' ),
177
  self::O_ESI => __( 'Enable ESI', 'litespeed-cache' ),
178
  self::O_ESI_CACHE_ADMBAR => __( 'Cache Admin Bar', 'litespeed-cache' ),
179
  self::O_ESI_CACHE_COMMFORM => __( 'Cache Comment Form', 'litespeed-cache' ),
180
+ self::O_ESI_NONCE => __( 'ESI Nonces', 'litespeed-cache' ),
181
  self::O_CACHE_VARY_GROUP => __( 'Vary Group', 'litespeed-cache' ),
182
  self::O_PURGE_HOOK_ALL => __( 'Purge All Hooks', 'litespeed-cache' ),
183
  self::O_UTIL_NO_HTTPS_VARY => __( 'Improve HTTP/HTTPS Compatibility', 'litespeed-cache' ),
src/optimize.cls.php CHANGED
@@ -47,6 +47,8 @@ class Optimize extends Base
47
  private $html_foot = '' ; // The html info append to <body>
48
  private $html_head = '' ; // The html info prepend to <body>
49
 
 
 
50
  /**
51
  *
52
  * @since 1.2.2
@@ -580,38 +582,38 @@ class Optimize extends Base
580
  */
581
  $this->_font_optm() ;
582
 
 
 
 
 
 
 
 
583
  // Replace html head part
584
- $this->html_head = apply_filters( 'litespeed_optm_html_head', $this->html_head ) ;
585
  if ( $this->html_head ) {
586
  // Put header content to be after charset
587
  if ( strpos( $this->content, '<meta charset' ) !== false ) {
588
- $this->content = preg_replace( '#<meta charset([^>]*)>#isU', '<meta charset$1>' . $this->html_head , $this->content, 1 ) ;
589
  }
590
  else {
591
- $this->content = preg_replace( '#<head([^>]*)>#isU', '<head$1>' . $this->html_head , $this->content, 1 ) ;
592
  }
593
  }
594
 
595
  // Replace html foot part
596
- $this->html_foot = apply_filters( 'litespeed_optm_html_foot', $this->html_foot ) ;
597
  if ( $this->html_foot ) {
598
- $this->content = str_replace( '</body>', $this->html_foot . '</body>' , $this->content ) ;
599
  }
600
 
601
  // HTML minify
602
  if ( Conf::val( Base::O_OPTM_HTML_MIN ) ) {
603
- $this->content = Optimizer::get_instance()->html_min( $this->content ) ;
604
  }
605
 
606
- /**
607
- * Inline script manipulated until document is ready
608
- *
609
- * @since 3.0
610
- */
611
- $this->_js_inline_defer() ;
612
-
613
  if ( $this->http2_headers ) {
614
- @header( 'Link: ' . implode( ',', $this->http2_headers ), false ) ;
615
  }
616
 
617
  }
@@ -622,69 +624,82 @@ class Optimize extends Base
622
  * @since 3.0
623
  * @access private
624
  */
625
- private function _js_inline_defer()
626
- {
627
  $optm_js_inline = Conf::val( Base::O_OPTM_JS_INLINE_DEFER );
628
  if ( ! $optm_js_inline ) {
629
- return ;
630
  }
631
 
632
  Debug2::debug( '[Optm] Inline JS defer ' . $optm_js_inline );
633
 
634
- preg_match_all( '#<script([^>]*)>(.*)</script>#isU', $this->content, $matches, PREG_SET_ORDER ) ;
635
 
636
- $script_ori = array() ;
637
- $script_deferred = array() ;
638
 
 
639
  foreach ( $matches as $match ) {
640
 
641
  if ( ! empty( $match[ 1 ] ) ) {
642
- $attrs = Utility::parse_attr( $match[ 1 ] ) ;
643
 
644
  if ( ! empty( $attrs[ 'src' ] ) ) {
645
- continue ;
646
  }
647
 
648
  if ( ! empty( $attrs[ 'data-no-optimize' ] ) ) {
649
- continue ;
650
  }
651
 
652
  if ( ! empty( $attrs[ 'type' ] ) && $attrs[ 'type' ] != 'text/javascript' ) {
653
- continue ;
654
  }
655
  }
656
 
657
- $con = trim( $match[ 2 ] ) ;
658
  if ( ! $con ) {
659
- continue ;
660
  }
661
 
662
  if ( $optm_js_inline === 2 ) {
663
- $script_ori[] = $match[ 0 ] ;
664
- $script_deferred[] = '<script src="data:text/javascript;base64, ' . base64_encode( $con ) . '" defer ' . $match[ 1 ] . '></script>' ;
 
 
 
 
 
 
 
 
665
  }
666
  else {
667
  // Prevent var scope issue
668
  if ( strpos( $con, 'var ' ) !== false && strpos( $con, '{' ) === false ) {
669
- continue ;
670
  }
671
 
672
  if ( strpos( $con, 'var ' ) !== false && strpos( $con, '{' ) !== false && strpos( $con, '{' ) > strpos( $con, 'var ' ) ) {
673
- continue ;
674
  }
675
 
676
- // $con = str_replace( 'var ', 'window.', $con ) ;
677
 
678
- $script_ori[] = $match[ 0 ] ;
679
 
680
- $deferred = 'document.addEventListener("DOMContentLoaded",function(){' . $con . '});' ;
681
 
682
- $script_deferred[] = '<script' . $match[ 1 ] . '>' . $deferred . '</script>' ;
683
  }
684
 
685
  }
686
 
687
- $this->content = str_replace( $script_ori, $script_deferred, $this->content ) ;
 
 
 
 
 
688
 
689
  }
690
 
@@ -739,7 +754,7 @@ class Optimize extends Base
739
  $html .= '"' . implode( '","', $families ) . ( $this->_conf_css_font_display ? '&display=' . $this->_conf_css_font_display : '' ) . '"';
740
 
741
  $html .= ']}};';
742
-
743
  // if webfontloader lib was loaded before WebFontConfig variable, call WebFont.load
744
  $html .= 'if ( typeof WebFont === "object" && typeof WebFont.load === "function" ) { WebFont.load( WebFontConfig ); }';
745
 
@@ -1013,10 +1028,8 @@ class Optimize extends Base
1013
  return false;
1014
  }
1015
 
1016
- // For those env who don't support SCRIPT_URI, need to keep $url_sensitive OFF.
1017
- if ( empty( $_SERVER[ 'SCRIPT_URI' ] ) ) {
1018
- $url_sensitive = false;
1019
- }
1020
 
1021
  if ( ! is_array( $src ) ) {
1022
  $src = array( $src );
@@ -1040,7 +1053,7 @@ class Optimize extends Base
1040
  $existed = false;
1041
  if ( $optm_data = Data::get_instance()->optm_hash2src( $filename ) ) {
1042
  // If conflicts
1043
- if ( $optm_data[ 'src' ] === $src && ( ! $url_sensitive || $optm_data[ 'refer' ] === $_SERVER[ 'SCRIPT_URI' ] ) ) {
1044
  $existed = true;
1045
  }
1046
  else {
@@ -1059,7 +1072,7 @@ class Optimize extends Base
1059
  if ( ! file_exists( $static_file ) || time() - filemtime( $static_file ) > $this->cfg_ttl ) {
1060
  $concat_only = ! ( $file_type === 'css' ? $this->cfg_css_min : $this->cfg_js_min );
1061
 
1062
- $content = Optimizer::get_instance()->serve( $filename, $concat_only, $src, ! empty( $_SERVER[ 'SCRIPT_URI' ] ) ? $_SERVER[ 'SCRIPT_URI' ] : false );
1063
 
1064
  // Generate static file
1065
  File::save( $static_file, $content, true );
47
  private $html_foot = '' ; // The html info append to <body>
48
  private $html_head = '' ; // The html info prepend to <body>
49
 
50
+ private static $_var_i = 0;
51
+
52
  /**
53
  *
54
  * @since 1.2.2
582
  */
583
  $this->_font_optm() ;
584
 
585
+ /**
586
+ * Inline script manipulated until document is ready
587
+ *
588
+ * @since 3.0
589
+ */
590
+ $this->_js_inline_defer();
591
+
592
  // Replace html head part
593
+ $this->html_head = apply_filters( 'litespeed_optm_html_head', $this->html_head );
594
  if ( $this->html_head ) {
595
  // Put header content to be after charset
596
  if ( strpos( $this->content, '<meta charset' ) !== false ) {
597
+ $this->content = preg_replace( '#<meta charset([^>]*)>#isU', '<meta charset$1>' . $this->html_head , $this->content, 1 );
598
  }
599
  else {
600
+ $this->content = preg_replace( '#<head([^>]*)>#isU', '<head$1>' . $this->html_head , $this->content, 1 );
601
  }
602
  }
603
 
604
  // Replace html foot part
605
+ $this->html_foot = apply_filters( 'litespeed_optm_html_foot', $this->html_foot );
606
  if ( $this->html_foot ) {
607
+ $this->content = str_replace( '</body>', $this->html_foot . '</body>' , $this->content );
608
  }
609
 
610
  // HTML minify
611
  if ( Conf::val( Base::O_OPTM_HTML_MIN ) ) {
612
+ $this->content = Optimizer::get_instance()->html_min( $this->content );
613
  }
614
 
 
 
 
 
 
 
 
615
  if ( $this->http2_headers ) {
616
+ @header( 'Link: ' . implode( ',', $this->http2_headers ), false );
617
  }
618
 
619
  }
624
  * @since 3.0
625
  * @access private
626
  */
627
+ private function _js_inline_defer() {
 
628
  $optm_js_inline = Conf::val( Base::O_OPTM_JS_INLINE_DEFER );
629
  if ( ! $optm_js_inline ) {
630
+ return;
631
  }
632
 
633
  Debug2::debug( '[Optm] Inline JS defer ' . $optm_js_inline );
634
 
635
+ preg_match_all( '#<script([^>]*)>(.*)</script>#isU', $this->content, $matches, PREG_SET_ORDER );
636
 
637
+ $script_ori = array();
638
+ $script_deferred = array();
639
 
640
+ $js_var_preserve = array();
641
  foreach ( $matches as $match ) {
642
 
643
  if ( ! empty( $match[ 1 ] ) ) {
644
+ $attrs = Utility::parse_attr( $match[ 1 ] );
645
 
646
  if ( ! empty( $attrs[ 'src' ] ) ) {
647
+ continue;
648
  }
649
 
650
  if ( ! empty( $attrs[ 'data-no-optimize' ] ) ) {
651
+ continue;
652
  }
653
 
654
  if ( ! empty( $attrs[ 'type' ] ) && $attrs[ 'type' ] != 'text/javascript' ) {
655
+ continue;
656
  }
657
  }
658
 
659
+ $con = trim( $match[ 2 ] );
660
  if ( ! $con ) {
661
+ continue;
662
  }
663
 
664
  if ( $optm_js_inline === 2 ) {
665
+ $script_ori[] = $match[ 0 ];
666
+ // Check if the content contains ESI nonce or not
667
+ if ( $esi_placeholder_list = ESI::get_instance()->contain_preserve_esi( $con ) ) {
668
+ foreach ( $esi_placeholder_list as $esi_placeholder ) {
669
+ $js_var = '__litespeed_var_' . ( self::$_var_i ++ ) . '__';
670
+ $con = str_replace( $esi_placeholder, $js_var, $con );
671
+ $js_var_preserve[] = $js_var . '=' . $esi_placeholder;
672
+ }
673
+ }
674
+ $script_deferred[] = '<script src="data:text/javascript;base64, ' . base64_encode( $con ) . '" defer ' . $match[ 1 ] . '></script>';
675
  }
676
  else {
677
  // Prevent var scope issue
678
  if ( strpos( $con, 'var ' ) !== false && strpos( $con, '{' ) === false ) {
679
+ continue;
680
  }
681
 
682
  if ( strpos( $con, 'var ' ) !== false && strpos( $con, '{' ) !== false && strpos( $con, '{' ) > strpos( $con, 'var ' ) ) {
683
+ continue;
684
  }
685
 
686
+ // $con = str_replace( 'var ', 'window.', $con );
687
 
688
+ $script_ori[] = $match[ 0 ];
689
 
690
+ $deferred = 'document.addEventListener("DOMContentLoaded",function(){' . $con . '});';
691
 
692
+ $script_deferred[] = '<script' . $match[ 1 ] . '>' . $deferred . '</script>';
693
  }
694
 
695
  }
696
 
697
+ if ( $js_var_preserve ) {
698
+ $this->html_head .= '<script>var ' . implode( ',', $js_var_preserve ) . ';</script>';
699
+ Debug2::debug2( '[Optm] Inline JS defer vars', $js_var_preserve );
700
+ }
701
+
702
+ $this->content = str_replace( $script_ori, $script_deferred, $this->content );
703
 
704
  }
705
 
754
  $html .= '"' . implode( '","', $families ) . ( $this->_conf_css_font_display ? '&display=' . $this->_conf_css_font_display : '' ) . '"';
755
 
756
  $html .= ']}};';
757
+
758
  // if webfontloader lib was loaded before WebFontConfig variable, call WebFont.load
759
  $html .= 'if ( typeof WebFont === "object" && typeof WebFont.load === "function" ) { WebFont.load( WebFontConfig ); }';
760
 
1028
  return false;
1029
  }
1030
 
1031
+ global $wp;
1032
+ $request_url = home_url( $wp->request );
 
 
1033
 
1034
  if ( ! is_array( $src ) ) {
1035
  $src = array( $src );
1053
  $existed = false;
1054
  if ( $optm_data = Data::get_instance()->optm_hash2src( $filename ) ) {
1055
  // If conflicts
1056
+ if ( $optm_data[ 'src' ] === $src && ( ! $url_sensitive || $optm_data[ 'refer' ] === $request_url ) ) {
1057
  $existed = true;
1058
  }
1059
  else {
1072
  if ( ! file_exists( $static_file ) || time() - filemtime( $static_file ) > $this->cfg_ttl ) {
1073
  $concat_only = ! ( $file_type === 'css' ? $this->cfg_css_min : $this->cfg_js_min );
1074
 
1075
+ $content = Optimizer::get_instance()->serve( $filename, $concat_only, $src, $request_url );
1076
 
1077
  // Generate static file
1078
  File::save( $static_file, $content, true );
src/optimizer.cls.php CHANGED
@@ -74,6 +74,8 @@ class Optimizer extends Instance
74
  * @access public
75
  */
76
  public function serve( $filename, $concat_only, $src_list = false, $page_url = false ) {
 
 
77
  // Search src set in db based on the requested filename
78
  if ( ! $src_list ) {
79
  $optm_data = Data::get_instance()->optm_hash2src( $filename );
@@ -88,7 +90,13 @@ class Optimizer extends Instance
88
 
89
  // Check if need to run Unique CSS feature
90
  if ( $file_type == 'css' ) {
91
- $content = apply_filters( 'litespeed_css_serve', false, $filename, $src_list, $page_url );
 
 
 
 
 
 
92
  if ( $content ) {
93
  Debug2::debug( '[Optmer] Content from filter `litespeed_css_serve` for [file] ' . $filename . ' [url] ' . $page_url );
94
  return $content;
74
  * @access public
75
  */
76
  public function serve( $filename, $concat_only, $src_list = false, $page_url = false ) {
77
+ $ua = ! empty( $_SERVER[ 'HTTP_USER_AGENT' ] ) ? $_SERVER[ 'HTTP_USER_AGENT' ] : '';
78
+
79
  // Search src set in db based on the requested filename
80
  if ( ! $src_list ) {
81
  $optm_data = Data::get_instance()->optm_hash2src( $filename );
90
 
91
  // Check if need to run Unique CSS feature
92
  if ( $file_type == 'css' ) {
93
+ // CHeck if need to trigger UCSS or not
94
+ $content = false;
95
+ if ( Conf::val( Base::O_OPTM_UCSS ) && ! Conf::val( Base::O_OPTM_UCSS_ASYNC ) ) {
96
+ $content = CSS::get_instance()->gen_ucss( $page_url, $ua );//todo: how to store ua!!!
97
+ }
98
+
99
+ $content = apply_filters( 'litespeed_css_serve', $content, $filename, $src_list, $page_url );
100
  if ( $content ) {
101
  Debug2::debug( '[Optmer] Content from filter `litespeed_css_serve` for [file] ' . $filename . ' [url] ' . $page_url );
102
  return $content;
src/router.cls.php CHANGED
@@ -10,7 +10,7 @@
10
  namespace LiteSpeed;
11
  defined( 'WPINC' ) || exit;
12
 
13
- class Router extends Instance
14
  {
15
  protected static $_instance;
16
 
@@ -39,6 +39,8 @@ class Router extends Instance
39
 
40
  const TYPE = 'litespeed_type';
41
 
 
 
42
  private static $_esi_enabled;
43
  private static $_is_ajax ;
44
  private static $_is_logged_in ;
@@ -180,61 +182,56 @@ class Router extends Instance
180
  }
181
 
182
  /**
183
- * Crawler simulate role
184
  *
185
  * @since 1.9.1
186
- * @access public
187
  */
188
- public function is_crawler_role_simulation()
189
- {
190
  if( is_admin() ) {
191
- return ;
192
  }
193
 
194
  if ( empty( $_COOKIE[ 'litespeed_role' ] ) || empty( $_COOKIE[ 'litespeed_hash' ] ) ) {
195
- return ;
196
  }
197
 
198
- Debug2::debug( '[Router] starting crawler role validation' ) ;
199
 
200
  // Check if is from crawler
201
- if ( empty( $_SERVER[ 'HTTP_USER_AGENT' ] ) || strpos( $_SERVER[ 'HTTP_USER_AGENT' ], Crawler::FAST_USER_AGENT ) !== 0 ) {
202
- Debug2::debug( '[Router] user agent not match' ) ;
203
- return ;
204
- }
205
 
206
  // Hash validation
207
- $hash = Crawler::get_option( Crawler::ITEM_HASH ) ;
208
  if ( ! $hash || $_COOKIE[ 'litespeed_hash' ] != $hash ) {
209
- Debug2::debug( '[Router] crawler hash not match ' . $_COOKIE[ 'litespeed_hash' ] . ' != ' . $hash ) ;
210
- return ;
211
  }
212
 
213
- $role_uid = $_COOKIE[ 'litespeed_role' ] ;
214
- Debug2::debug( '[Router] role simulate litespeed_role uid ' . $role_uid ) ;
215
 
216
- wp_set_current_user( $role_uid ) ;
217
  }
218
 
219
  /**
220
- * Get user id
221
  *
222
- * @since 1.6.2
223
  */
224
- public static function get_uid()
225
- {
226
- if ( defined( 'LITESPEED_WP_UID' ) ) {
227
- return LITESPEED_WP_UID ;
 
228
  }
229
 
230
- $user = wp_get_current_user() ;
231
- $user_id = $user->ID ;
232
-
233
- Debug2::debug( '[Router] get_uid: ' . $user_id, 3 ) ;
234
-
235
- define( 'LITESPEED_WP_UID', $user_id ) ;
236
-
237
- return LITESPEED_WP_UID ;
238
  }
239
 
240
  /**
@@ -242,14 +239,13 @@ class Router extends Instance
242
  *
243
  * @since 1.6.2
244
  */
245
- public static function get_role( $uid = null )
246
- {
247
  if ( defined( 'LITESPEED_WP_ROLE' ) ) {
248
- return LITESPEED_WP_ROLE ;
249
  }
250
 
251
  if ( $uid === null ) {
252
- $uid = self::get_uid() ;
253
  }
254
 
255
  $role = false ;
10
  namespace LiteSpeed;
11
  defined( 'WPINC' ) || exit;
12
 
13
+ class Router extends Base
14
  {
15
  protected static $_instance;
16
 
39
 
40
  const TYPE = 'litespeed_type';
41
 
42
+ const ITEM_HASH = 'hash';
43
+
44
  private static $_esi_enabled;
45
  private static $_is_ajax ;
46
  private static $_is_logged_in ;
182
  }
183
 
184
  /**
185
+ * UCSS/Crawler role simulator
186
  *
187
  * @since 1.9.1
188
+ * @since 3.3 Renamed from `is_crawler_role_simulation`
189
  */
190
+ public function is_role_simulation() {
 
191
  if( is_admin() ) {
192
+ return;
193
  }
194
 
195
  if ( empty( $_COOKIE[ 'litespeed_role' ] ) || empty( $_COOKIE[ 'litespeed_hash' ] ) ) {
196
+ return;
197
  }
198
 
199
+ Debug2::debug( '[Router] starting role validation' );
200
 
201
  // Check if is from crawler
202
+ // if ( empty( $_SERVER[ 'HTTP_USER_AGENT' ] ) || strpos( $_SERVER[ 'HTTP_USER_AGENT' ], Crawler::FAST_USER_AGENT ) !== 0 ) {
203
+ // Debug2::debug( '[Router] user agent not match' );
204
+ // return;
205
+ // }
206
 
207
  // Hash validation
208
+ $hash = self::get_option( self::ITEM_HASH );
209
  if ( ! $hash || $_COOKIE[ 'litespeed_hash' ] != $hash ) {
210
+ Debug2::debug( '[Router] hash not match ' . $_COOKIE[ 'litespeed_hash' ] . ' != ' . $hash );
211
+ return;
212
  }
213
 
214
+ $role_uid = $_COOKIE[ 'litespeed_role' ];
215
+ Debug2::debug( '[Router] role simulate litespeed_role uid ' . $role_uid );
216
 
217
+ wp_set_current_user( $role_uid );
218
  }
219
 
220
  /**
221
+ * Get a security hash
222
  *
223
+ * @since 3.3
224
  */
225
+ public static function get_hash() {
226
+ // Reuse previous hash if existed
227
+ $hash = self::get_option( self::ITEM_HASH );
228
+ if ( $hash ) {
229
+ return $hash;
230
  }
231
 
232
+ $hash = Str::rrand( 6 );
233
+ self::update_option( self::ITEM_HASH, $hash );
234
+ return $hash;
 
 
 
 
 
235
  }
236
 
237
  /**
239
  *
240
  * @since 1.6.2
241
  */
242
+ public static function get_role( $uid = null ) {
 
243
  if ( defined( 'LITESPEED_WP_ROLE' ) ) {
244
+ return LITESPEED_WP_ROLE;
245
  }
246
 
247
  if ( $uid === null ) {
248
+ $uid = get_current_user_id();
249
  }
250
 
251
  $role = false ;
src/vary.cls.php CHANGED
@@ -287,7 +287,7 @@ class Vary extends Instance {
287
  * Update default vary
288
  *
289
  * @since 1.6.2
290
- * @since 1.6.6.1 Add ran check to make it only run once ( No run multiple times due to login process doesn't have valid uid from router::get_uid )
291
  * @access private
292
  */
293
  private function _update_default_vary( $uid = false, $expire = false )
@@ -365,15 +365,14 @@ class Vary extends Instance {
365
  * @since 1.6.2
366
  * @access public
367
  */
368
- public function finalize_default_vary( $uid = false )
369
- {
370
  $vary = self::$_default_vary_val;
371
 
372
  if ( ! $uid ) {
373
- $uid = Router::get_uid() ;
374
  }
375
  else {
376
- Debug2::debug( '[Vary] uid: ' . $uid ) ;
377
  }
378
 
379
  // get user's group id
287
  * Update default vary
288
  *
289
  * @since 1.6.2
290
+ * @since 1.6.6.1 Add ran check to make it only run once ( No run multiple times due to login process doesn't have valid uid )
291
  * @access private
292
  */
293
  private function _update_default_vary( $uid = false, $expire = false )
365
  * @since 1.6.2
366
  * @access public
367
  */
368
+ public function finalize_default_vary( $uid = false ) {
 
369
  $vary = self::$_default_vary_val;
370
 
371
  if ( ! $uid ) {
372
+ $uid = get_current_user_id();
373
  }
374
  else {
375
+ Debug2::debug( '[Vary] uid: ' . $uid );
376
  }
377
 
378
  // get user's group id
tpl/banner/ajax.php CHANGED
@@ -1,4 +1,8 @@
1
  <?php
 
 
 
 
2
  namespace LiteSpeed ;
3
  defined( 'WPINC' ) || exit ;
4
 
1
  <?php
2
+ /**
3
+ * @deprecated 3.3 Will only show banner after user manually checked score
4
+ */
5
+
6
  namespace LiteSpeed ;
7
  defined( 'WPINC' ) || exit ;
8
 
tpl/banner/new_version.php CHANGED
@@ -1,54 +1,54 @@
1
  <?php
2
- namespace LiteSpeed ;
3
- defined( 'WPINC' ) || exit ;
4
 
5
  /**
6
  * NOTE: Only show for single site
7
  */
8
  if ( is_multisite() ) {
9
- return ;
10
  }
11
 
12
  if ( Conf::val( Base::O_AUTO_UPGRADE ) ) {
13
- return ;
14
  }
15
 
16
- $current = get_site_transient( 'update_plugins' ) ;
17
  if ( ! isset( $current->response[ Core::PLUGIN_FILE ] ) ) {
18
- return ;
19
  }
20
 
21
- $last_check = empty( $this->_summary[ 'new_version.last_check' ] ) ? 0 : $this->_summary[ 'new_version.last_check' ] ;
22
  // Check once in a half day
23
  if ( time() - $last_check > 43200 ) {
24
- $this->_summary[ 'new_version.last_check' ] = time() ;
25
- Admin_Display::save_summary( $this->_summary ) ;
26
 
27
  // Detect version
28
  $auto_v = Cloud::version_check( 'new_version_banner' );
29
  if ( ! empty( $auto_v[ 'latest' ] ) ) {
30
  $this->_summary[ 'new_version.v' ] = $auto_v[ 'latest' ];
31
- Admin_Display::save_summary( $this->_summary ) ;
32
  }
33
  // After detect, don't show, just return and show next time
34
- return ;
35
  }
36
 
37
  if ( ! isset( $this->_summary[ 'new_version.v' ] ) ) {
38
- return ;
39
  }
40
 
41
  // Check if current version is newer than auto_v or not
42
  if ( version_compare( Core::VER, $this->_summary[ 'new_version.v' ], '>=' ) ) {
43
- return ;
44
  }
45
 
46
  //********** Can show now **********//
47
 
48
- $this->_promo_true = true ;
49
 
50
  if ( $check_only ) {
51
- return ;
52
  }
53
 
54
  ?>
@@ -56,35 +56,35 @@ if ( $check_only ) {
56
  <div class="litespeed-banner-promo-logo"></div>
57
 
58
  <div class="litespeed-banner-promo-content">
59
- <h3 class="litespeed-banner-title litespeed-top15"><?php echo __( 'LiteSpeed Cache', 'litespeed-cache' ) ; ?>: <?php echo __( 'New Version Available!', 'litespeed-cache' ) ; ?></h3>
60
  <div class="litespeed-banner-description">
61
  <div class="litespeed-banner-description-padding-right-15">
62
  <p class="litespeed-banner-desciption-content">
63
- <?php echo sprintf( __( 'New release %s is available now.', 'litespeed-cache' ), 'v' . $this->_summary[ 'new_version.v' ] ) ; ?>
64
  </p>
65
  </div>
66
  <div class="litespeed-row-flex litespeed-banner-description">
67
  <div class="litespeed-banner-description-padding-right-15">
68
- <?php $url = Utility::build_url( Router::ACTION_ACTIVATION, Activation::TYPE_UPGRADE ) ; ?>
69
- <a href="<?php echo $url ; ?>" class="button litespeed-btn-success litespeed-btn-mini">
70
  <i class="dashicons dashicons-image-rotate">&nbsp;</i>
71
- <?php echo __( 'Upgrade', 'litespeed-cache' ) ; ?>
72
  </a>
73
  </div>
74
  <div class="litespeed-banner-description-padding-right-15">
75
  <?php
76
- $cfg = array( Conf::TYPE_SET . '[' . Base::O_AUTO_UPGRADE . ']' => 1 ) ;
77
- $url = Utility::build_url( Router::ACTION_CONF, Conf::TYPE_SET, false, null, $cfg ) ;
78
  ?>
79
- <a href="<?php echo $url ; ?>" class="button litespeed-btn-primary litespeed-btn-mini">
80
  <i class="dashicons dashicons-update">&nbsp;</i>
81
- <?php echo __( 'Turn On Auto Upgrade', 'litespeed-cache' ) ; ?>
82
  </a>
83
  </div>
84
  <div class="litespeed-banner-description-padding-right-15">
85
- <?php $url = Utility::build_url( Core::ACTION_DISMISS, GUI::TYPE_DISMISS_PROMO, false, null, array( 'promo_tag' => 'new_version' ) ) ; ?>
86
- <a href="<?php echo $url ; ?>" class="button litespeed-btn-warning litespeed-btn-mini">
87
- <?php echo __( 'Maybe Later', 'litespeed-cache' ) ; ?>
88
  </a>
89
  </div>
90
  </div>
@@ -92,8 +92,8 @@ if ( $check_only ) {
92
  </div>
93
 
94
  <div>
95
- <?php $dismiss_url = Utility::build_url( Core::ACTION_DISMISS, GUI::TYPE_DISMISS_PROMO, false, null, array( 'promo_tag' => 'new_version', 'later' => 1 ) ) ; ?>
96
  <span class="screen-reader-text">Dismiss this notice.</span>
97
- <a href="<?php echo $dismiss_url ; ?>" class="litespeed-notice-dismiss">X</a>
98
  </div>
99
  </div>
1
  <?php
2
+ namespace LiteSpeed;
3
+ defined( 'WPINC' ) || exit;
4
 
5
  /**
6
  * NOTE: Only show for single site
7
  */
8
  if ( is_multisite() ) {
9
+ return;
10
  }
11
 
12
  if ( Conf::val( Base::O_AUTO_UPGRADE ) ) {
13
+ return;
14
  }
15
 
16
+ $current = get_site_transient( 'update_plugins' );
17
  if ( ! isset( $current->response[ Core::PLUGIN_FILE ] ) ) {
18
+ return;
19
  }
20
 
21
+ $last_check = empty( $this->_summary[ 'new_version.last_check' ] ) ? 0 : $this->_summary[ 'new_version.last_check' ];
22
  // Check once in a half day
23
  if ( time() - $last_check > 43200 ) {
24
+ $this->_summary[ 'new_version.last_check' ] = time();
25
+ Admin_Display::save_summary( $this->_summary );
26
 
27
  // Detect version
28
  $auto_v = Cloud::version_check( 'new_version_banner' );
29
  if ( ! empty( $auto_v[ 'latest' ] ) ) {
30
  $this->_summary[ 'new_version.v' ] = $auto_v[ 'latest' ];
31
+ Admin_Display::save_summary( $this->_summary );
32
  }
33
  // After detect, don't show, just return and show next time
34
+ return;
35
  }
36
 
37
  if ( ! isset( $this->_summary[ 'new_version.v' ] ) ) {
38
+ return;
39
  }
40
 
41
  // Check if current version is newer than auto_v or not
42
  if ( version_compare( Core::VER, $this->_summary[ 'new_version.v' ], '>=' ) ) {
43
+ return;
44
  }
45
 
46
  //********** Can show now **********//
47
 
48
+ $this->_promo_true = true;
49
 
50
  if ( $check_only ) {
51
+ return;
52
  }
53
 
54
  ?>
56
  <div class="litespeed-banner-promo-logo"></div>
57
 
58
  <div class="litespeed-banner-promo-content">
59
+ <h3 class="litespeed-banner-title litespeed-top15"><?php echo __( 'LiteSpeed Cache', 'litespeed-cache' ); ?>: <?php echo __( 'New Version Available!', 'litespeed-cache' ); ?></h3>
60
  <div class="litespeed-banner-description">
61
  <div class="litespeed-banner-description-padding-right-15">
62
  <p class="litespeed-banner-desciption-content">
63
+ <?php echo sprintf( __( 'New release %s is available now.', 'litespeed-cache' ), 'v' . $this->_summary[ 'new_version.v' ] ); ?>
64
  </p>
65
  </div>
66
  <div class="litespeed-row-flex litespeed-banner-description">
67
  <div class="litespeed-banner-description-padding-right-15">
68
+ <?php $url = Utility::build_url( Router::ACTION_ACTIVATION, Activation::TYPE_UPGRADE ); ?>
69
+ <a href="<?php echo $url; ?>" class="button litespeed-btn-success litespeed-btn-mini">
70
  <i class="dashicons dashicons-image-rotate">&nbsp;</i>
71
+ <?php echo __( 'Upgrade', 'litespeed-cache' ); ?>
72
  </a>
73
  </div>
74
  <div class="litespeed-banner-description-padding-right-15">
75
  <?php
76
+ $cfg = array( Conf::TYPE_SET . '[' . Base::O_AUTO_UPGRADE . ']' => 1 );
77
+ $url = Utility::build_url( Router::ACTION_CONF, Conf::TYPE_SET, false, null, $cfg );
78
  ?>
79
+ <a href="<?php echo $url; ?>" class="button litespeed-btn-primary litespeed-btn-mini">
80
  <i class="dashicons dashicons-update">&nbsp;</i>
81
+ <?php echo __( 'Turn On Auto Upgrade', 'litespeed-cache' ); ?>
82
  </a>
83
  </div>
84
  <div class="litespeed-banner-description-padding-right-15">
85
+ <?php $url = Utility::build_url( Core::ACTION_DISMISS, GUI::TYPE_DISMISS_PROMO, false, null, array( 'promo_tag' => 'new_version' ) ); ?>
86
+ <a href="<?php echo $url; ?>" class="button litespeed-btn-warning litespeed-btn-mini">
87
+ <?php echo __( 'Maybe Later', 'litespeed-cache' ); ?>
88
  </a>
89
  </div>
90
  </div>
92
  </div>
93
 
94
  <div>
95
+ <?php $dismiss_url = Utility::build_url( Core::ACTION_DISMISS, GUI::TYPE_DISMISS_PROMO, false, null, array( 'promo_tag' => 'new_version', 'later' => 1 ) ); ?>
96
  <span class="screen-reader-text">Dismiss this notice.</span>
97
+ <a href="<?php echo $dismiss_url; ?>" class="litespeed-notice-dismiss">X</a>
98
  </div>
99
  </div>
tpl/banner/score.php CHANGED
@@ -1,68 +1,19 @@
1
  <?php
2
- namespace LiteSpeed ;
3
- defined( 'WPINC' ) || exit ;
4
-
5
- $last_check = empty( $this->_summary[ 'score.last_check' ] ) ? 0 : $this->_summary[ 'score.last_check' ] ;
6
- // Check once per 10 days
7
- if ( time() - $last_check > 864000 ) {
8
- // Generate the ajax code to check score in separate request
9
- $this->_enqueue_score_req_ajax() ;
10
- // After detect, don't show, just return and show next time
11
- return ;
12
- }
13
-
14
- if ( ! isset( $this->_summary[ 'score.data' ] ) ) {
15
- return ;
16
- }
17
-
18
- $_score = $this->_summary[ 'score.data' ] ;
19
 
20
- if ( empty( $_score[ 'speed_before_cache' ] ) || empty( $_score[ 'speed_after_cache' ] ) || empty( $_score[ 'score_before_optm' ] ) || empty( $_score[ 'score_after_optm' ] ) ) {
21
- return ;
22
- }
23
 
24
  // If speed is not reduced half or score is larger
25
- if ( $_score[ 'speed_before_cache' ] < $_score[ 'speed_after_cache' ] * 2 || $_score[ 'score_before_optm' ] > $_score[ 'score_after_optm' ] ) {
26
- return ;
27
  }
28
 
29
  //********** Can show now **********//
30
- $this->_promo_true = true ;
31
 
32
  if ( $check_only ) {
33
- return ;
34
- }
35
-
36
- // Format loading time
37
- $speed_before_cache = $_score[ 'speed_before_cache' ] / 1000 ;
38
- if ( $speed_before_cache < 0.01 ) {
39
- $speed_before_cache = 0.01 ;
40
- }
41
- $speed_before_cache = number_format( $speed_before_cache, 2 ) ;
42
-
43
- $speed_after_cache = $_score[ 'speed_after_cache' ] / 1000 ;
44
- if ( $speed_after_cache < 0.01 ) {
45
- $speed_after_cache = number_format( $speed_after_cache, 3 ) ;
46
- }
47
- else {
48
- $speed_after_cache = number_format( $speed_after_cache, 2 ) ;
49
- }
50
-
51
- $speed_improved = ( $_score[ 'speed_before_cache' ] - $_score[ 'speed_after_cache' ] ) * 100 / $_score[ 'speed_before_cache' ] ;
52
- if ( $speed_improved > 99 ) {
53
- $speed_improved = number_format( $speed_improved, 2 ) ;
54
- }
55
- else {
56
- $speed_improved = number_format( $speed_improved ) ;
57
- }
58
-
59
- // Format PageSpeed Score
60
- $score_improved = ( $_score[ 'score_after_optm' ] - $_score[ 'score_before_optm' ] ) * 100 / $_score[ 'score_after_optm' ] ;
61
- if ( $score_improved > 99 ) {
62
- $score_improved = number_format( $score_improved, 2 ) ;
63
- }
64
- else {
65
- $score_improved = number_format( $score_improved ) ;
66
  }
67
 
68
  ?>
@@ -70,87 +21,87 @@ else {
70
  <div class="litespeed-banner-promo-logo"></div>
71
 
72
  <div class="litespeed-banner-promo-content">
73
- <h3 class="litespeed-banner-title litespeed-banner-promo-content"><?php echo __( 'Thank You for Using the LiteSpeed Cache Plugin!', 'litespeed-cache' ) ; ?></h3>
74
 
75
  <div class="litespeed-row-flex litespeed-banner-promo-content litespeed-margin-left-remove litespeed-flex-wrap">
76
  <div class="litespeed-right50 litespeed-margin-bottom20">
77
- <h2 class="litespeed-text-grey litespeed-margin-bottom-remove litespeed-top10"><?php echo __( 'Page Load Time', 'litespeed-cache' ) ; ?></h2>
78
  <hr class="litespeed-margin-bottom-remove" />
79
  <div class="litespeed-row-flex" style="margin-left: -10px;">
80
  <div class="litespeed-width-1-3 litespeed-padding-space litespeed-margin-x5">
81
  <div>
82
  <p class="litespeed-text-grey litespeed-margin-y-remove">
83
- <?php echo __( 'Before', 'litespeed-cache' ) ; ?>
84
  </p>
85
  </div>
86
  <div class="litespeed-top10 litespeed-text-jumbo litespeed-text-grey">
87
- <?php echo $speed_before_cache ; ?><span class="litespeed-text-large">s</span>
88
  </div>
89
 
90
  </div>
91
  <div class="litespeed-width-1-3 litespeed-padding-space litespeed-margin-x5">
92
  <div>
93
  <p class="litespeed-text-grey litespeed-margin-y-remove">
94
- <?php echo __( 'After', 'litespeed-cache' ) ; ?>
95
  </p>
96
  </div>
97
  <div class="litespeed-top10 litespeed-text-jumbo litespeed-success">
98
- <?php echo $speed_after_cache ; ?><span class="litespeed-text-large">s</span>
99
  </div>
100
  </div>
101
  <div class="litespeed-width-1-3 litespeed-padding-space litespeed-margin-x5">
102
  <div>
103
  <p class="litespeed-text-grey litespeed-margin-y-remove" style="white-space: nowrap;">
104
- <?php echo __( 'Improved by', 'litespeed-cache' ) ; ?>
105
  </p>
106
  </div>
107
  <div class="litespeed-top10 litespeed-text-jumbo litespeed-text-fern">
108
- <?php echo $speed_improved ; ?><span class="litespeed-text-large">%</span>
109
  </div>
110
  </div>
111
  </div>
112
 
113
  </div>
114
 
115
- <?php if ( $_score[ 'score_before_optm' ] < $_score[ 'score_after_optm' ] ) : ?>
116
  <div class="litespeed-margin-bottom20">
117
- <h2 class="litespeed-text-grey litespeed-margin-bottom-remove litespeed-top10"><?php echo __( 'PageSpeed Score', 'litespeed-cache' ) ; ?></h2>
118
  <hr class="litespeed-margin-bottom-remove" />
119
  <div class="litespeed-row-flex" style="margin-left: -10px;">
120
  <div class="litespeed-width-1-3 litespeed-padding-space litespeed-margin-x5">
121
  <div>
122
  <p class="litespeed-text-grey litespeed-text-center litespeed-margin-y-remove">
123
- <?php echo __( 'Before', 'litespeed-cache' ) ; ?>
124
  </p>
125
  </div>
126
  <div class="litespeed-promo-score" style="margin-top:-5px;">
127
- <?php echo GUI::pie( $_score[ 'score_before_optm' ], 45, false, true, 'litespeed-pie-' . $this->get_cls_of_pagescore( $_score[ 'score_before_optm' ] ) ) ; ?>
128
  </div>
129
  </div>
130
  <div class="litespeed-width-1-3 litespeed-padding-space litespeed-margin-x5">
131
  <div>
132
  <p class="litespeed-text-grey litespeed-text-center litespeed-margin-y-remove">
133
- <?php echo __( 'After', 'litespeed-cache' ) ; ?>
134
  </p>
135
  </div>
136
  <div class="litespeed-promo-score" style="margin-top:-5px;">
137
- <?php echo GUI::pie( $_score[ 'score_after_optm' ], 45, false, true, 'litespeed-pie-' . $this->get_cls_of_pagescore( $_score[ 'score_after_optm' ] ) ) ; ?>
138
  </div>
139
  </div>
140
  <div class="litespeed-width-1-3 litespeed-padding-space litespeed-margin-x5">
141
  <div>
142
  <p class="litespeed-text-grey litespeed-margin-y-remove" style="white-space: nowrap;">
143
- <?php echo __( 'Improved by', 'litespeed-cache' ) ; ?>
144
  </p>
145
  </div>
146
  <div class="litespeed-top10 litespeed-text-jumbo litespeed-text-fern">
147
- <?php echo $score_improved ; ?><span class="litespeed-text-large">%</span>
148
  </div>
149
  </div>
150
  </div>
151
 
152
  </div>
153
- <?php endif ; ?>
154
 
155
  </div>
156
 
@@ -159,30 +110,30 @@ else {
159
 
160
  <a href="https://wordpress.org/support/plugin/litespeed-cache/reviews/?filter=5#new-post" target="_blank" style="text-decoration: none;">
161
  <button class="button litespeed-btn-success litespeed-btn-mini">
162
- <?php echo __( 'Sure I\'d love to review!', 'litespeed-cache' ) ; ?>
163
  ⭐⭐⭐⭐⭐
164
  </button>
165
  </a>
166
- <button type="button" class="button litespeed-btn-primary litespeed-btn-mini" id="litespeed-promo-done"> <?php echo __( 'I\'ve already left a review', 'litespeed-cache' ) ; ?></button>
167
- <button type="button" class="button litespeed-btn-warning litespeed-btn-mini" id="litespeed-promo-later"> <?php echo __( 'Maybe later', 'litespeed-cache' ) ; ?></button>
168
  </div>
169
  <div>
170
  <p class="litespeed-text-small">
171
- <?php echo __( 'Created with ❤️ by LiteSpeed team.', 'litespeed-cache' ) ; ?>
172
  <?php echo sprintf(
173
  __( '<a %s>Support forum</a> | <a %s>Submit a ticket</a>', 'litespeed-cache' ),
174
  'href="https://wordpress.org/support/plugin/litespeed-cache" target="_blank"',
175
  'href="https://www.litespeedtech.com/support" target="_blank"'
176
- ) ; ?>
177
  </p>
178
  </div>
179
  </div>
180
  </div>
181
 
182
  <div>
183
- <?php $dismiss_url = Utility::build_url( Core::ACTION_DISMISS, GUI::TYPE_DISMISS_PROMO, false, null, array( 'promo_tag' => 'score', 'later' => 1 ) ) ; ?>
184
  <span class="screen-reader-text">Dismiss this notice.</span>
185
- <a href="<?php echo $dismiss_url ; ?>" class="litespeed-notice-dismiss">X</a>
186
  </div>
187
 
188
  </div>
1
  <?php
2
+ namespace LiteSpeed;
3
+ defined( 'WPINC' ) || exit;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
 
5
+ $health_scores = Health::get_instance()->scores();
 
 
6
 
7
  // If speed is not reduced half or score is larger
8
+ if ( $health_scores[ 'speed_before' ] < $health_scores[ 'speed_after' ] * 2 || $health_scores[ 'score_before' ] > $health_scores[ 'score_after' ] ) {
9
+ return;
10
  }
11
 
12
  //********** Can show now **********//
13
+ $this->_promo_true = true;
14
 
15
  if ( $check_only ) {
16
+ return;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  }
18
 
19
  ?>
21
  <div class="litespeed-banner-promo-logo"></div>
22
 
23
  <div class="litespeed-banner-promo-content">
24
+ <h3 class="litespeed-banner-title litespeed-banner-promo-content"><?php echo __( 'Thank You for Using the LiteSpeed Cache Plugin!', 'litespeed-cache' ); ?></h3>
25
 
26
  <div class="litespeed-row-flex litespeed-banner-promo-content litespeed-margin-left-remove litespeed-flex-wrap">
27
  <div class="litespeed-right50 litespeed-margin-bottom20">
28
+ <h2 class="litespeed-text-grey litespeed-margin-bottom-remove litespeed-top10"><?php echo __( 'Page Load Time', 'litespeed-cache' ); ?></h2>
29
  <hr class="litespeed-margin-bottom-remove" />
30
  <div class="litespeed-row-flex" style="margin-left: -10px;">
31
  <div class="litespeed-width-1-3 litespeed-padding-space litespeed-margin-x5">
32
  <div>
33
  <p class="litespeed-text-grey litespeed-margin-y-remove">
34
+ <?php echo __( 'Before', 'litespeed-cache' ); ?>
35
  </p>
36
  </div>
37
  <div class="litespeed-top10 litespeed-text-jumbo litespeed-text-grey">
38
+ <?php echo $health_scores[ 'speed_before' ]; ?><span class="litespeed-text-large">s</span>
39
  </div>
40
 
41
  </div>
42
  <div class="litespeed-width-1-3 litespeed-padding-space litespeed-margin-x5">
43
  <div>
44
  <p class="litespeed-text-grey litespeed-margin-y-remove">
45
+ <?php echo __( 'After', 'litespeed-cache' ); ?>
46
  </p>
47
  </div>
48
  <div class="litespeed-top10 litespeed-text-jumbo litespeed-success">
49
+ <?php echo $health_scores[ 'speed_after' ]; ?><span class="litespeed-text-large">s</span>
50
  </div>
51
  </div>
52
  <div class="litespeed-width-1-3 litespeed-padding-space litespeed-margin-x5">
53
  <div>
54
  <p class="litespeed-text-grey litespeed-margin-y-remove" style="white-space: nowrap;">
55
+ <?php echo __( 'Improved by', 'litespeed-cache' ); ?>
56
  </p>
57
  </div>
58
  <div class="litespeed-top10 litespeed-text-jumbo litespeed-text-fern">
59
+ <?php echo $health_scores[ 'speed_improved' ]; ?><span class="litespeed-text-large">%</span>
60
  </div>
61
  </div>
62
  </div>
63
 
64
  </div>
65
 
66
+ <?php if ( $health_scores[ 'score_before' ] < $health_scores[ 'score_after' ] ) : ?>
67
  <div class="litespeed-margin-bottom20">
68
+ <h2 class="litespeed-text-grey litespeed-margin-bottom-remove litespeed-top10"><?php echo __( 'PageSpeed Score', 'litespeed-cache' ); ?></h2>
69
  <hr class="litespeed-margin-bottom-remove" />
70
  <div class="litespeed-row-flex" style="margin-left: -10px;">
71
  <div class="litespeed-width-1-3 litespeed-padding-space litespeed-margin-x5">
72
  <div>
73
  <p class="litespeed-text-grey litespeed-text-center litespeed-margin-y-remove">
74
+ <?php echo __( 'Before', 'litespeed-cache' ); ?>
75
  </p>
76
  </div>
77
  <div class="litespeed-promo-score" style="margin-top:-5px;">
78
+ <?php echo GUI::pie( $health_scores[ 'score_before' ], 45, false, true, 'litespeed-pie-' . $this->get_cls_of_pagescore( $health_scores[ 'score_before' ] ) ); ?>
79
  </div>
80
  </div>
81
  <div class="litespeed-width-1-3 litespeed-padding-space litespeed-margin-x5">
82
  <div>
83
  <p class="litespeed-text-grey litespeed-text-center litespeed-margin-y-remove">
84
+ <?php echo __( 'After', 'litespeed-cache' ); ?>
85
  </p>
86
  </div>
87
  <div class="litespeed-promo-score" style="margin-top:-5px;">
88
+ <?php echo GUI::pie( $health_scores[ 'score_after' ], 45, false, true, 'litespeed-pie-' . $this->get_cls_of_pagescore( $health_scores[ 'score_after' ] ) ); ?>
89
  </div>
90
  </div>
91
  <div class="litespeed-width-1-3 litespeed-padding-space litespeed-margin-x5">
92
  <div>
93
  <p class="litespeed-text-grey litespeed-margin-y-remove" style="white-space: nowrap;">
94
+ <?php echo __( 'Improved by', 'litespeed-cache' ); ?>
95
  </p>
96
  </div>
97
  <div class="litespeed-top10 litespeed-text-jumbo litespeed-text-fern">
98
+ <?php echo $health_scores[ 'score_improved' ]; ?><span class="litespeed-text-large">%</span>
99
  </div>
100
  </div>
101
  </div>
102
 
103
  </div>
104
+ <?php endif; ?>
105
 
106
  </div>
107
 
110
 
111
  <a href="https://wordpress.org/support/plugin/litespeed-cache/reviews/?filter=5#new-post" target="_blank" style="text-decoration: none;">
112
  <button class="button litespeed-btn-success litespeed-btn-mini">
113
+ <?php echo __( 'Sure I\'d love to review!', 'litespeed-cache' ); ?>
114
  ⭐⭐⭐⭐⭐
115
  </button>
116
  </a>
117
+ <button type="button" class="button litespeed-btn-primary litespeed-btn-mini" id="litespeed-promo-done"> <?php echo __( 'I\'ve already left a review', 'litespeed-cache' ); ?></button>
118
+ <button type="button" class="button litespeed-btn-warning litespeed-btn-mini" id="litespeed-promo-later"> <?php echo __( 'Maybe later', 'litespeed-cache' ); ?></button>
119
  </div>
120
  <div>
121
  <p class="litespeed-text-small">
122
+ <?php echo __( 'Created with ❤️ by LiteSpeed team.', 'litespeed-cache' ); ?>
123
  <?php echo sprintf(
124
  __( '<a %s>Support forum</a> | <a %s>Submit a ticket</a>', 'litespeed-cache' ),
125
  'href="https://wordpress.org/support/plugin/litespeed-cache" target="_blank"',
126
  'href="https://www.litespeedtech.com/support" target="_blank"'
127
+ ); ?>
128
  </p>
129
  </div>
130
  </div>
131
  </div>
132
 
133
  <div>
134
+ <?php $dismiss_url = Utility::build_url( Core::ACTION_DISMISS, GUI::TYPE_DISMISS_PROMO, false, null, array( 'promo_tag' => 'score', 'later' => 1 ) ); ?>
135
  <span class="screen-reader-text">Dismiss this notice.</span>
136
+ <a href="<?php echo $dismiss_url; ?>" class="litespeed-notice-dismiss">X</a>
137
  </div>
138
 
139
  </div>
tpl/cache/settings-esi.tpl.php CHANGED
@@ -88,9 +88,9 @@ defined( 'WPINC' ) || exit ;
88
  <?php $this->build_textarea( $id ) ; ?>
89
  </div>
90
  <div class="litespeed-width-3-10">
91
- <a class="button litespeed-btn-warning" id="litespeed_fetch_esi_nonce"><?php echo __( 'Fetch Latest Predefined Nonce', 'litespeed-cache' ); ?></a>
92
  <p class="litespeed-desc">
93
- <?php echo __( 'This will append any new predefined nonce found from the latest list source', 'litespeed-cache' ); ?>: <a href="https://github.com/litespeedtech/lscache_wp/blob/master/data/esi.nonce.txt" target="_blank">https://github.com/litespeedtech/lscache_wp/blob/master/data/esi.nonce.txt</a>
94
  </p>
95
  </div>
96
  </div>
88
  <?php $this->build_textarea( $id ) ; ?>
89
  </div>
90
  <div class="litespeed-width-3-10">
91
+ <a class="button litespeed-btn-warning" id="litespeed_fetch_esi_nonce"><?php echo __( 'Fetch Latest Predefined Nonces', 'litespeed-cache' ); ?></a>
92
  <p class="litespeed-desc">
93
+ <?php echo __( 'This will append any new predefined nonces found from the latest list source', 'litespeed-cache' ); ?>: <a href="https://github.com/litespeedtech/lscache_wp/blob/master/data/esi.nonce.txt" target="_blank">https://github.com/litespeedtech/lscache_wp/blob/master/data/esi.nonce.txt</a>
94
  </p>
95
  </div>
96
  </div>
tpl/page_optm/settings_css.tpl.php CHANGED
@@ -60,6 +60,65 @@ $closest_server = Cloud::get_summary( 'server.' . Cloud::SVC_CCSS );
60
  </td>
61
  </tr>
62
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
63
  <tr>
64
  <th>
65
  <?php $id = Base::O_OPTM_CSS_HTTP2; ?>
60
  </td>
61
  </tr>
62
 
63
+ <tr class="litespeed-hide">
64
+ <th class="litespeed-padding-left">
65
+ <?php $id = Base::O_OPTM_UCSS; ?>
66
+ <?php $this->title( $id ); ?> (Experiential Only)
67
+ </th>
68
+ <td>
69
+ <?php $this->build_switch( $id ); ?>
70
+ <div class="litespeed-desc">
71
+ <?php echo __( 'Use QUIC.cloud online service to generate unique CSS.', 'litespeed-cache' ); ?>
72
+ </div>
73
+ </td>
74
+ </tr>
75
+
76
+ <tr class="litespeed-hide">
77
+ <th class="litespeed-padding-left">
78
+ <?php $id = Base::O_OPTM_UCSS_ASYNC; ?>
79
+ <?php $this->title( $id ); ?>
80
+ </th>
81
+ <td>
82
+ <?php $this->build_switch( $id ); ?>
83
+ <div class="litespeed-desc">
84
+ <?php echo __( 'Generate unique CSS in the background via a cron-based queue.', 'litespeed-cache' ); ?>
85
+ <?php echo sprintf( __( 'If set to %s this is done in the foreground, which may slow down page load.', 'litespeed-cache' ), '<code>' . __('OFF', 'litespeed-cache') . '</code>' ); ?>
86
+ </div>
87
+
88
+ <?php if ( $css_summary ) : ?>
89
+ <div class="litespeed-desc litespeed-left20">
90
+ <?php if ( ! empty( $css_summary[ 'last_request_ucss' ] ) ) : ?>
91
+ <p>
92
+ <?php echo __( 'Last generated', 'litespeed-cache' ) . ': <code>' . Utility::readable_time( $css_summary[ 'last_request_ucss' ] ) . '</code>'; ?>
93
+ </p>
94
+ <p>
95
+ <?php echo __( 'Last requested cost', 'litespeed-cache' ) . ': <code>' . $css_summary[ 'last_spent_ucss' ] . 's</code>'; ?>
96
+ </p>
97
+ <?php endif; ?>
98
+
99
+ <?php if ( $closest_server ) : ?>
100
+ <a href="<?php echo Utility::build_url( Router::ACTION_CLOUD, Cloud::TYPE_REDETECT_CLOUD, false, null, array( 'svc' => Cloud::SVC_CCSS ) ); ?>" data-balloon-pos="up" data-balloon-break aria-label='<?php echo sprintf( __( 'Current closest Cloud server is %s.&#10; Click to redetect.', 'litespeed-cache' ), $closest_server ); ?>' data-litespeed-cfm="<?php echo __( 'Are you sure to redetect the closest cloud server for this service?', 'litespeed-cache' ) ; ?>"><i class='litespeed-quic-icon'></i></a>
101
+ <?php endif; ?>
102
+
103
+ </div>
104
+ <?php endif; ?>
105
+
106
+ </td>
107
+ </tr>
108
+
109
+ <tr class="litespeed-hide">
110
+ <th class="litespeed-padding-left">
111
+ <?php $id = Base::O_OPTM_UCSS_WHITELIST; ?>
112
+ <?php $this->title( $id ); ?>
113
+ </th>
114
+ <td>
115
+ <?php $this->build_textarea( $id ); ?>
116
+ <div class="litespeed-desc">
117
+ <?php echo __( 'List the CSS selector that its style should be always contained in UCSS.', 'litespeed-cache' ); ?>
118
+ </div>
119
+ </td>
120
+ </tr>
121
+
122
  <tr>
123
  <th>
124
  <?php $id = Base::O_OPTM_CSS_HTTP2; ?>