Speed Booster Pack - Version 4.3.0

Version Description

Release Date: 29 August 2021

  • NEW - Advisor: This new feature will recommend things like upgrading your PHP version, HTTP protocol and more, in the future.
  • NEW - Set missing image dimensions: SBP can now set missing width and height parameters for <img> tags automatically.
  • NEW - Content-specific Critical CSS: Allows you to set critical CSS rules for each post, page or other custom post types.
  • NEW - Content-specific Optimize JS: Allows you to set JS optimization rules for each post, page or other custom post types.
  • Improved: Google Fonts optimizer now supports /css2 URLs!
  • Improved: Better handling of the wp-config.php file.
  • Improved: Better handling of Cloudflare credentials.
  • Improved: You can now exclude CSS files from being deferred while critical CSS is enabled.
  • Fixed: An immutable notice shows that the PageSpeed Tricker feature is enabled.
  • Fixed: Email newsletter nag shows one day after SBP is installed, instead of immediately on first install.
  • Fixed: Fixed a harmless error in the cache warmup process.
Download this release

Release Info

Developer optimocha
Plugin Icon 128x128 Speed Booster Pack
Version 4.3.0
Comparing to
See all releases

Code changes from version 4.2.2 to 4.3.0

README.txt CHANGED
@@ -5,7 +5,7 @@ Tags: speed, pagespeed, optimization, core web vitals, cache
5
  Requires at least: 4.6
6
  Tested up to: 5.8
7
  Requires PHP: 5.6
8
- Stable tag: 4.2.2
9
  License: GPLv3 or later
10
  License URI: https://www.gnu.org/licenses/gpl-3.0.html
11
 
@@ -104,6 +104,22 @@ All the time! We're always looking for new ways to get this plugin to a better s
104
 
105
  == Changelog ==
106
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
107
  = 4.2.1 & 4.2.2 =
108
 
109
  *Release Date: 03 July 2021*
5
  Requires at least: 4.6
6
  Tested up to: 5.8
7
  Requires PHP: 5.6
8
+ Stable tag: 4.3.0
9
  License: GPLv3 or later
10
  License URI: https://www.gnu.org/licenses/gpl-3.0.html
11
 
104
 
105
  == Changelog ==
106
 
107
+ = 4.3.0 =
108
+
109
+ *Release Date: 29 August 2021*
110
+
111
+ * **NEW - Advisor**: This new feature will recommend things like upgrading your PHP version, HTTP protocol and more, in the future.
112
+ * **NEW - Set missing image dimensions**: SBP can now set missing `width` and `height` parameters for `<img>` tags automatically.
113
+ * **NEW - Content-specific Critical CSS**: Allows you to set critical CSS rules for each post, page or other custom post types.
114
+ * **NEW - Content-specific Optimize JS**: Allows you to set JS optimization rules for each post, page or other custom post types.
115
+ * **Improved**: Google Fonts optimizer now supports /css2 URLs!
116
+ * **Improved**: Better handling of the wp-config.php file.
117
+ * **Improved**: Better handling of Cloudflare credentials.
118
+ * **Improved**: You can now exclude CSS files from being deferred while critical CSS is enabled.
119
+ * **Fixed**: An immutable notice shows that the PageSpeed Tricker feature is enabled.
120
+ * **Fixed**: Email newsletter nag shows one day after SBP is installed, instead of immediately on first install.
121
+ * **Fixed**: Fixed a harmless error in the cache warmup process.
122
+
123
  = 4.2.1 & 4.2.2 =
124
 
125
  *Release Date: 03 July 2021*
admin/class-speed-booster-pack-admin.php CHANGED
@@ -11,6 +11,7 @@
11
  */
12
 
13
  // If this file is called directly, abort.
 
14
  use SpeedBooster\SBP_Notice_Manager;
15
 
16
  if ( ! defined( 'WPINC' ) ) {
@@ -76,7 +77,9 @@ class Speed_Booster_Pack_Admin {
76
 
77
  add_action( 'admin_print_footer_scripts', [ $this, 'modify_menu_title' ] );
78
 
79
- $this->create_settings_page();
 
 
80
  $this->create_metaboxes();
81
  }
82
 
@@ -224,16 +227,62 @@ class Speed_Booster_Pack_Admin {
224
  );
225
  /* END Section: Dashboard */
226
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
227
  /* BEGIN Section: Caching */
228
  $cache_fields = [
229
  [
230
- 'id' => 'module_caching',
231
- 'class' => 'module-caching',
232
- 'type' => 'switcher',
233
  /* translators: used like "Enable/Disable XXX" where "XXX" is the module name. */
234
- 'title' => __( 'Enable/Disable', 'speed-booster-pack' ) . ' ' . __( 'Caching', 'speed-booster-pack' ),
235
- 'label' => __( 'Enables or disables the whole module without resetting its settings.', 'speed-booster-pack' ),
236
- 'sanitize' => 'sbp_sanitize_boolean',
237
  ],
238
  [
239
  'title' => __( 'Cache expiry time', 'speed-booster-pack' ),
@@ -321,16 +370,16 @@ class Speed_Booster_Pack_Admin {
321
 
322
  /* BEGIN Section: CDN & Proxy */
323
  /* Begin Of Cloudflare Fields */
324
- $cloudflare_fields = [
325
  [
326
  'title' => __( 'Cloudflare', 'speed-booster-pack' ),
327
  'type' => 'subheading',
328
  ],
329
  [
330
- 'title' => __( 'Connect to Cloudflare', 'speed-booster-pack' ),
331
- 'id' => 'cloudflare_enable',
332
- 'type' => 'switcher',
333
- 'sanitize' => 'sbp_sanitize_boolean',
334
  ],
335
  [
336
  'title' => __( 'Cloudflare global API key', 'speed-booster-pack' ),
@@ -462,11 +511,11 @@ class Speed_Booster_Pack_Admin {
462
  'type' => 'subheading',
463
  ],
464
  [
465
- 'title' => __( 'Connect to Sucuri', 'speed-booster-pack' ),
466
- 'id' => 'sucuri_enable',
467
- 'type' => 'switcher',
468
- 'desc' => sprintf( __( 'When you connect your Sucuri account, you\'ll be able to clear your Sucuri cache via your admin bar. Plus, every time %1$s Cache\'s cache is cleared, Sucuri\'s cache will be cleared as well.', 'speed-booster-pack' ), SBP_PLUGIN_NAME ),
469
- 'sanitize' => 'sbp_sanitize_boolean',
470
  ],
471
  [
472
  'title' => __( 'Sucuri API key', 'speed-booster-pack' ),
@@ -662,13 +711,13 @@ class Speed_Booster_Pack_Admin {
662
 
663
  [
664
  /* translators: used like "Enable/Disable XXX" where "XXX" is the module name. */
665
- 'title' => __( 'Enable/Disable', 'speed-booster-pack' ) . ' ' . __( 'Optimize CSS', 'speed-booster-pack' ),
666
- 'id' => 'module_css',
667
- 'class' => 'module-css',
668
- 'type' => 'switcher',
669
- 'label' => __( 'Enables or disables the whole module without resetting its settings.', 'speed-booster-pack' ),
670
- 'default' => true,
671
- 'sanitize' => 'sbp_sanitize_boolean',
672
  ],
673
  [
674
  'type' => 'subheading',
@@ -676,7 +725,7 @@ class Speed_Booster_Pack_Admin {
676
  ],
677
  [
678
  'id' => 'enable_criticalcss',
679
- 'title' => __( 'Enable', 'speed-booster-pack' ) . ' ' . __( ' Critical CSS', 'speed-booster-pack' ),
680
  'type' => 'switcher',
681
  'default' => false,
682
  'desc' => sprintf( __( 'Critical CSS is a method to optimize CSS delivery, %1$srecommended by Google%2$s. It allows you to defer all your CSS files and inline the styles of your content above the fold. You can generate critical CSS needed for your website %3$susing a tool like this%4$s and paste them below.', 'speed-booster-pack' ), '<a href="https://web.dev/extract-critical-css/" rel="external noopener" target="_blank">', '</a>', '<a href="https://www.sitelocity.com/critical-path-css-generator" rel="external noopener" target="_blank">', '</a>' ),
@@ -686,7 +735,7 @@ class Speed_Booster_Pack_Admin {
686
  [
687
  'id' => 'criticalcss_default',
688
  'type' => 'code_editor',
689
- 'before' => __( '<h3>Default Critical CSS</h3>', 'speed-booster-pack' ),
690
  'sanitize' => 'sbp_sanitize_strip_tags',
691
  'desc' => sprintf( __( 'This CSS block will be injected into all pages if there\'s no critical CSS blocks with higher priority. %1$sLearn more about the template hierarchy of WordPress.%2$s', 'speed-booster-pack' ), '<a href="https://developer.wordpress.org/themes/basics/template-hierarchy/" rel="external noopener" target="_blank">', '</a>' ),
692
  'dependency' => [ 'module_css|enable_criticalcss', '==|==', '1|1', '', 'visible' ],
@@ -709,6 +758,15 @@ class Speed_Booster_Pack_Admin {
709
  'dependency' => [ 'module_css|enable_criticalcss', '==|==', '1|1', '', 'visible' ],
710
  'sanitize' => 'sbp_sanitize_boolean',
711
  ],
 
 
 
 
 
 
 
 
 
712
  [
713
  'type' => 'subheading',
714
  'title' => __( 'Inline & Minify CSS', 'speed-booster-pack' ),
@@ -747,12 +805,12 @@ class Speed_Booster_Pack_Admin {
747
  $asset_fields = [
748
  [
749
  /* translators: used like "Enable/Disable XXX" where "XXX" is the module name. */
750
- 'title' => __( 'Enable/Disable', 'speed-booster-pack' ) . ' ' . __( 'Assets', 'speed-booster-pack' ),
751
- 'id' => 'module_assets',
752
- 'type' => 'switcher',
753
- 'label' => __( 'Enables or disables the whole module without resetting its settings.', 'speed-booster-pack' ),
754
- 'default' => true,
755
- 'sanitize' => 'sbp_sanitize_boolean',
756
  ],
757
  [
758
  'title' => __( 'Minify HTML', 'speed-booster-pack' ),
@@ -770,6 +828,14 @@ class Speed_Booster_Pack_Admin {
770
  'dependency' => [ 'module_assets', '==', '1', '', 'visible' ],
771
  'sanitize' => 'sbp_sanitize_boolean',
772
  ],
 
 
 
 
 
 
 
 
773
  ];
774
 
775
  $should_disable_lazyload = sbp_should_disable_feature( 'lazyload' );
@@ -851,7 +917,7 @@ class Speed_Booster_Pack_Admin {
851
  [
852
  'title' => __( 'JavaScript to exclude from moving to footer', 'speed-booster-pack' ),
853
  'id' => 'js_footer_exclude',
854
- 'class' => 'js-footer-exclude',
855
  'type' => 'code_editor',
856
  'desc' => __( 'Enter JS filenames/URLs or parts of inline JS to exclude from moving to footer.', 'speed-booster-pack' ) . ' ' . __( 'One rule per line. Each line will be taken as a separate rule, so don\'t paste entire blocks of inline JS!', 'speed-booster-pack' ),
857
  'default' => 'js/jquery/jquery.js' . PHP_EOL . 'js/jquery/jquery.min.js',
@@ -866,30 +932,22 @@ class Speed_Booster_Pack_Admin {
866
  'sanitize' => 'sbp_sanitize_strip_tags',
867
  'fields' => [
868
  [
869
- 'id' => 'preboost_enable',
870
- 'type' => 'switcher',
871
- 'label' => __( 'Enable preloading of the assets specified below.', 'speed-booster-pack' ),
872
- 'sanitize' => 'sbp_sanitize_boolean',
873
  ],
874
  [
875
  'id' => 'preboost_include',
876
  'type' => 'code_editor',
877
  'desc' => __( 'Enter full URLs of the assets you want to preload. One URL per line.', 'speed-booster-pack' ),
878
  'dependency' => [ 'preboost_enable', '==', '1', '', 'visible' ],
879
- 'settings' => [ 'lineWrapping' => true ],
 
880
  ],
881
  ],
882
  'dependency' => [ 'module_assets', '==', '1', '', 'visible' ],
883
  ],
884
- [
885
- /** B_TODO: Change text */
886
- 'title' => __( 'Content Specific Preload Post Types', 'speed-booster-pack' ),
887
- 'id' => 'csp_post_types',
888
- 'type' => 'checkbox',
889
- 'options' => 'post_types',
890
- 'sanitize' => 'sbp_sanitize_titles_in_array',
891
- 'inline' => true,
892
- ]
893
  ] );
894
 
895
  CSF::createSection(
@@ -914,13 +972,13 @@ class Speed_Booster_Pack_Admin {
914
 
915
  [
916
  /* translators: used like "Enable/Disable XXX" where "XXX" is the module name. */
917
- 'title' => __( 'Enable/Disable', 'speed-booster-pack' ) . ' ' . __( 'Special', 'speed-booster-pack' ),
918
- 'id' => 'module_special',
919
- 'class' => 'module-special',
920
- 'type' => 'switcher',
921
- 'label' => __( 'Enables or disables the whole module without resetting its settings.', 'speed-booster-pack' ),
922
- 'default' => true,
923
- 'sanitize' => 'sbp_sanitize_boolean',
924
  ],
925
  [
926
  'title' => __( 'Localize Google Analytics & Google Tag Manager', 'speed-booster-pack' ),
@@ -938,15 +996,15 @@ class Speed_Booster_Pack_Admin {
938
  'accordion_title_number' => true,
939
  'accordion_title_auto' => false,
940
  'sanitize' => function ( $item ) {
941
- if ( $item && is_iterable( $item ) ) {
942
- foreach ( $item as &$code_item ) {
943
- if ( isset( $code_item['custom_codes_item'] ) ) {
944
- $code = $code_item['custom_codes_item'];
945
- $code = preg_replace( '#<(textarea)>.*?<\/$1>#s', '', $code );
946
- $code_item['custom_codes_item'] = str_replace( '</textarea>', '', $code );
947
- }
948
- }
949
- }
950
 
951
  return $item;
952
  },
@@ -1032,10 +1090,10 @@ class Speed_Booster_Pack_Admin {
1032
  ],
1033
  [
1034
  /* translators: %s = PageSpeed Tricker */
1035
- 'title' => sprintf( __( 'Enable %s', 'speed-booster-pack' ), 'PageSpeed Tricker' ),
1036
- 'id' => 'pagespeed_tricker',
1037
- 'type' => 'switcher',
1038
- 'sanitize' => 'sbp_sanitize_boolean',
1039
  ],
1040
  ],
1041
  ]
@@ -1054,13 +1112,13 @@ class Speed_Booster_Pack_Admin {
1054
 
1055
  [
1056
  /* translators: used like "Enable/Disable XXX" where "XXX" is the module name. */
1057
- 'title' => __( 'Enable/Disable', 'speed-booster-pack' ) . ' ' . __( 'Tweaks', 'speed-booster-pack' ),
1058
- 'id' => 'module_tweaks',
1059
- 'class' => 'module-tweaks',
1060
- 'type' => 'switcher',
1061
- 'label' => __( 'Enables or disables the whole module without resetting its settings.', 'speed-booster-pack' ),
1062
- 'default' => true,
1063
- 'sanitize' => 'sbp_sanitize_boolean',
1064
  ],
1065
  [
1066
  'title' => __( 'Enable instant.page', 'speed-booster-pack' ),
@@ -1182,53 +1240,53 @@ class Speed_Booster_Pack_Admin {
1182
  'fields' => [
1183
 
1184
  [
1185
- 'title' => __( 'Shortlinks', 'speed-booster-pack' ),
1186
- 'id' => 'declutter_shortlinks',
1187
- 'type' => 'switcher',
1188
- 'label' => '<link rel=\'shortlink\' href=\'...\' />',
1189
- 'sanitize' => 'sbp_sanitize_boolean',
1190
  ],
1191
  [
1192
- 'title' => __( 'Next/previous posts links', 'speed-booster-pack' ),
1193
- 'id' => 'declutter_adjacent_posts_links',
1194
- 'type' => 'switcher',
1195
- 'label' => "<link rel='next (or prev)' title='...' href='...' />",
1196
- 'sanitize' => 'sbp_sanitize_boolean',
1197
  ],
1198
  [
1199
- 'title' => __( 'WLW Manifest link', 'speed-booster-pack' ),
1200
- 'id' => 'declutter_wlw',
1201
- 'type' => 'switcher',
1202
- 'label' => '<link rel="wlwmanifest" type="application/wlwmanifest+xml" href="..." />',
1203
- 'sanitize' => 'sbp_sanitize_boolean',
1204
  ],
1205
  [
1206
- 'title' => __( 'Really Simple Discovery (RSD) link', 'speed-booster-pack' ),
1207
- 'id' => 'declutter_rsd',
1208
- 'type' => 'switcher',
1209
- 'label' => '<link rel="EditURI" type="application/rsd+xml" title="RSD" href="..." />',
1210
- 'sanitize' => 'sbp_sanitize_boolean',
1211
  ],
1212
  [
1213
- 'title' => __( 'REST API links', 'speed-booster-pack' ),
1214
- 'id' => 'declutter_rest_api_links',
1215
- 'type' => 'switcher',
1216
- 'label' => "<link rel='https://api.w.org/' href='...' />",
1217
- 'sanitize' => 'sbp_sanitize_boolean',
1218
  ],
1219
  [
1220
- 'title' => __( 'RSS feed links', 'speed-booster-pack' ),
1221
- 'id' => 'declutter_feed_links',
1222
- 'type' => 'switcher',
1223
- 'label' => '<link rel="alternate" type="application/rss+xml" title="..." href="..." />',
1224
- 'sanitize' => 'sbp_sanitize_boolean',
1225
  ],
1226
  [
1227
- 'title' => __( 'WordPress version', 'speed-booster-pack' ),
1228
- 'id' => 'declutter_wp_version',
1229
- 'type' => 'switcher',
1230
- 'label' => '<meta name="generator" content="WordPress X.X" />',
1231
- 'sanitize' => 'sbp_sanitize_boolean',
1232
  ],
1233
  ],
1234
  'dependency' => [ 'module_tweaks', '==', '1', '', 'visible' ],
@@ -1249,7 +1307,7 @@ class Speed_Booster_Pack_Admin {
1249
  'fields' => [
1250
  [
1251
  'type' => 'subheading',
1252
- 'title' => __( 'Database Engine Converter', 'speed-booster-pack' ),
1253
  ],
1254
  [
1255
  'id' => 'button',
@@ -1336,14 +1394,14 @@ class Speed_Booster_Pack_Admin {
1336
  </ul>',
1337
  ],
1338
  [
1339
- 'title' => __( 'Allow external notices', 'speed-booster-pack' ),
1340
- 'id' => 'enable_external_notices',
1341
- 'type' => 'switcher',
1342
- 'label' => __( '', 'speed-booster-pack' ),
1343
  /* translators: %s = hyperlink to speedboosterpack.com */
1344
- 'desc' => sprintf( __( 'Fetches notices from %s, and shows them in a non-obtrusive manner. We intend to send essential notices only, and we hate spam as much as you do, but if you don\'t want to get them, you can disable this setting.', 'speed-booster-pack' ), '<a href="https://speedboosterpack.com/" rel="external noopener" target="_blank">speedboosterpack.com</a>' ),
1345
- 'default' => true,
1346
- 'sanitize' => 'sbp_sanitize_boolean',
1347
  ],
1348
  ],
1349
  ]
@@ -1354,23 +1412,25 @@ class Speed_Booster_Pack_Admin {
1354
 
1355
  public function create_metaboxes() {
1356
  /* BEGIN Metaboxes */
1357
- $metabox_prefix = 'sbp_post_meta';
1358
- $csp_post_types = sbp_get_option( 'csp_post_types' );
1359
- if ( is_array( $csp_post_types ) ) {
1360
  CSF::createMetabox( $metabox_prefix,
1361
  [
1362
  'title' => SBP_PLUGIN_NAME,
1363
- 'post_type' => $csp_post_types,
1364
  ]
1365
  );
1366
 
 
1367
  $meta_fields = [
1368
  [
1369
- 'id' => 'sbp_preload',
1370
- 'type' => 'code_editor',
1371
- 'title' => __( 'Content-Specific Preload Rules', 'speed-booster-pack' ),
1372
- 'desc' => __( 'Enter full URLs of files to preload only for this page.', 'speed-booster-pack' ),
1373
  'settings' => [ 'lineWrapping' => true ],
 
1374
  ],
1375
  ];
1376
 
@@ -1382,12 +1442,111 @@ class Speed_Booster_Pack_Admin {
1382
  'title' => __( sprintf( 'Warning: Preloading isn\'t active in %1$s%2$s settings.%3$s', '<a href="admin.php?page=sbp-settings#tab=assets" target="_blank">', SBP_PLUGIN_NAME, '</a>' ) ),
1383
  ];
1384
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1385
 
1386
  CSF::createSection( $metabox_prefix,
1387
  array(
1388
  'fields' => $meta_fields,
1389
  ) );
1390
- }
1391
  }
1392
 
1393
  public function modify_menu_title() {
11
  */
12
 
13
  // If this file is called directly, abort.
14
+ use SpeedBooster\SBP_Advisor;
15
  use SpeedBooster\SBP_Notice_Manager;
16
 
17
  if ( ! defined( 'WPINC' ) ) {
77
 
78
  add_action( 'admin_print_footer_scripts', [ $this, 'modify_menu_title' ] );
79
 
80
+ add_action( 'plugins_loaded', [ $this, 'create_settings_page' ] );
81
+
82
+ // $this->create_settings_page();
83
  $this->create_metaboxes();
84
  }
85
 
227
  );
228
  /* END Section: Dashboard */
229
 
230
+ $advisor = new SBP_Advisor();
231
+ $advisor_messages = $advisor->get_messages();
232
+ $advisor_fields = [
233
+ [
234
+ 'id' => 'advisor_heading',
235
+ 'type' => 'subheading',
236
+ 'content' => __( 'Recommendations to Improve Performance', 'speed-booster-pack' ),
237
+ ],
238
+ [
239
+ 'id' => 'advisor_introduction',
240
+ 'type' => 'content',
241
+ 'content' => __( 'All the notices below include optional, yet recommended changes to your website or your server, which will improve performance.', 'speed-booster-pack' ),
242
+ ],
243
+ ];
244
+
245
+ if ( $advisor_messages ) {
246
+ foreach ( $advisor_messages as $message_id => $message ) {
247
+ $dismissible = $message['type'] == 'dismissible' ? 'is-dismissible' : null;
248
+ $advisor_fields[] = [
249
+ 'type' => 'content',
250
+ 'content' => '<div class="notice notice-' . $message['style'] . ' ' . $dismissible . ' sbp-advice" data-message-id="' . $message_id . '">
251
+ <p>' . $message['content'] . '</p>
252
+ </div>',
253
+ ];
254
+ }
255
+ } else {
256
+ $advisor_fields[] = [
257
+ 'type' => 'submessage',
258
+ 'style' => 'success',
259
+ 'content' => '<p>' . __( 'No recommendations for now.', 'speed-booster-pack' ) . '</p>',
260
+ ];
261
+ }
262
+
263
+ /* BEGIN Section: Speed Advisor */
264
+ CSF::createSection(
265
+ $prefix,
266
+ [
267
+ 'title' => __( 'Advisor', 'speed-booster-pack' ),
268
+ 'id' => 'dashboard',
269
+ 'class' => 'dashboard',
270
+ 'icon' => 'fa fa-graduation-cap',
271
+ 'fields' => $advisor_fields,
272
+ ]
273
+ );
274
+ /* END Section: Speed Advisor */
275
+
276
  /* BEGIN Section: Caching */
277
  $cache_fields = [
278
  [
279
+ 'id' => 'module_caching',
280
+ 'class' => 'module-caching',
281
+ 'type' => 'switcher',
282
  /* translators: used like "Enable/Disable XXX" where "XXX" is the module name. */
283
+ 'title' => __( 'Enable/Disable', 'speed-booster-pack' ) . ' ' . __( 'Caching', 'speed-booster-pack' ),
284
+ 'label' => __( 'Enables or disables the whole module without resetting its settings.', 'speed-booster-pack' ),
285
+ 'sanitize' => 'sbp_sanitize_boolean',
286
  ],
287
  [
288
  'title' => __( 'Cache expiry time', 'speed-booster-pack' ),
370
 
371
  /* BEGIN Section: CDN & Proxy */
372
  /* Begin Of Cloudflare Fields */
373
+ $cloudflare_fields = [
374
  [
375
  'title' => __( 'Cloudflare', 'speed-booster-pack' ),
376
  'type' => 'subheading',
377
  ],
378
  [
379
+ 'title' => __( 'Connect to Cloudflare', 'speed-booster-pack' ),
380
+ 'id' => 'cloudflare_enable',
381
+ 'type' => 'switcher',
382
+ 'sanitize' => 'sbp_sanitize_boolean',
383
  ],
384
  [
385
  'title' => __( 'Cloudflare global API key', 'speed-booster-pack' ),
511
  'type' => 'subheading',
512
  ],
513
  [
514
+ 'title' => __( 'Connect to Sucuri', 'speed-booster-pack' ),
515
+ 'id' => 'sucuri_enable',
516
+ 'type' => 'switcher',
517
+ 'desc' => sprintf( __( 'When you connect your Sucuri account, you\'ll be able to clear your Sucuri cache via your admin bar. Plus, every time %1$s Cache\'s cache is cleared, Sucuri\'s cache will be cleared as well.', 'speed-booster-pack' ), SBP_PLUGIN_NAME ),
518
+ 'sanitize' => 'sbp_sanitize_boolean',
519
  ],
520
  [
521
  'title' => __( 'Sucuri API key', 'speed-booster-pack' ),
711
 
712
  [
713
  /* translators: used like "Enable/Disable XXX" where "XXX" is the module name. */
714
+ 'title' => __( 'Enable/Disable', 'speed-booster-pack' ) . ' ' . __( 'Optimize CSS', 'speed-booster-pack' ),
715
+ 'id' => 'module_css',
716
+ 'class' => 'module-css',
717
+ 'type' => 'switcher',
718
+ 'label' => __( 'Enables or disables the whole module without resetting its settings.', 'speed-booster-pack' ),
719
+ 'default' => true,
720
+ 'sanitize' => 'sbp_sanitize_boolean',
721
  ],
722
  [
723
  'type' => 'subheading',
725
  ],
726
  [
727
  'id' => 'enable_criticalcss',
728
+ 'title' => __( 'Enable', 'speed-booster-pack' ) . ' ' . __( 'Critical CSS', 'speed-booster-pack' ),
729
  'type' => 'switcher',
730
  'default' => false,
731
  'desc' => sprintf( __( 'Critical CSS is a method to optimize CSS delivery, %1$srecommended by Google%2$s. It allows you to defer all your CSS files and inline the styles of your content above the fold. You can generate critical CSS needed for your website %3$susing a tool like this%4$s and paste them below.', 'speed-booster-pack' ), '<a href="https://web.dev/extract-critical-css/" rel="external noopener" target="_blank">', '</a>', '<a href="https://www.sitelocity.com/critical-path-css-generator" rel="external noopener" target="_blank">', '</a>' ),
735
  [
736
  'id' => 'criticalcss_default',
737
  'type' => 'code_editor',
738
+ 'before' => '<h3>' . __( 'Default Critical CSS', 'speed-booster-pack' ) . '</h3>',
739
  'sanitize' => 'sbp_sanitize_strip_tags',
740
  'desc' => sprintf( __( 'This CSS block will be injected into all pages if there\'s no critical CSS blocks with higher priority. %1$sLearn more about the template hierarchy of WordPress.%2$s', 'speed-booster-pack' ), '<a href="https://developer.wordpress.org/themes/basics/template-hierarchy/" rel="external noopener" target="_blank">', '</a>' ),
741
  'dependency' => [ 'module_css|enable_criticalcss', '==|==', '1|1', '', 'visible' ],
758
  'dependency' => [ 'module_css|enable_criticalcss', '==|==', '1|1', '', 'visible' ],
759
  'sanitize' => 'sbp_sanitize_boolean',
760
  ],
761
+ [
762
+ 'id' => 'criticalcss_excludes',
763
+ 'type' => 'code_editor',
764
+ 'title' => __( 'Critical CSS exclude rules', 'speed-booster-pack' ),
765
+ 'sanitize' => 'sbp_sanitize_strip_tags',
766
+ 'desc' => __( 'Enter CSS file names or URLs to exclude from critical CSS.', 'speed-booster-pack' ),
767
+ 'dependency' => [ 'module_css|enable_criticalcss', '==|==', '1|1', '', 'visible' ],
768
+ 'settings' => [ 'lineWrapping' => true ],
769
+ ],
770
  [
771
  'type' => 'subheading',
772
  'title' => __( 'Inline & Minify CSS', 'speed-booster-pack' ),
805
  $asset_fields = [
806
  [
807
  /* translators: used like "Enable/Disable XXX" where "XXX" is the module name. */
808
+ 'title' => __( 'Enable/Disable', 'speed-booster-pack' ) . ' ' . __( 'Assets', 'speed-booster-pack' ),
809
+ 'id' => 'module_assets',
810
+ 'type' => 'switcher',
811
+ 'label' => __( 'Enables or disables the whole module without resetting its settings.', 'speed-booster-pack' ),
812
+ 'default' => true,
813
+ 'sanitize' => 'sbp_sanitize_boolean',
814
  ],
815
  [
816
  'title' => __( 'Minify HTML', 'speed-booster-pack' ),
828
  'dependency' => [ 'module_assets', '==', '1', '', 'visible' ],
829
  'sanitize' => 'sbp_sanitize_boolean',
830
  ],
831
+ [
832
+ 'title' => __( 'Set missing image dimensions', 'speed-booster-pack' ),
833
+ 'id' => 'missing_image_dimensions',
834
+ 'type' => 'switcher',
835
+ 'desc' => __( 'Automatically sets missing image width and height parameters to improve the Cumulative Layout Shift (CLS) and Largest Contentful Paint (LCP) metrics.', 'speed-booster-pack' ),
836
+ 'dependency' => [ 'module_assets', '==', '1', '', 'visible' ],
837
+ 'sanitize' => 'sbp_sanitize_boolean',
838
+ ],
839
  ];
840
 
841
  $should_disable_lazyload = sbp_should_disable_feature( 'lazyload' );
917
  [
918
  'title' => __( 'JavaScript to exclude from moving to footer', 'speed-booster-pack' ),
919
  'id' => 'js_footer_exclude',
920
+ 'class' => 'js-footer-exclude',
921
  'type' => 'code_editor',
922
  'desc' => __( 'Enter JS filenames/URLs or parts of inline JS to exclude from moving to footer.', 'speed-booster-pack' ) . ' ' . __( 'One rule per line. Each line will be taken as a separate rule, so don\'t paste entire blocks of inline JS!', 'speed-booster-pack' ),
923
  'default' => 'js/jquery/jquery.js' . PHP_EOL . 'js/jquery/jquery.min.js',
932
  'sanitize' => 'sbp_sanitize_strip_tags',
933
  'fields' => [
934
  [
935
+ 'id' => 'preboost_enable',
936
+ 'type' => 'switcher',
937
+ 'label' => __( 'Enable preloading of the assets specified below.', 'speed-booster-pack' ),
938
+ 'sanitize' => 'sbp_sanitize_boolean',
939
  ],
940
  [
941
  'id' => 'preboost_include',
942
  'type' => 'code_editor',
943
  'desc' => __( 'Enter full URLs of the assets you want to preload. One URL per line.', 'speed-booster-pack' ),
944
  'dependency' => [ 'preboost_enable', '==', '1', '', 'visible' ],
945
+ 'settings' => [ 'lineWrapping' => true ],
946
+ 'sanitize' => 'sbp_sanitize_strip_tags',
947
  ],
948
  ],
949
  'dependency' => [ 'module_assets', '==', '1', '', 'visible' ],
950
  ],
 
 
 
 
 
 
 
 
 
951
  ] );
952
 
953
  CSF::createSection(
972
 
973
  [
974
  /* translators: used like "Enable/Disable XXX" where "XXX" is the module name. */
975
+ 'title' => __( 'Enable/Disable', 'speed-booster-pack' ) . ' ' . __( 'Special', 'speed-booster-pack' ),
976
+ 'id' => 'module_special',
977
+ 'class' => 'module-special',
978
+ 'type' => 'switcher',
979
+ 'label' => __( 'Enables or disables the whole module without resetting its settings.', 'speed-booster-pack' ),
980
+ 'default' => true,
981
+ 'sanitize' => 'sbp_sanitize_boolean',
982
  ],
983
  [
984
  'title' => __( 'Localize Google Analytics & Google Tag Manager', 'speed-booster-pack' ),
996
  'accordion_title_number' => true,
997
  'accordion_title_auto' => false,
998
  'sanitize' => function ( $item ) {
999
+ if ( $item && is_iterable( $item ) ) {
1000
+ foreach ( $item as &$code_item ) {
1001
+ if ( isset( $code_item['custom_codes_item'] ) ) {
1002
+ $code = $code_item['custom_codes_item'];
1003
+ $code = preg_replace( '#<(textarea)>.*?<\/$1>#s', '', $code );
1004
+ $code_item['custom_codes_item'] = str_replace( '</textarea>', '', $code );
1005
+ }
1006
+ }
1007
+ }
1008
 
1009
  return $item;
1010
  },
1090
  ],
1091
  [
1092
  /* translators: %s = PageSpeed Tricker */
1093
+ 'title' => sprintf( __( 'Enable %s', 'speed-booster-pack' ), 'PageSpeed Tricker' ),
1094
+ 'id' => 'pagespeed_tricker',
1095
+ 'type' => 'switcher',
1096
+ 'sanitize' => 'sbp_sanitize_boolean',
1097
  ],
1098
  ],
1099
  ]
1112
 
1113
  [
1114
  /* translators: used like "Enable/Disable XXX" where "XXX" is the module name. */
1115
+ 'title' => __( 'Enable/Disable', 'speed-booster-pack' ) . ' ' . __( 'Tweaks', 'speed-booster-pack' ),
1116
+ 'id' => 'module_tweaks',
1117
+ 'class' => 'module-tweaks',
1118
+ 'type' => 'switcher',
1119
+ 'label' => __( 'Enables or disables the whole module without resetting its settings.', 'speed-booster-pack' ),
1120
+ 'default' => true,
1121
+ 'sanitize' => 'sbp_sanitize_boolean',
1122
  ],
1123
  [
1124
  'title' => __( 'Enable instant.page', 'speed-booster-pack' ),
1240
  'fields' => [
1241
 
1242
  [
1243
+ 'title' => __( 'Shortlinks', 'speed-booster-pack' ),
1244
+ 'id' => 'declutter_shortlinks',
1245
+ 'type' => 'switcher',
1246
+ 'label' => '<link rel=\'shortlink\' href=\'...\' />',
1247
+ 'sanitize' => 'sbp_sanitize_boolean',
1248
  ],
1249
  [
1250
+ 'title' => __( 'Next/previous posts links', 'speed-booster-pack' ),
1251
+ 'id' => 'declutter_adjacent_posts_links',
1252
+ 'type' => 'switcher',
1253
+ 'label' => "<link rel='next (or prev)' title='...' href='...' />",
1254
+ 'sanitize' => 'sbp_sanitize_boolean',
1255
  ],
1256
  [
1257
+ 'title' => __( 'WLW Manifest link', 'speed-booster-pack' ),
1258
+ 'id' => 'declutter_wlw',
1259
+ 'type' => 'switcher',
1260
+ 'label' => '<link rel="wlwmanifest" type="application/wlwmanifest+xml" href="..." />',
1261
+ 'sanitize' => 'sbp_sanitize_boolean',
1262
  ],
1263
  [
1264
+ 'title' => __( 'Really Simple Discovery (RSD) link', 'speed-booster-pack' ),
1265
+ 'id' => 'declutter_rsd',
1266
+ 'type' => 'switcher',
1267
+ 'label' => '<link rel="EditURI" type="application/rsd+xml" title="RSD" href="..." />',
1268
+ 'sanitize' => 'sbp_sanitize_boolean',
1269
  ],
1270
  [
1271
+ 'title' => __( 'REST API links', 'speed-booster-pack' ),
1272
+ 'id' => 'declutter_rest_api_links',
1273
+ 'type' => 'switcher',
1274
+ 'label' => "<link rel='https://api.w.org/' href='...' />",
1275
+ 'sanitize' => 'sbp_sanitize_boolean',
1276
  ],
1277
  [
1278
+ 'title' => __( 'RSS feed links', 'speed-booster-pack' ),
1279
+ 'id' => 'declutter_feed_links',
1280
+ 'type' => 'switcher',
1281
+ 'label' => '<link rel="alternate" type="application/rss+xml" title="..." href="..." />',
1282
+ 'sanitize' => 'sbp_sanitize_boolean',
1283
  ],
1284
  [
1285
+ 'title' => __( 'WordPress version', 'speed-booster-pack' ),
1286
+ 'id' => 'declutter_wp_version',
1287
+ 'type' => 'switcher',
1288
+ 'label' => '<meta name="generator" content="WordPress X.X" />',
1289
+ 'sanitize' => 'sbp_sanitize_boolean',
1290
  ],
1291
  ],
1292
  'dependency' => [ 'module_tweaks', '==', '1', '', 'visible' ],
1307
  'fields' => [
1308
  [
1309
  'type' => 'subheading',
1310
+ 'title' => __( 'Database Engine Converter', 'speed-booster-pack' ),
1311
  ],
1312
  [
1313
  'id' => 'button',
1394
  </ul>',
1395
  ],
1396
  [
1397
+ 'title' => __( 'Allow external notices', 'speed-booster-pack' ),
1398
+ 'id' => 'enable_external_notices',
1399
+ 'type' => 'switcher',
1400
+ 'label' => __( '', 'speed-booster-pack' ),
1401
  /* translators: %s = hyperlink to speedboosterpack.com */
1402
+ 'desc' => sprintf( __( 'Fetches notices from %s, and shows them in a non-obtrusive manner. We intend to send essential notices only, and we hate spam as much as you do, but if you don\'t want to get them, you can disable this setting.', 'speed-booster-pack' ), '<a href="https://speedboosterpack.com/" rel="external noopener" target="_blank">speedboosterpack.com</a>' ),
1403
+ 'default' => true,
1404
+ 'sanitize' => 'sbp_sanitize_boolean',
1405
  ],
1406
  ],
1407
  ]
1412
 
1413
  public function create_metaboxes() {
1414
  /* BEGIN Metaboxes */
1415
+ $metabox_prefix = 'sbp_post_meta';
1416
+ $public_post_types = get_option( 'sbp_public_post_types' );
1417
+ if ( is_array( $public_post_types ) ) {
1418
  CSF::createMetabox( $metabox_prefix,
1419
  [
1420
  'title' => SBP_PLUGIN_NAME,
1421
+ 'post_type' => $public_post_types,
1422
  ]
1423
  );
1424
 
1425
+ // BEGIN CONTENT SPECIFIC PRELOAD
1426
  $meta_fields = [
1427
  [
1428
+ 'id' => 'sbp_preload',
1429
+ 'type' => 'code_editor',
1430
+ 'title' => __( 'Preload Rules for this content', 'speed-booster-pack' ),
1431
+ 'desc' => __( 'Enter full URLs of files to preload only for this content.', 'speed-booster-pack' ),
1432
  'settings' => [ 'lineWrapping' => true ],
1433
+ 'sanitize' => 'sbp_sanitize_strip_tags',
1434
  ],
1435
  ];
1436
 
1442
  'title' => __( sprintf( 'Warning: Preloading isn\'t active in %1$s%2$s settings.%3$s', '<a href="admin.php?page=sbp-settings#tab=assets" target="_blank">', SBP_PLUGIN_NAME, '</a>' ) ),
1443
  ];
1444
  }
1445
+ // END CONTENT SPECIFIC PRELOAD
1446
+
1447
+ // BEGIN CONTENT SPECIFIC CRITICALCSS
1448
+ $meta_fields[] = [
1449
+ 'id' => 'sbp_criticalcss_status',
1450
+ 'type' => 'button_set',
1451
+ 'title' => __( 'Critical CSS for this content', 'speed-booster-pack' ),
1452
+ 'options' => array(
1453
+ 'main_setting' => 'Main setting',
1454
+ 'off' => 'Off',
1455
+ 'custom' => 'Custom',
1456
+ ),
1457
+ 'default' => 'main_setting',
1458
+ 'class' => 'sbp-gap-top',
1459
+ ];
1460
+
1461
+ $meta_fields[] = [
1462
+ 'id' => 'sbp_criticalcss',
1463
+ 'type' => 'code_editor',
1464
+ 'desc' => __( 'Paste the critical CSS rules generated for this exact URL.', 'speed-booster-pack' ),
1465
+ 'settings' => [ 'lineWrapping' => true ],
1466
+ 'dependency' => [ 'sbp_criticalcss_status', '==', 'custom', '', 'visible' ],
1467
+ 'class' => 'meta_box_critical_css_excludes',
1468
+ ];
1469
+
1470
+ if ( ! sbp_get_option( 'module_css' ) || ! sbp_get_option( 'enable_criticalcss' ) ) {
1471
+ $meta_fields[] = [
1472
+ 'id' => 'sbp_criticalcss_warning',
1473
+ 'type' => 'notice',
1474
+ 'style' => 'warning',
1475
+ 'title' => __( sprintf( 'Warning: Critical CSS isn\'t active in %1$s%2$s settings.%3$s', '<a href="admin.php?page=sbp-settings#tab=optimize-css" target="_blank">', SBP_PLUGIN_NAME, '</a>' ) ),
1476
+ ];
1477
+ }
1478
+ // END CONTENT SPECIFIC CRITICALCSS
1479
+
1480
+ // BEGIN CONTENT SPECIFIC JS DEFER
1481
+ $meta_fields[] = [
1482
+ 'title' => __( 'Optimize JS for this content', 'speed-booster-pack' ),
1483
+ 'id' => 'js_optimize',
1484
+ 'desc' => __( 'Improves JavaScript loading by deferring all JS files and inline JS, avoiding render blocking issues. You can either defer everything and exclude some JS, or only defer some JS with the Custom option. Be sure what you\'re doing and use the exclude/include lists, or you might break your front-end JavaScript!', 'speed-booster-pack' ),
1485
+ 'type' => 'button_set',
1486
+ 'options' => [
1487
+ 'main_setting' => __( 'Main setting', 'speed-booster-pack' ),
1488
+ 'off' => __( 'Off', 'speed-booster-pack' ),
1489
+ 'everything' => __( 'Everything', 'speed-booster-pack' ),
1490
+ 'custom' => __( 'Custom', 'speed-booster-pack' ),
1491
+ ],
1492
+ 'default' => 'main_setting',
1493
+ ];
1494
+
1495
+ $meta_fields[] = [
1496
+ 'title' => __( 'JavaScript to exclude from deferring', 'speed-booster-pack' ),
1497
+ 'id' => 'js_exclude',
1498
+ 'class' => 'js-exclude',
1499
+ 'type' => 'code_editor',
1500
+ 'desc' => __( 'Enter JS filenames/URLs or parts of inline JS to exclude from deferring.', 'speed-booster-pack' ) . ' ' . __( 'One rule per line. Each line will be taken as a separate rule, so don\'t paste entire blocks of inline JS!', 'speed-booster-pack' ),
1501
+ 'default' => 'js/jquery/jquery.js' . PHP_EOL . 'js/jquery/jquery.min.js',
1502
+ 'dependency' => [ 'js_optimize', '==', 'everything', '', 'visible' ],
1503
+ 'sanitize' => 'sbp_sanitize_strip_tags',
1504
+ ];
1505
+
1506
+ $meta_fields[] = [
1507
+ 'title' => __( 'JavaScript to defer', 'speed-booster-pack' ),
1508
+ 'id' => 'js_include',
1509
+ 'class' => 'js-include',
1510
+ 'type' => 'code_editor',
1511
+ 'desc' => __( 'Enter JS filenames/URLs or parts of inline JS to defer.', 'speed-booster-pack' ) . ' ' . __( 'One rule per line. Each line will be taken as a separate rule, so don\'t paste entire blocks of inline JS!', 'speed-booster-pack' ),
1512
+ 'default' => '',
1513
+ 'dependency' => [ 'js_optimize', '==', 'custom', '', 'visible' ],
1514
+ 'sanitize' => 'sbp_sanitize_strip_tags',
1515
+ ];
1516
+ // END CONTENT SPECIFIC JS DEFER
1517
+
1518
+ // BEGIN CONTENT SPECIFIC JS MOVE TO FOOTER
1519
+ $meta_fields[] = [
1520
+ 'title' => __( 'Move JS to footer for this content', 'speed-booster-pack' ),
1521
+ 'id' => 'js_footer_status',
1522
+ 'class' => 'js-footer',
1523
+ 'type' => 'button_set',
1524
+ 'options' => [
1525
+ 'main_setting' => __( 'Main setting', 'speed-booster-pack' ),
1526
+ 'off' => __( 'Off', 'speed-booster-pack' ),
1527
+ 'on' => __( 'On', 'speed-booster-pack' ),
1528
+ ],
1529
+ 'desc' => __( 'Moves all JS files and inline JS to the bottom of your page sources. Has a high chance to break your website, so be sure to exclude things! If you\'re using the defer setting, you probably don\'t need to enable this.', 'speed-booster-pack' ),
1530
+ 'default' => 'main_setting',
1531
+ ];
1532
+
1533
+ $meta_fields[] = [
1534
+ 'title' => __( 'JavaScript to exclude from moving to footer', 'speed-booster-pack' ),
1535
+ 'id' => 'js_footer_exclude',
1536
+ 'class' => 'js-footer-exclude',
1537
+ 'type' => 'code_editor',
1538
+ 'desc' => __( 'Enter JS filenames/URLs or parts of inline JS to exclude from moving to footer.', 'speed-booster-pack' ) . ' ' . __( 'One rule per line. Each line will be taken as a separate rule, so don\'t paste entire blocks of inline JS!', 'speed-booster-pack' ),
1539
+ 'default' => 'js/jquery/jquery.js' . PHP_EOL . 'js/jquery/jquery.min.js',
1540
+ 'dependency' => [ 'js_footer_status', '==', 'on', '', 'visible' ],
1541
+ 'sanitize' => 'sbp_sanitize_strip_tags',
1542
+ ];
1543
+ // END CONTENT SPECIFIC JS MOVE TO FOOTER
1544
 
1545
  CSF::createSection( $metabox_prefix,
1546
  array(
1547
  'fields' => $meta_fields,
1548
  ) );
1549
+ }
1550
  }
1551
 
1552
  public function modify_menu_title() {
admin/css/speed-booster-pack-admin.css CHANGED
@@ -190,4 +190,17 @@
190
  -webkit-box-shadow: inset 0 1px 0 rgba(120,200,230,0.6);
191
  box-shadow: inset 0 1px 0 rgba(120,200,230,0.6);
192
  color: #fff;
 
 
 
 
 
 
 
 
 
 
 
 
 
193
  }
190
  -webkit-box-shadow: inset 0 1px 0 rgba(120,200,230,0.6);
191
  box-shadow: inset 0 1px 0 rgba(120,200,230,0.6);
192
  color: #fff;
193
+ }
194
+
195
+ .sbp-advice {
196
+ padding: 7px;
197
+ padding-right: 38px;
198
+ }
199
+
200
+ .sbp-advice p {
201
+ margin-bottom: 0;
202
+ }
203
+
204
+ .meta_box_critical_css_excludes.csf-depend-on {
205
+ display: none!important;
206
  }
admin/js/speed-booster-pack-admin.js CHANGED
@@ -34,15 +34,21 @@
34
 
35
  $(document).on('click', '.sbp-cloudflare-test', function (e) {
36
  e.preventDefault();
 
 
 
 
 
 
 
 
 
 
37
  $('.sbp-cloudflare-info-text').hide();
38
  $('.sbp-cloudflare-test .sbp-cloudflare-spinner').show();
39
  $(e.target).attr('disabled', 'disabled').css('opacity', '0.6');
40
  $('.sbp-cloudflare-incorrect, .sbp-cloudflare-correct').hide();
41
 
42
- const api_key = $('[data-depend-id="cloudflare_api"]').val();
43
- const email = $('[data-depend-id="cloudflare_email"]').val();
44
- const zone_id = $('[data-depend-id="cloudflare_zone"]').val();
45
-
46
  $.ajax({
47
  url: ajaxurl,
48
  type: 'POST',
@@ -275,4 +281,18 @@
275
  });
276
  });
277
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
278
  })(jQuery);
34
 
35
  $(document).on('click', '.sbp-cloudflare-test', function (e) {
36
  e.preventDefault();
37
+
38
+ const api_key = $.trim($('[data-depend-id="cloudflare_api"]').val());
39
+ const email = $.trim($('[data-depend-id="cloudflare_email"]').val());
40
+ const zone_id = $.trim($('[data-depend-id="cloudflare_zone"]').val());
41
+
42
+ if ( ! api_key || ! email || ! zone_id ) {
43
+ alert('Global API key, email address and zone id fields are required.');
44
+ return;
45
+ }
46
+
47
  $('.sbp-cloudflare-info-text').hide();
48
  $('.sbp-cloudflare-test .sbp-cloudflare-spinner').show();
49
  $(e.target).attr('disabled', 'disabled').css('opacity', '0.6');
50
  $('.sbp-cloudflare-incorrect, .sbp-cloudflare-correct').hide();
51
 
 
 
 
 
52
  $.ajax({
53
  url: ajaxurl,
54
  type: 'POST',
281
  });
282
  });
283
 
284
+ $(document).on('click', '.sbp-advice .notice-dismiss', function() {
285
+ var message_id = $(this).parent().data('message-id');
286
+
287
+ $.ajax({
288
+ type: 'GET',
289
+ url: ajaxurl,
290
+ data: {'action': 'sbp_dismiss_advisor_message', 'sbp_action': 'sbp_dismiss_advisor_message', 'nonce': sbp_ajax_vars.nonce, 'sbp_dismiss_message_id': message_id},
291
+ success: function(response) {
292
+ },
293
+ error: function(xhr, status) {
294
+ },
295
+ });
296
+ });
297
+
298
  })(jQuery);
includes/class-speed-booster-pack.php CHANGED
@@ -17,6 +17,7 @@ if ( ! defined( 'WPINC' ) ) {
17
  die;
18
  }
19
 
 
20
  use SpeedBooster\SBP_Cache;
21
  use SpeedBooster\SBP_Cache_Warmup;
22
  use SpeedBooster\SBP_CDN;
@@ -25,6 +26,7 @@ use SpeedBooster\SBP_Critical_CSS;
25
  use SpeedBooster\SBP_CSS_Minifier;
26
  use SpeedBooster\SBP_Custom_Code_Manager;
27
  use SpeedBooster\SBP_Database_Optimizer;
 
28
  use SpeedBooster\SBP_WP_Admin;
29
  use SpeedBooster\SBP_Font_Optimizer;
30
  use SpeedBooster\SBP_HTML_Minifier;
@@ -102,6 +104,7 @@ class Speed_Booster_Pack {
102
  $this->plugin_name = 'speed-booster-pack';
103
 
104
  $this->load_dependencies();
 
105
  $this->set_locale();
106
  $this->init_modules();
107
  $this->define_admin_hooks();
@@ -170,12 +173,14 @@ class Speed_Booster_Pack {
170
  new SBP_Lazy_Loader();
171
  new SBP_CSS_Minifier();
172
  new SBP_Critical_CSS();
 
173
  new SBP_HTML_Minifier();
174
  new SBP_Localize_Tracker();
175
  new SBP_Special();
176
  new SBP_Custom_Code_Manager();
177
  new SBP_Cloudflare();
178
  new SBP_Notice_Manager();
 
179
  new SBP_Sucuri();
180
  new SBP_Cache_Warmup();
181
  new SBP_Cache();
@@ -285,6 +290,17 @@ class Speed_Booster_Pack {
285
  add_filter( 'aioseo_flush_output_buffer', '__return_false' );
286
  }
287
 
 
 
 
 
 
 
 
 
 
 
 
288
  /**
289
  * Run the loader to execute all of the hooks with WordPress.
290
  *
17
  die;
18
  }
19
 
20
+ use SpeedBooster\SBP_Advisor;
21
  use SpeedBooster\SBP_Cache;
22
  use SpeedBooster\SBP_Cache_Warmup;
23
  use SpeedBooster\SBP_CDN;
26
  use SpeedBooster\SBP_CSS_Minifier;
27
  use SpeedBooster\SBP_Custom_Code_Manager;
28
  use SpeedBooster\SBP_Database_Optimizer;
29
+ use SpeedBooster\SBP_Image_Dimensions;
30
  use SpeedBooster\SBP_WP_Admin;
31
  use SpeedBooster\SBP_Font_Optimizer;
32
  use SpeedBooster\SBP_HTML_Minifier;
104
  $this->plugin_name = 'speed-booster-pack';
105
 
106
  $this->load_dependencies();
107
+ $this->save_post_types();
108
  $this->set_locale();
109
  $this->init_modules();
110
  $this->define_admin_hooks();
173
  new SBP_Lazy_Loader();
174
  new SBP_CSS_Minifier();
175
  new SBP_Critical_CSS();
176
+ new SBP_Image_Dimensions();
177
  new SBP_HTML_Minifier();
178
  new SBP_Localize_Tracker();
179
  new SBP_Special();
180
  new SBP_Custom_Code_Manager();
181
  new SBP_Cloudflare();
182
  new SBP_Notice_Manager();
183
+ // new SBP_Advisor();
184
  new SBP_Sucuri();
185
  new SBP_Cache_Warmup();
186
  new SBP_Cache();
290
  add_filter( 'aioseo_flush_output_buffer', '__return_false' );
291
  }
292
 
293
+ private function save_post_types() {
294
+ add_action('admin_init', function() {
295
+ $post_types = array_keys( get_post_types( [ 'public' => true ] ) );
296
+ $saved_post_types = get_option( 'sbp_public_post_types' );
297
+
298
+ if ( ! $saved_post_types || $saved_post_types != $post_types ) {
299
+ update_option( 'sbp_public_post_types', $post_types );
300
+ }
301
+ });
302
+ }
303
+
304
  /**
305
  * Run the loader to execute all of the hooks with WordPress.
306
  *
includes/classes/class-sbp-advisor.php ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace SpeedBooster;
4
+
5
+ // If this file is called directly, abort.
6
+ if ( ! defined( 'WPINC' ) ) {
7
+ die;
8
+ }
9
+
10
+ class SBP_Advisor {
11
+ private $messages = [];
12
+ private $dismissed_messages = [];
13
+ private $user_meta_key = 'sbp_dismissed_messages';
14
+
15
+ public function __construct() {
16
+ $this->get_dismissed_messages();
17
+ $this->set_messages();
18
+
19
+ add_action( 'wp_ajax_sbp_dismiss_advisor_message', [ $this, 'dismiss_advisor_message' ] );
20
+ }
21
+
22
+ public function set_messages() {
23
+ $this->check_php_version();
24
+ $this->check_http_protocol_version();
25
+ }
26
+
27
+ public function get_dismissed_messages() {
28
+ $dismissed_messages = get_user_meta( get_current_user_id(), $this->user_meta_key, true );
29
+
30
+ if ( ! is_array( $dismissed_messages ) ) {
31
+ $this->dismissed_messages = [];
32
+ } else {
33
+ $this->dismissed_messages = $dismissed_messages;
34
+ }
35
+ }
36
+
37
+ private function check_http_protocol_version() {
38
+ $message_id = 'update_http_protocol';
39
+
40
+ if ( isset( $_SERVER['SERVER_PROTOCOL'] ) && $_SERVER['SERVER_PROTOCOL'] !== 'HTTP/1.1' ) {
41
+ return;
42
+ }
43
+
44
+ if ( ! in_array( $message_id, $this->dismissed_messages ) ) {
45
+ $this->messages[ $message_id ] = [
46
+ 'style' => 'warning',
47
+ 'type' => 'non-dismissible',
48
+ 'content' => __( 'You\'re using HTTP/1.1. For best performance, you should upgrade to HTTP/2 or, if possible, HTTP/3.', 'speed-booster-pack' ),
49
+ ];
50
+ }
51
+ }
52
+
53
+ private function check_php_version() {
54
+ $message_id = 'update_php';
55
+
56
+ if ( version_compare( PHP_VERSION, '7.3' ) !== -1 ) {
57
+ return;
58
+ }
59
+
60
+ if ( ! in_array( $message_id, $this->dismissed_messages ) ) {
61
+ $this->messages[ $message_id ] = [
62
+ 'style' => 'warning',
63
+ 'type' => 'non-dismissible',
64
+ 'content' => __( 'You\'re using and old version of PHP. For best performance, you should upgrade PHP to version 7.3 or above.', 'speed-booster-pack' ),
65
+ ];
66
+ }
67
+ }
68
+
69
+ public function get_messages() {
70
+ return $this->messages;
71
+ }
72
+
73
+ public function dismiss_advisor_message() {
74
+ if ( isset( $_GET['sbp_action'] ) && $_GET['sbp_action'] == 'sbp_dismiss_advisor_message' && current_user_can( 'manage_options' ) && isset( $_GET['nonce'] ) && wp_verify_nonce( $_GET['nonce'], 'sbp_ajax_nonce' ) ) {
75
+ $message_id = $_GET['sbp_dismiss_message_id'];
76
+ $this->get_dismissed_messages();
77
+ $dismissed_messages = $this->dismissed_messages;
78
+ $dismissed_messages[] = $message_id;
79
+ $dismissed_messages = array_unique($dismissed_messages);
80
+ update_user_meta( get_current_user_id(), $this->user_meta_key, $dismissed_messages );
81
+ wp_die();
82
+ }
83
+ }
84
+ }
includes/classes/class-sbp-cache-warmup.php CHANGED
@@ -25,6 +25,7 @@ class SBP_Cache_Warmup extends SBP_Abstract_Module {
25
  public function handle_warmup_request() {
26
  if ( isset( $_GET['sbp_action'] ) && $_GET['sbp_action'] == 'sbp_warmup_cache' && current_user_can( 'manage_options' ) && isset( $_GET['sbp_nonce'] ) && wp_verify_nonce( $_GET['sbp_nonce'], 'sbp_warmup_cache' ) ) {
27
  $this->start_process();
 
28
  $redirect_url = remove_query_arg( [ 'sbp_action', 'sbp_nonce' ] );
29
  wp_safe_redirect( $redirect_url );
30
  exit;
25
  public function handle_warmup_request() {
26
  if ( isset( $_GET['sbp_action'] ) && $_GET['sbp_action'] == 'sbp_warmup_cache' && current_user_can( 'manage_options' ) && isset( $_GET['sbp_nonce'] ) && wp_verify_nonce( $_GET['sbp_nonce'], 'sbp_warmup_cache' ) ) {
27
  $this->start_process();
28
+ set_transient( 'sbp_warmup_started', 1 );
29
  $redirect_url = remove_query_arg( [ 'sbp_action', 'sbp_nonce' ] );
30
  wp_safe_redirect( $redirect_url );
31
  exit;
includes/classes/class-sbp-cache.php CHANGED
@@ -225,7 +225,7 @@ class SBP_Cache extends SBP_Abstract_Module {
225
 
226
  if ( file_exists( $wp_config_file ) && sbp_check_file_permissions( $wp_config_file ) ) {
227
  // get wp config as array
228
- $wp_config = file( $wp_config_file );
229
 
230
  if ( $wp_cache ) {
231
  $append_line = PHP_EOL . "define('WP_CACHE', true); // Added by Speed Booster Pack" . PHP_EOL;
@@ -233,39 +233,15 @@ class SBP_Cache extends SBP_Abstract_Module {
233
  $append_line = '';
234
  }
235
 
236
- $found_wp_cache = false;
237
 
238
- foreach ( $wp_config as $line_number => &$line ) {
239
- if ( preg_match( '/^\s*define\s*\(\s*[\'\"]WP_CACHE[\'\"]\s*,.*\)\s*;/', $line ) ) {
240
- // Remove blank line before constant
241
- if ( isset( $wp_config[ $line_number - 1 ] ) && $wp_config[ $line_number - 1 ] === PHP_EOL ) {
242
- unset( $wp_config[ $line_number - 1 ] );
243
- }
244
-
245
- // Remove blank line after constant
246
- if ( isset( $wp_config[ $line_number + 1 ] ) && $wp_config[ $line_number + 1 ] === PHP_EOL ) {
247
- unset( $wp_config[ $line_number + 1 ] );
248
- }
249
-
250
- $line = $append_line;
251
- $found_wp_cache = true;
252
- break;
253
- }
254
- }
255
-
256
- // append wp cache constant if not found yet
257
- if ( ! $found_wp_cache && $wp_cache ) {
258
- array_shift( $wp_config );
259
- array_unshift( $wp_config, "<?php", $append_line );
260
  }
261
 
262
- // write wp-config.php file
263
- $fh = @fopen( $wp_config_file, 'w' );
264
- foreach ( $wp_config as $ln ) {
265
- @fwrite( $fh, $ln );
266
- }
267
 
268
- @fclose( $fh );
269
  }
270
  }
271
 
225
 
226
  if ( file_exists( $wp_config_file ) && sbp_check_file_permissions( $wp_config_file ) ) {
227
  // get wp config as array
228
+ $wp_config_file_content = file_get_contents( $wp_config_file );
229
 
230
  if ( $wp_cache ) {
231
  $append_line = PHP_EOL . "define('WP_CACHE', true); // Added by Speed Booster Pack" . PHP_EOL;
233
  $append_line = '';
234
  }
235
 
236
+ $wp_config_file_content = preg_replace( '/^.*define\s*\(\s*[\'\"]WP_CACHE[\'\"]\s*,.*\);.*$' . PHP_EOL . '(?:\r\n|\n)?/m', "", $wp_config_file_content );
237
 
238
+ if ( strpos( $wp_config_file_content, '<?php' ) === false && strpos( $wp_config_file_content, '<?' ) === false ) {
239
+ $wp_config_file_content = '<?php' . PHP_EOL . $wp_config_file_content;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
240
  }
241
 
242
+ $wp_config_file_content = str_replace( '<?php', '<?php' . $append_line, $wp_config_file_content );
 
 
 
 
243
 
244
+ file_put_contents( $wp_config_file, $wp_config_file_content );
245
  }
246
  }
247
 
includes/classes/class-sbp-critical-css.php CHANGED
@@ -27,28 +27,51 @@ class SBP_Critical_CSS extends SBP_Abstract_Module {
27
  return $html;
28
  }
29
 
30
- // Find Default Critical CSS Code if exists
31
- $criticalcss_code = sbp_get_option( 'criticalcss_default' );
32
-
33
- $conditions = [
34
- 'is_front_page',
35
- 'is_home',
36
- 'is_single',
37
- 'is_page',
38
- 'is_category',
39
- 'is_tag',
40
- 'is_archive',
41
- 'is_shop',
42
- 'is_product',
43
- 'is_product_category',
44
- ];
45
-
46
- foreach ( $conditions as $condition ) {
47
- if ( function_exists( $condition ) && call_user_func( $condition ) ) {
48
- $criticalcss_codes = sbp_get_option( 'criticalcss_codes' );
49
- if ( isset( $criticalcss_codes[ $condition ] ) && $criticalcss_codes[ $condition ] ) {
50
- $criticalcss_code = $criticalcss_codes[ $condition ];
51
- break;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
  }
53
  }
54
  }
@@ -66,9 +89,18 @@ class SBP_Critical_CSS extends SBP_Abstract_Module {
66
  $dom = new HtmlDocument();
67
  $dom->load( $html, true, false );
68
 
 
 
 
69
  // Find all links
70
  $links = $dom->find( 'link[rel=stylesheet]' );
71
  foreach ( $links as $link ) {
 
 
 
 
 
 
72
  if ( ( ! isset( $link->media ) || $link->media !== 'print' ) && ! in_array( $link->id, $this->excluded_handles ) ) {
73
  $link->media = 'print';
74
  $link->onload = "this.media='all'";
27
  return $html;
28
  }
29
 
30
+ $run_main_setting = false;
31
+
32
+ // Content Specific Option
33
+ if ( is_singular() ) {
34
+ $content_specific_criticalcss_status = sbp_get_post_meta( get_the_ID(), 'sbp_criticalcss_status', 'main_setting' );
35
+
36
+ if ( $content_specific_criticalcss_status == 'off' ) {
37
+ return $html;
38
+ } elseif ( $content_specific_criticalcss_status == 'custom' ) {
39
+ $content_specific_criticalcss = sbp_get_post_meta( get_the_ID(), 'sbp_criticalcss' );
40
+ } else {
41
+ $run_main_setting = true;
42
+ }
43
+ } else {
44
+ $run_main_setting = true;
45
+ }
46
+
47
+ // Find main_setting Critical CSS Code if exists
48
+ if ( $run_main_setting ) {
49
+ $criticalcss_code = sbp_get_option( 'criticalcss_default' );
50
+ } else {
51
+ $criticalcss_code = $content_specific_criticalcss;
52
+ }
53
+
54
+ if ( $run_main_setting ) {
55
+ $conditions = [
56
+ 'is_front_page',
57
+ 'is_home',
58
+ 'is_single',
59
+ 'is_page',
60
+ 'is_category',
61
+ 'is_tag',
62
+ 'is_archive',
63
+ 'is_shop',
64
+ 'is_product',
65
+ 'is_product_category',
66
+ ];
67
+
68
+ foreach ( $conditions as $condition ) {
69
+ if ( function_exists( $condition ) && call_user_func( $condition ) ) {
70
+ $criticalcss_codes = sbp_get_option( 'criticalcss_codes' );
71
+ if ( isset( $criticalcss_codes[ $condition ] ) && $criticalcss_codes[ $condition ] ) {
72
+ $criticalcss_code = $criticalcss_codes[ $condition ];
73
+ break;
74
+ }
75
  }
76
  }
77
  }
89
  $dom = new HtmlDocument();
90
  $dom->load( $html, true, false );
91
 
92
+ // Get excluded urls
93
+ $excluded_urls = SBP_Utils::explode_lines( sbp_get_option( 'criticalcss_excludes' ) );
94
+
95
  // Find all links
96
  $links = $dom->find( 'link[rel=stylesheet]' );
97
  foreach ( $links as $link ) {
98
+ foreach ( $excluded_urls as $url ) {
99
+ if ( strpos( $link, $url ) !== false ) {
100
+ continue 2;
101
+ }
102
+ }
103
+
104
  if ( ( ! isset( $link->media ) || $link->media !== 'print' ) && ! in_array( $link->id, $this->excluded_handles ) ) {
105
  $link->media = 'print';
106
  $link->onload = "this.media='all'";
includes/classes/class-sbp-font-optimizer.php CHANGED
@@ -11,6 +11,8 @@ class SBP_Font_Optimizer extends SBP_Abstract_Module {
11
  private $families;
12
  private $subsets;
13
 
 
 
14
  public function __construct() {
15
  if ( ! sbp_get_option( 'module_assets' ) || ! sbp_get_option( 'optimize_gfonts' ) ) {
16
  return;
@@ -28,6 +30,18 @@ class SBP_Font_Optimizer extends SBP_Abstract_Module {
28
  }
29
 
30
  public function process_google_fonts( $html ) {
 
 
 
 
 
 
 
 
 
 
 
 
31
  preg_match_all( "/<link[^<>\/]+href=['\"?]((https?:)?\/\/fonts\.googleapis\.com\/css\?(.*?))['\"?].*?>/is", $html, $matches );
32
  if ( ! isset( $matches[1] ) || empty( $matches[1] ) ) {
33
  return $html;
@@ -48,13 +62,111 @@ class SBP_Font_Optimizer extends SBP_Abstract_Module {
48
  }
49
  }
50
 
51
- $html = preg_replace( "/<link[^<>\/]+href=['\"?]((https?:)?\/\/fonts\.googleapis\.com\/css\?(.*?))['\"?].*?>/i", '', $html );
52
- $link_tag = $this->create_tag();
53
- $html = str_replace( '</head>', '<link rel="dns-prefetch" href="//fonts.googleapis.com" />' . PHP_EOL . '<link rel="dns-prefetch" href="//fonts.gstatic.com" />' . PHP_EOL . $link_tag . PHP_EOL . '</head>', $html );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
 
55
  return $html;
56
  }
57
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
  private function parse_attributes( $url ) {
59
  $url = htmlspecialchars_decode( $url );
60
  parse_str( parse_url( $url )['query'], $attributes );
11
  private $families;
12
  private $subsets;
13
 
14
+ private $css2_families;
15
+
16
  public function __construct() {
17
  if ( ! sbp_get_option( 'module_assets' ) || ! sbp_get_option( 'optimize_gfonts' ) ) {
18
  return;
30
  }
31
 
32
  public function process_google_fonts( $html ) {
33
+ // Process old Google Fonts API
34
+ $html = $this->process_google_fonts_api( $html );
35
+ $html = $this->process_new_google_fonts_api( $html );
36
+
37
+ $html = preg_replace( "/<link[^<>\/]+href=['\"?]((https?:)?\/\/fonts\.googleapis\.com\/css\?(.*?))['\"?].*?>/i", '', $html );
38
+ $link_tag = $this->create_tag();
39
+ $html = str_replace( '</title>', '</title>' . PHP_EOL . '<link rel="preconnect" href="https://fonts.googleapis.com" />' . PHP_EOL . '<link rel="preconnect" href="https://fonts.gstatic.com" />' . PHP_EOL . $link_tag, $html );
40
+
41
+ return $html;
42
+ }
43
+
44
+ public function process_google_fonts_api( $html ) {
45
  preg_match_all( "/<link[^<>\/]+href=['\"?]((https?:)?\/\/fonts\.googleapis\.com\/css\?(.*?))['\"?].*?>/is", $html, $matches );
46
  if ( ! isset( $matches[1] ) || empty( $matches[1] ) ) {
47
  return $html;
62
  }
63
  }
64
 
65
+ return $html;
66
+ }
67
+
68
+ public function process_new_google_fonts_api( $html ) {
69
+ preg_match_all( "/<link[^<>\/]+href=['\"?]((https?:)?\/\/fonts\.googleapis\.com\/css2\?(.*?))['\"?].*?>/is", $html, $matches );
70
+ if ( ! isset( $matches[1] ) || empty( $matches[1] ) ) {
71
+ return $html;
72
+ }
73
+
74
+ $urls = $matches[1];
75
+ $fonts = [];
76
+
77
+ // Process each url
78
+ foreach ( $urls as $url ) {
79
+ $fonts[] = $this->parse_css2_attributes( $url );
80
+ }
81
+
82
+ $list = [];
83
+ foreach ( $fonts as $font ) {
84
+ if ( is_array( $font['family'] ) ) {
85
+ foreach ( $font['family'] as $font ) {
86
+ $this->append_css2_fonts_list( $font );
87
+ $list[] = $font;
88
+ }
89
+ } else {
90
+ $this->append_css2_fonts_list( $font['family'] );
91
+ $list[] = $font['family'];
92
+ }
93
+ }
94
+
95
+ $link_tag = $this->generate_css2_link_tag();
96
+
97
+ $html = preg_replace( "/<link[^<>\/]+href=['\"?]((https?:)?\/\/fonts\.googleapis\.com\/css2\?(.*?))['\"?].*?>/i", '', $html );
98
+ $html = str_replace( '</title>', '</title>' . PHP_EOL . $link_tag, $html );
99
 
100
  return $html;
101
  }
102
 
103
+ private function append_css2_fonts_list( $font ) {
104
+ $font_array = explode( ':', $font );
105
+ $font_family = $font_array[0];
106
+
107
+ if ( isset( $font_array[1] ) ) {
108
+ $font_attributes = explode( '@', $font_array[1] );
109
+
110
+ if ( isset( $font_attributes[1] ) ) {
111
+ $weights = explode( ';', $font_attributes[1] );
112
+
113
+ if ( ! isset( $this->css2_families[ $font_family ]['weights'] ) ) {
114
+ $this->css2_families[ $font_family ]['weights'] = [];
115
+ }
116
+
117
+ $this->css2_families[ $font_family ]['weights'] = array_merge( $this->css2_families[ $font_family ]['weights'], $weights );
118
+ }
119
+
120
+ $styles = explode( ',', $font_attributes[0] );
121
+
122
+ if ( $styles ) {
123
+ foreach ( $styles as $style ) {
124
+ $this->css2_families[ $font_family ]['styles'][] = $style;
125
+ }
126
+ }
127
+ } else {
128
+ if ( ! isset( $this->css2_families[ $font_family ] ) ) {
129
+ $this->css2_families[ $font_family ] = [];
130
+ }
131
+ }
132
+ }
133
+
134
+ private function generate_css2_link_tag() {
135
+ $query_strings = [];
136
+
137
+ // Sort and clear arrays first
138
+ $this->css2_families = array_map(function($item) {
139
+ $item['styles'] = array_unique($item['styles']);
140
+ sort($item['styles']);
141
+ $item['weights'] = array_unique($item['weights']);
142
+ sort($item['weights']);
143
+
144
+ return $item;
145
+ }, $this->css2_families);
146
+
147
+ if ( $this->css2_families ) {
148
+ foreach ( $this->css2_families as $family_name => $attributes ) {
149
+ $query_string = 'family=' . $family_name;
150
+
151
+ if ( isset( $attributes['styles'] ) && $attributes['styles'] ) {
152
+ $query_string .= ':' . implode( ',', $attributes['styles'] );
153
+ }
154
+
155
+ if ( isset( $attributes['weights'] ) && $attributes['weights'] ) {
156
+ $query_string .= '@' . implode( ';', $attributes['weights'] );
157
+ }
158
+
159
+ $query_strings[] = $query_string;
160
+ }
161
+ }
162
+
163
+ return '<link rel="stylesheet" href="https://fonts.googleapis.com/css2?' . implode( '&', $query_strings ) . '" />';
164
+ }
165
+
166
+ private function parse_css2_attributes( $url ) {
167
+ return sbp_proper_parse_str( parse_url( $url )['query'] );
168
+ }
169
+
170
  private function parse_attributes( $url ) {
171
  $url = htmlspecialchars_decode( $url );
172
  parse_str( parse_url( $url )['query'], $attributes );
includes/classes/class-sbp-image-dimensions.php ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace SpeedBooster;
4
+
5
+ use simplehtmldom\HtmlDocument;
6
+
7
+ class SBP_Image_Dimensions extends SBP_Abstract_Module {
8
+ public function __construct() {
9
+ if ( ! sbp_get_option( 'module_assets' ) || ! sbp_get_option( 'missing_image_dimensions' ) ) {
10
+ return;
11
+ }
12
+
13
+ add_filter( 'sbp_output_buffer', [ $this, 'specify_missing_dimensions' ] );
14
+ }
15
+
16
+ public function specify_missing_dimensions( $html ) {
17
+ $dom = new HtmlDocument();
18
+ $dom->load( $html, true, false );
19
+ $site_url = get_option( 'siteurl' );
20
+
21
+ $images = $dom->find('img');
22
+ if ( $images ) {
23
+ foreach ( $images as &$image ) {
24
+ if ( ! isset( $image->width ) || ! isset( $image->height ) ) {
25
+ $src = $image->hasAttribute('data-src') ? $image->getAttribute('data-src') : $image->getAttribute('src');
26
+ $path = sbp_remove_leading_string( $src, $site_url );
27
+ $image_path = ABSPATH . $path;
28
+ if ( file_exists( $image_path ) ) {
29
+ $sizes = getimagesize( $image_path );
30
+ $image->width = $sizes[0];
31
+ $image->height = $sizes[1];
32
+ }
33
+ }
34
+ }
35
+ }
36
+
37
+ return $dom;
38
+ }
39
+ }
includes/classes/class-sbp-js-optimizer.php CHANGED
@@ -176,9 +176,9 @@ class SBP_JS_Optimizer extends SBP_Abstract_Module {
176
 
177
  /**
178
  *
179
- * @var mixed|null $optimize_strategy
180
  */
181
- private $optimize_strategy = 'off';
182
 
183
  /**
184
  * @var mixed|null
@@ -186,21 +186,41 @@ class SBP_JS_Optimizer extends SBP_Abstract_Module {
186
  private $js_footer = false;
187
 
188
  public function __construct() {
189
- $this->optimize_strategy = sbp_get_option( 'js_optimize', 'off' );
190
- $this->js_footer = sbp_get_option( 'js_footer' );
191
 
192
- if ( ! sbp_get_option( 'module_assets' ) || ( $this->optimize_strategy == 'off' && ! $this->js_footer ) ) {
193
- return;
 
 
 
 
194
  }
195
 
196
  $this->js_footer_exclude_rules = array_merge( SBP_Utils::explode_lines( sbp_get_option( 'js_footer_exclude' ) ), $this->default_excludes );
197
- $this->exclude_rules = array_merge( SBP_Utils::explode_lines( sbp_get_option( 'js_exclude' ) ), $this->default_excludes );
198
- $this->include_rules = array_merge( SBP_Utils::explode_lines( sbp_get_option( 'js_include' ) ), $this->default_includes );
 
 
 
 
 
 
 
 
 
 
 
 
199
 
200
- add_filter( 'sbp_output_buffer', [ $this, 'optimize_scripts' ] );
201
- }
 
 
 
 
 
202
 
203
- public function optimize_scripts( $html ) {
204
  $this->replace_comments_with_placeholders( $html );
205
  $this->find_scripts_without_defer( $html );
206
  $this->check_script_types();
@@ -210,7 +230,7 @@ class SBP_JS_Optimizer extends SBP_Abstract_Module {
210
  $this->move_scripts( $html );
211
  }
212
 
213
- if ( $this->optimize_strategy !== 'off' ) {
214
  $this->remove_excluded_scripts();
215
  $this->add_defer_attribute();
216
  $this->convert_inline_to_base64();
@@ -291,7 +311,7 @@ class SBP_JS_Optimizer extends SBP_Abstract_Module {
291
  private function remove_excluded_scripts() {
292
  $script_count = count( $this->included_scripts );
293
  for ( $i = 0; $i < $script_count; $i ++ ) {
294
- if ( $this->optimize_strategy == 'everything' ) {
295
  foreach ( $this->exclude_rules as $rule ) {
296
  if ( isset( $this->included_scripts[ $i ] ) ) {
297
  if ( strpos( $this->included_scripts[ $i ], $rule ) !== false ) {
@@ -299,7 +319,7 @@ class SBP_JS_Optimizer extends SBP_Abstract_Module {
299
  }
300
  }
301
  }
302
- } elseif ( $this->optimize_strategy == 'custom' ) {
303
  $has_found = false;
304
  foreach ( $this->include_rules as $rule ) {
305
  if ( isset( $this->included_scripts[ $i ] ) ) {
176
 
177
  /**
178
  *
179
+ * @var mixed|null $js_optimize_strategy
180
  */
181
+ private $js_optimize_strategy = 'off';
182
 
183
  /**
184
  * @var mixed|null
186
  private $js_footer = false;
187
 
188
  public function __construct() {
189
+ $this->js_optimize_strategy = sbp_get_option( 'js_optimize', 'off' );
190
+ $this->js_footer = sbp_get_option( 'js_footer' );
191
 
192
+ add_filter( 'sbp_output_buffer', [ $this, 'optimize_scripts' ] );
193
+ }
194
+
195
+ public function optimize_scripts( $html ) {
196
+ if ( ( ! sbp_get_option( 'module_assets' ) || ( $this->js_optimize_strategy == 'off' && ! $this->js_footer ) ) && ! is_singular() ) {
197
+ return $html;
198
  }
199
 
200
  $this->js_footer_exclude_rules = array_merge( SBP_Utils::explode_lines( sbp_get_option( 'js_footer_exclude' ) ), $this->default_excludes );
201
+ $this->exclude_rules = array_merge( SBP_Utils::explode_lines( sbp_get_option( 'js_exclude' ) ), $this->default_excludes );
202
+ $this->include_rules = array_merge( SBP_Utils::explode_lines( sbp_get_option( 'js_include' ) ), $this->default_includes );
203
+
204
+ if ( is_singular() ) {
205
+ $js_optimization_status = sbp_get_post_meta( get_the_ID(), 'js_optimize', 'main_setting' );
206
+ $js_footer_status = sbp_get_post_meta( get_the_ID(), 'js_footer_status', 'main_setting' );
207
+
208
+ if ( $js_optimization_status == 'off' || ( ! sbp_get_option( 'module_assets' ) && $js_optimization_status == 'main_setting' ) ) {
209
+ $this->js_optimize_strategy = 'off';
210
+ } elseif ( $js_optimization_status != 'main_setting' ) {
211
+ $this->exclude_rules = array_merge( SBP_Utils::explode_lines( sbp_get_post_meta( get_the_ID(), 'js_exclude' ) ), $this->default_excludes );
212
+ $this->include_rules = array_merge( SBP_Utils::explode_lines( sbp_get_post_meta( get_the_ID(), 'js_include' ) ), $this->default_includes );
213
+ $this->js_optimize_strategy = sbp_get_post_meta( get_the_ID(), 'js_optimize' );
214
+ }
215
 
216
+ if ( $js_footer_status == 'off' || ( ! sbp_get_option( 'module_assets' ) && $js_footer_status == 'main_setting' ) ) {
217
+ $this->js_footer = false;
218
+ } elseif ( $js_footer_status == 'on' ) {
219
+ $this->js_footer = true;
220
+ $this->js_footer_exclude_rules = array_merge( SBP_Utils::explode_lines( sbp_get_post_meta( get_the_ID(), 'js_footer_exclude' ) ), $this->default_excludes );
221
+ }
222
+ }
223
 
 
224
  $this->replace_comments_with_placeholders( $html );
225
  $this->find_scripts_without_defer( $html );
226
  $this->check_script_types();
230
  $this->move_scripts( $html );
231
  }
232
 
233
+ if ( $this->js_optimize_strategy !== 'off' ) {
234
  $this->remove_excluded_scripts();
235
  $this->add_defer_attribute();
236
  $this->convert_inline_to_base64();
311
  private function remove_excluded_scripts() {
312
  $script_count = count( $this->included_scripts );
313
  for ( $i = 0; $i < $script_count; $i ++ ) {
314
+ if ( $this->js_optimize_strategy == 'everything' ) {
315
  foreach ( $this->exclude_rules as $rule ) {
316
  if ( isset( $this->included_scripts[ $i ] ) ) {
317
  if ( strpos( $this->included_scripts[ $i ], $rule ) !== false ) {
319
  }
320
  }
321
  }
322
+ } elseif ( $this->js_optimize_strategy == 'custom' ) {
323
  $has_found = false;
324
  foreach ( $this->include_rules as $rule ) {
325
  if ( isset( $this->included_scripts[ $i ] ) ) {
includes/classes/class-sbp-migrator.php CHANGED
@@ -33,7 +33,6 @@ class SBP_Migrator {
33
 
34
  public function __construct() {
35
  add_action( 'admin_init', [ $this, 'check_migrate_notice' ] );
36
- add_action( 'upgrader_process_complete', [ $this, 'sbp_upgrade_completed' ], 10, 2 );
37
 
38
  add_action( 'wp_ajax_sbp_dismiss_migrator_notice', [ $this, 'dismiss_upgrade_notice' ] );
39
 
@@ -46,6 +45,7 @@ class SBP_Migrator {
46
  public function migrate_plugin() {
47
  $this->migrate_from_legacy();
48
  $this->update_js_optimize_options();
 
49
  update_option( 'sbp_migrator_version', SBP_MIGRATOR_VERSION );
50
  }
51
 
@@ -73,29 +73,6 @@ class SBP_Migrator {
73
  update_option( 'sbp_options', $this->sbp_options );
74
  }
75
 
76
- /**
77
- * This function runs when WordPress completes its upgrade process
78
- * It iterates through each plugin updated to see if ours is included
79
- *
80
- * @param $upgrader_object Array
81
- * @param $options Array
82
- */
83
- public function sbp_upgrade_completed( $upgrader_object, $options ) {
84
- // The path to our plugin's main file
85
- $our_plugin = 'speed-booster-pack/speed-booster-pack.php';
86
- // If an update has taken place and the updated type is plugins and the plugins element exists
87
- if ( $options['action'] == 'update' && $options['type'] == 'plugin' && isset( $options['plugins'] ) ) {
88
- // Iterate through the plugins being updated and check if ours is there
89
- foreach ( $options['plugins'] as $plugin ) {
90
- if ( $plugin == $our_plugin ) {
91
- SBP_WP_Config_Injector::inject_wp_config();
92
- SBP_Cache::generate_htaccess();
93
- SBP_Cache::set_wp_cache_constant();
94
- }
95
- }
96
- }
97
- }
98
-
99
  public function add_tracking_scripts() {
100
  if ( ! isset( $this->sbp_settings['sbp_enable_local_analytics'] ) || ! $this->sbp_settings['sbp_enable_local_analytics'] ) {
101
  return;
@@ -135,6 +112,12 @@ ga('send', 'pageview');";
135
  }
136
  }
137
 
 
 
 
 
 
 
138
  private function migrate_standard_options() {
139
  foreach ( $this->options_name_matches as $old_option_name => $new_option_name ) {
140
  $this->sbp_options[ $new_option_name ] = (int) ( isset( $this->sbp_settings[ $old_option_name ] ) ? $this->sbp_settings[ $old_option_name ] : 0 );
33
 
34
  public function __construct() {
35
  add_action( 'admin_init', [ $this, 'check_migrate_notice' ] );
 
36
 
37
  add_action( 'wp_ajax_sbp_dismiss_migrator_notice', [ $this, 'dismiss_upgrade_notice' ] );
38
 
45
  public function migrate_plugin() {
46
  $this->migrate_from_legacy();
47
  $this->update_js_optimize_options();
48
+ $this->apply_cache_settings();
49
  update_option( 'sbp_migrator_version', SBP_MIGRATOR_VERSION );
50
  }
51
 
73
  update_option( 'sbp_options', $this->sbp_options );
74
  }
75
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
76
  public function add_tracking_scripts() {
77
  if ( ! isset( $this->sbp_settings['sbp_enable_local_analytics'] ) || ! $this->sbp_settings['sbp_enable_local_analytics'] ) {
78
  return;
112
  }
113
  }
114
 
115
+ private function apply_cache_settings() {
116
+ SBP_WP_Config_Injector::inject_wp_config();
117
+ SBP_Cache::generate_htaccess();
118
+ SBP_Cache::set_wp_cache_constant();
119
+ }
120
+
121
  private function migrate_standard_options() {
122
  foreach ( $this->options_name_matches as $old_option_name => $new_option_name ) {
123
  $this->sbp_options[ $new_option_name ] = (int) ( isset( $this->sbp_settings[ $old_option_name ] ) ? $this->sbp_settings[ $old_option_name ] : 0 );
includes/classes/class-sbp-newsletter.php CHANGED
@@ -15,11 +15,18 @@ class SBP_Newsletter {
15
  }
16
 
17
  function my_admin_enqueue_scripts() {
18
- if ( current_user_can( 'manage_options' ) && ! get_user_meta( get_current_user_id(), 'sbp_hide_newsletter_pointer', true ) ) {
19
- wp_enqueue_style( 'wp-pointer' );
20
- wp_enqueue_script( 'wp-pointer' );
21
- add_action( 'admin_print_footer_scripts', [ $this, 'my_admin_print_footer_scripts' ] );
22
- }
 
 
 
 
 
 
 
23
  }
24
 
25
  function my_admin_print_footer_scripts() {
15
  }
16
 
17
  function my_admin_enqueue_scripts() {
18
+ // Check timestamp
19
+ $display_time = get_user_meta( get_current_user_id(), 'sbp_newsletter_display_time', true );
20
+ if ( ! $display_time ) {
21
+ $display_time = strtotime('+1 day');
22
+ update_user_meta( get_current_user_id(), 'sbp_newsletter_display_time', $display_time );
23
+ }
24
+
25
+ if ( time() > $display_time && current_user_can( 'manage_options' ) && ! get_user_meta( get_current_user_id(), 'sbp_hide_newsletter_pointer', true ) ) {
26
+ wp_enqueue_style( 'wp-pointer' );
27
+ wp_enqueue_script( 'wp-pointer' );
28
+ add_action( 'admin_print_footer_scripts', [ $this, 'my_admin_print_footer_scripts' ] );
29
+ }
30
  }
31
 
32
  function my_admin_print_footer_scripts() {
includes/classes/class-sbp-notice-manager.php CHANGED
@@ -8,7 +8,7 @@ if ( ! defined( 'WPINC' ) ) {
8
  }
9
 
10
  class SBP_Notice_Manager {
11
- private static $notice_count = 0;
12
 
13
  public function __construct() {
14
  add_action( 'wp_ajax_sbp_dismiss_notice', [ $this, 'dismiss_notice' ] );
@@ -56,7 +56,7 @@ class SBP_Notice_Manager {
56
  }
57
 
58
  $action = $notice_type == 'recurrent' ? 'sbp_remove_notice_transient' : 'sbp_dismiss_notice';
59
- if ( self::should_display( $id ) || ( $notice_type == 'recurrent' && get_transient( $id ) ) || ( $notice_type == 'flash' && ! get_transient( $id ) ) ) {
60
  add_action( 'admin_notices',
61
  function () use ( $type, $is_dismissible, $id, $text, $action, $pages, $notice_type ) {
62
  self::$notice_count ++;
@@ -80,11 +80,7 @@ class SBP_Notice_Manager {
80
 
81
  public static function should_display( $id ) {
82
  $dismissed_notices = self::get_dismissed_notices();
83
- if ( in_array( $id, $dismissed_notices ) ) {
84
- return false;
85
- }
86
-
87
- return true;
88
  }
89
 
90
  public static function get_dismissed_notices() {
8
  }
9
 
10
  class SBP_Notice_Manager {
11
+ public static $notice_count = 0;
12
 
13
  public function __construct() {
14
  add_action( 'wp_ajax_sbp_dismiss_notice', [ $this, 'dismiss_notice' ] );
56
  }
57
 
58
  $action = $notice_type == 'recurrent' ? 'sbp_remove_notice_transient' : 'sbp_dismiss_notice';
59
+ if ( ( $notice_type == 'one_time' && self::should_display( $id ) ) || ( $notice_type == 'recurrent' && get_transient( $id ) ) || ( $notice_type == 'flash' && ! get_transient( $id ) ) ) {
60
  add_action( 'admin_notices',
61
  function () use ( $type, $is_dismissible, $id, $text, $action, $pages, $notice_type ) {
62
  self::$notice_count ++;
80
 
81
  public static function should_display( $id ) {
82
  $dismissed_notices = self::get_dismissed_notices();
83
+ return ! in_array( $id, $dismissed_notices );
 
 
 
 
84
  }
85
 
86
  public static function get_dismissed_notices() {
includes/classes/class-sbp-preboost.php CHANGED
@@ -60,13 +60,10 @@ class SBP_Preboost extends SBP_Abstract_Module {
60
  }
61
 
62
  if ( is_singular() ) {
63
- $csp_enabled_post_types = sbp_get_option( 'csp_post_types' );
64
- if ( is_array( $csp_enabled_post_types ) && in_array( get_post_type(), $csp_enabled_post_types ) ) {
65
- $content_specific_preload_rules = sbp_get_post_meta( get_the_ID(), 'sbp_preload' );
66
- if ( $content_specific_preload_rules !== null ) {
67
- $content_specific_preload_rules_array = SBP_Utils::explode_lines( $content_specific_preload_rules );
68
- $urls = array_merge( $urls, $content_specific_preload_rules_array );
69
- }
70
  }
71
  }
72
 
60
  }
61
 
62
  if ( is_singular() ) {
63
+ $content_specific_preload_rules = sbp_get_post_meta( get_the_ID(), 'sbp_preload' );
64
+ if ( $content_specific_preload_rules !== null ) {
65
+ $content_specific_preload_rules_array = SBP_Utils::explode_lines( $content_specific_preload_rules );
66
+ $urls = array_merge( $urls, $content_specific_preload_rules_array );
 
 
 
67
  }
68
  }
69
 
includes/classes/class-sbp-utils.php CHANGED
@@ -9,7 +9,7 @@ if ( ! defined( 'WPINC' ) ) {
9
 
10
  class SBP_Utils extends SBP_Abstract_Module {
11
  public static function explode_lines( $text, $unique = true ) {
12
- if ( '' === $text ) {
13
  return [];
14
  }
15
 
9
 
10
  class SBP_Utils extends SBP_Abstract_Module {
11
  public static function explode_lines( $text, $unique = true ) {
12
+ if ( ! $text ) {
13
  return [];
14
  }
15
 
includes/classes/class-sbp-warmup-process.php CHANGED
@@ -29,7 +29,6 @@ class SBP_Warmup_Process extends \WP_Background_Process {
29
  wp_remote_get( $item['url'], $args );
30
 
31
  if ( $this->begun === false ) {
32
- set_transient( 'sbp_warmup_started', 1 );
33
  $this->begun = true;
34
  }
35
 
@@ -37,8 +36,8 @@ class SBP_Warmup_Process extends \WP_Background_Process {
37
  }
38
 
39
  protected function complete() {
40
- set_transient( 'sbp_warmup_complete', true );
41
  delete_transient( 'sbp_warmup_started' );
 
42
  parent::complete();
43
  }
44
  }
29
  wp_remote_get( $item['url'], $args );
30
 
31
  if ( $this->begun === false ) {
 
32
  $this->begun = true;
33
  }
34
 
36
  }
37
 
38
  protected function complete() {
 
39
  delete_transient( 'sbp_warmup_started' );
40
+ set_transient( 'sbp_warmup_completed', 1 );
41
  parent::complete();
42
  }
43
  }
includes/classes/class-sbp-wp-admin.php CHANGED
@@ -16,6 +16,7 @@ class SBP_WP_Admin {
16
  $this->initialize_announce4wp();
17
 
18
  add_action( 'admin_init', [ $this, 'timed_notifications' ] );
 
19
  add_action( 'admin_head', [ $this, 'check_required_file_permissions' ] );
20
  }
21
 
@@ -154,13 +155,11 @@ class SBP_WP_Admin {
154
  }
155
 
156
  // Set Cache Clear Notice
157
- if ( get_transient( 'sbp_notice_cache' ) ) {
158
- SBP_Notice_Manager::display_notice( 'sbp_notice_cache',
159
- '<p><strong>' . SBP_PLUGIN_NAME . ':</strong> ' . __( 'Cache cleared.', 'speed-booster-pack' ) . '</p>',
160
- 'success',
161
- true,
162
- 'flash' );
163
- }
164
 
165
  // Set Localizer Cache Clear Notice
166
  if ( get_transient( 'sbp_notice_tracker_localizer' ) ) {
@@ -171,24 +170,6 @@ class SBP_WP_Admin {
171
  'flash' );
172
  }
173
 
174
- // Warmup Start Notice
175
- if ( get_transient( 'sbp_warmup_started' ) ) {
176
- SBP_Notice_Manager::display_notice( 'sbp_warmup_started',
177
- '<p><strong>' . SBP_PLUGIN_NAME . ':</strong> ' . __( 'Cache warmup started.', 'speed-booster-pack' ) . '</p>',
178
- 'success',
179
- true,
180
- 'recurrent' );
181
- }
182
-
183
- // Warmup Complete Notice
184
- if ( get_transient( 'sbp_warmup_complete' ) ) {
185
- SBP_Notice_Manager::display_notice( 'sbp_warmup_complete',
186
- '<p><strong>' . SBP_PLUGIN_NAME . ':</strong> ' . __( 'Cache warmup complete.', 'speed-booster-pack' ) . '</p>',
187
- 'success',
188
- true,
189
- 'recurrent' );
190
- }
191
-
192
  // Advanced Cache File Error
193
  if ( get_transient( 'sbp_advanced_cache_error' ) ) {
194
  SBP_Notice_Manager::display_notice( 'sbp_advanced_cache_error',
@@ -209,6 +190,20 @@ class SBP_WP_Admin {
209
  'recurrent' );
210
  }
211
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
212
  // WP-Config File Error
213
  if ( get_transient( 'sbp_warmup_errors' ) ) {
214
  $list = '';
@@ -334,4 +329,10 @@ class SBP_WP_Admin {
334
  SBP_Notice_Manager::display_notice('permission_errors', $notice_content, 'warning', false, 'recurrent', 'toplevel_page_sbp-settings');
335
  }
336
  }
 
 
 
 
 
 
337
  }
16
  $this->initialize_announce4wp();
17
 
18
  add_action( 'admin_init', [ $this, 'timed_notifications' ] );
19
+ add_action( 'admin_init', [ $this, 'check_pagespeed_tricker' ] );
20
  add_action( 'admin_head', [ $this, 'check_required_file_permissions' ] );
21
  }
22
 
155
  }
156
 
157
  // Set Cache Clear Notice
158
+ SBP_Notice_Manager::display_notice( 'sbp_notice_cache',
159
+ '<p><strong>' . SBP_PLUGIN_NAME . ':</strong> ' . __( 'Cache cleared.', 'speed-booster-pack' ) . '</p>',
160
+ 'success',
161
+ true,
162
+ 'recurrent' );
 
 
163
 
164
  // Set Localizer Cache Clear Notice
165
  if ( get_transient( 'sbp_notice_tracker_localizer' ) ) {
170
  'flash' );
171
  }
172
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
173
  // Advanced Cache File Error
174
  if ( get_transient( 'sbp_advanced_cache_error' ) ) {
175
  SBP_Notice_Manager::display_notice( 'sbp_advanced_cache_error',
190
  'recurrent' );
191
  }
192
 
193
+ // Warmup Started Notice
194
+ SBP_Notice_Manager::display_notice( 'sbp_warmup_started',
195
+ '<p><strong>' . SBP_PLUGIN_NAME . ':</strong> ' . __( 'Cache warmup started.', 'speed-booster-pack' ) . '</p>',
196
+ 'info',
197
+ true,
198
+ 'recurrent' );
199
+
200
+ // Warmup Completed Notice
201
+ SBP_Notice_Manager::display_notice( 'sbp_warmup_completed',
202
+ '<p><strong>' . SBP_PLUGIN_NAME . ':</strong> ' . __( 'Cache warmup completed.', 'speed-booster-pack' ) . '</p>',
203
+ 'success',
204
+ true,
205
+ 'recurrent' );
206
+
207
  // WP-Config File Error
208
  if ( get_transient( 'sbp_warmup_errors' ) ) {
209
  $list = '';
329
  SBP_Notice_Manager::display_notice('permission_errors', $notice_content, 'warning', false, 'recurrent', 'toplevel_page_sbp-settings');
330
  }
331
  }
332
+
333
+ public function check_pagespeed_tricker() {
334
+ if ( sbp_get_option( 'pagespeed_tricker' ) ) {
335
+ SBP_Notice_Manager::display_notice( 'pagespeed_tricker_active', '<p>' . sprintf( __( '%1$s\'s experimental feature, %2$s, is enabled. You will get 100%% PageSpeed Insights scores in all PageSpeed tests, but SEO rankings are calculated by Real User Monitoring (RUM) in all search engines. %2$s only proves that it\'s easy to manipulate PageSpeed Insights and nothing else. Please don\'t keep this feature enabled on production websites!', 'speed-booster-pack' ) . '</p>', SBP_PLUGIN_NAME, 'PageSpeed Tricker' ), 'info', false );
336
+ }
337
+ }
338
  }
includes/sbp-helpers.php CHANGED
@@ -454,4 +454,43 @@ if ( ! function_exists( 'sbp_sanitize_titles_in_array' ) ) {
454
 
455
  return $array;
456
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
457
  }
454
 
455
  return $array;
456
  }
457
+ }
458
+
459
+ if ( ! function_exists( 'sbp_proper_parse_str' ) ) {
460
+ function sbp_proper_parse_str( $str ) {
461
+ # result array
462
+ $arr = array();
463
+
464
+ # split on outer delimiter
465
+ $pairs = explode( '&', $str );
466
+
467
+ # loop through each pair
468
+ foreach ( $pairs as $i ) {
469
+ # split into name and value
470
+ list( $name, $value ) = explode( '=', $i, 2 );
471
+
472
+ # if name already exists
473
+ if ( isset( $arr[ $name ] ) ) {
474
+ # stick multiple values into an array
475
+ if ( is_array( $arr[ $name ] ) ) {
476
+ $arr[ $name ][] = $value;
477
+ } else {
478
+ $arr[ $name ] = array( $arr[ $name ], $value );
479
+ }
480
+ } # otherwise, simply stick it in a scalar
481
+ else {
482
+ $arr[ $name ] = $value;
483
+ }
484
+ }
485
+
486
+ # return result array
487
+ return $arr;
488
+ }
489
+ }
490
+
491
+ if ( ! function_exists( 'sbp_get_public_post_types' ) ) {
492
+ function sbp_get_public_post_types() {
493
+ $post_types = get_option( 'sbp_public_post_types' );
494
+ return is_array( $post_types ) ? $post_types : [];
495
+ }
496
  }
speed-booster-pack.php CHANGED
@@ -6,7 +6,7 @@
6
  * Plugin Name: Speed Booster Pack
7
  * Plugin URI: https://speedboosterpack.com
8
  * Description: PageSpeed optimization is vital for SEO: A faster website equals better conversions. Optimize & cache your site with this smart plugin!
9
- * Version: 4.2.2
10
  * Author: Optimocha
11
  * Author URI: https://optimocha.com
12
  * License: GPLv3 or later
@@ -32,7 +32,7 @@ define( 'SBP_PLUGIN_NAME', 'Speed Booster Pack' );
32
  /**
33
  * Current plugin version.
34
  */
35
- define( 'SBP_VERSION', '4.2.2' );
36
 
37
  /**
38
  * Plugin website URL.
6
  * Plugin Name: Speed Booster Pack
7
  * Plugin URI: https://speedboosterpack.com
8
  * Description: PageSpeed optimization is vital for SEO: A faster website equals better conversions. Optimize & cache your site with this smart plugin!
9
+ * Version: 4.3.0
10
  * Author: Optimocha
11
  * Author URI: https://optimocha.com
12
  * License: GPLv3 or later
32
  /**
33
  * Current plugin version.
34
  */
35
+ define( 'SBP_VERSION', '4.3.0' );
36
 
37
  /**
38
  * Plugin website URL.
templates/cache/advanced-cache.php CHANGED
@@ -121,7 +121,7 @@ function get_cache_file_path()
121
 
122
  function sbp_explode_lines($text)
123
  {
124
- if ($text === '') {
125
  return [];
126
  }
127
 
121
 
122
  function sbp_explode_lines($text)
123
  {
124
+ if ( ! $text ) {
125
  return [];
126
  }
127
 
templates/wp-config/pagespeed-tricker.php CHANGED
@@ -1,7 +1,7 @@
1
  <?php
2
 
3
  if ( preg_match( '/Lighthouse/i', $_SERVER['HTTP_USER_AGENT'] ) ) {
4
- echo "<!DOCTYPE html><html lang=\"en\" style=\"background:#0cce6b;font:bold 8rem sans-serif;color:#fff\"><head><meta charset=\"UTF-8\"></head><body>You now have a perfect score. Good for you! Now go and optimize your website for humans. #Optimocha</body></html>";
5
  exit;
6
  }
7
 
1
  <?php
2
 
3
  if ( preg_match( '/Lighthouse/i', $_SERVER['HTTP_USER_AGENT'] ) ) {
4
+ echo "<!DOCTYPE html><html lang=\"en\" style=\"background:#0cce6b;font:bold 8rem sans-serif;color:#fff\"><head><meta charset=\"UTF-8\"></head><body>You now have a perfect score. Good for you! Now go and optimize your website for humans.</body></html>";
5
  exit;
6
  }
7
 
uninstall.php CHANGED
@@ -109,6 +109,8 @@ foreach ( $users as $user ) {
109
  delete_user_meta( $user->ID, 'sbp_tweet_notice_display_time' );
110
  delete_user_meta( $user->ID, 'sbp_rate_wp_org_notice_display_time' );
111
  delete_user_meta( $user->ID, 'sbp_hide_newsletter_pointer' );
 
 
112
  }
113
 
114
  // Z_TODO: let's make a tool called "Cleanup SBP metadata" in a future version
109
  delete_user_meta( $user->ID, 'sbp_tweet_notice_display_time' );
110
  delete_user_meta( $user->ID, 'sbp_rate_wp_org_notice_display_time' );
111
  delete_user_meta( $user->ID, 'sbp_hide_newsletter_pointer' );
112
+ delete_user_meta( $user->ID, 'sbp_newsletter_display_time' );
113
+ delete_user_meta( $user->ID, 'sbp_dismissed_messages' );
114
  }
115
 
116
  // Z_TODO: let's make a tool called "Cleanup SBP metadata" in a future version