NitroPack - Version 1.5.17

Version Description

  • Feature: Introduce a new features "Ecommerce Cart Cache" for WooCommerce sites
  • Improvement: Add new filter "nitropack_is_archive_page"
  • Improvement: Overall stability improvements
Download this release

Release Info

Developer nitropack
Plugin Icon 128x128 NitroPack
Version 1.5.17
Comparing to
See all releases

Code changes from version 1.5.16 to 1.5.17

classes/Integration/Server/LiteSpeed.php CHANGED
@@ -133,6 +133,7 @@ class LiteSpeed {
133
  RewriteEngine on
134
  CacheLookup on
135
 
 
136
  RewriteRule .* - [E=Cache-Control:vary=nitrodesktop]
137
 
138
  RewriteCond %{HTTP_USER_AGENT} Android|iPad|RIM\ Tablet|hp-tablet|Kindle\ Fire [NC]
@@ -151,6 +152,8 @@ RewriteRule .* - [E=Cache-Control:no-cache]
151
  </IfModule>
152
  ";
153
 
 
 
154
  $nitro = get_nitropack()->getSdk();
155
 
156
  $bypassCookies = ["wordpress_logged_in", "comment_author", "wp-postpass_", "woocommerce_items_in_cart="];
133
  RewriteEngine on
134
  CacheLookup on
135
 
136
+ RewriteRule .* - [E=NitroPackHtaccessVersion:NITROPACK_VERSION]
137
  RewriteRule .* - [E=Cache-Control:vary=nitrodesktop]
138
 
139
  RewriteCond %{HTTP_USER_AGENT} Android|iPad|RIM\ Tablet|hp-tablet|Kindle\ Fire [NC]
152
  </IfModule>
153
  ";
154
 
155
+ $rules = str_replace("NITROPACK_VERSION", NITROPACK_VERSION, $rules);
156
+
157
  $nitro = get_nitropack()->getSdk();
158
 
159
  $bypassCookies = ["wordpress_logged_in", "comment_author", "wp-postpass_", "woocommerce_items_in_cart="];
classes/WordPress/NitroPack.php CHANGED
@@ -21,14 +21,18 @@ class NitroPack {
21
  }
22
 
23
  private $sdkObjects;
 
 
24
 
25
  public $Config;
26
- public $Notification;
27
 
28
  public function __construct() {
29
  $this->Config = new Config($this);
30
  $this->Notifications = new Notifications($this);
31
  $this->sdkObjects = array();
 
 
32
  }
33
 
34
  public function getSiteConfig() {
@@ -226,4 +230,21 @@ class NitroPack {
226
  public function initDataDir() {
227
  return $this->dataDirExists() || @mkdir(NITROPACK_DATA_DIR, 0755, true); // TODO: Convert this to use the Filesystem abstraction for better Redis support
228
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
229
  }
21
  }
22
 
23
  private $sdkObjects;
24
+ private $disabledReason;
25
+ private $pageType;
26
 
27
  public $Config;
28
+ public $Notifications;
29
 
30
  public function __construct() {
31
  $this->Config = new Config($this);
32
  $this->Notifications = new Notifications($this);
33
  $this->sdkObjects = array();
34
+ $this->disabledReason = NULL;
35
+ $this->pageType = NULL;
36
  }
37
 
38
  public function getSiteConfig() {
230
  public function initDataDir() {
231
  return $this->dataDirExists() || @mkdir(NITROPACK_DATA_DIR, 0755, true); // TODO: Convert this to use the Filesystem abstraction for better Redis support
232
  }
233
+
234
+ public function setDisabledReason($reason) {
235
+ $this->disabledReason = $reason;
236
+ nitropack_header("X-Nitro-Disabled-Reason: $reason");
237
+ }
238
+
239
+ public function getDisabledReason() {
240
+ return $this->disabledReason;
241
+ }
242
+
243
+ public function setPageType($type) {
244
+ $this->pageType = $type;
245
+ }
246
+
247
+ public function getPageType() {
248
+ return $this->pageType;
249
+ }
250
  }
constants.php CHANGED
@@ -6,7 +6,7 @@ function nitropack_trailingslashit($string) {
6
  return rtrim( $string, '/\\' ) . '/';
7
  }
8
 
9
- define( 'NITROPACK_VERSION', '1.5.16' );
10
  define( 'NITROPACK_OPTION_GROUP', 'nitropack' );
11
  define( 'NITROPACK_DATA_DIR', nitropack_trailingslashit(WP_CONTENT_DIR) . 'nitropack' );
12
  define( 'NITROPACK_CONFIG_FILE', nitropack_trailingslashit(NITROPACK_DATA_DIR) . 'config.json' );
6
  return rtrim( $string, '/\\' ) . '/';
7
  }
8
 
9
+ define( 'NITROPACK_VERSION', '1.5.17' );
10
  define( 'NITROPACK_OPTION_GROUP', 'nitropack' );
11
  define( 'NITROPACK_DATA_DIR', nitropack_trailingslashit(WP_CONTENT_DIR) . 'nitropack' );
12
  define( 'NITROPACK_CONFIG_FILE', nitropack_trailingslashit(NITROPACK_DATA_DIR) . 'config.json' );
functions.php CHANGED
@@ -26,15 +26,28 @@ function nitropack_is_logged_in() {
26
  }
27
 
28
  function nitropack_passes_cookie_requirements() {
29
- $isUserLoggedIn = nitropack_is_logged_in() && !nitropack_header("X-Nitro-Disabled-Reason: logged in");
30
  $cookieStr = implode("|", array_keys($_COOKIE));
31
- $safeCookie = (strpos($cookieStr, "comment_author") === false
32
- && strpos($cookieStr, "wp-postpass_") === false
33
- && empty($_COOKIE["woocommerce_items_in_cart"]))
34
- || !!nitropack_header("X-Nitro-Disabled-Reason: cookie bypass");
 
 
 
 
 
 
 
 
 
 
 
 
 
35
 
36
  // allow registering filters to "nitropack_passes_cookie_requirements"
37
- return apply_filters("nitropack_passes_cookie_requirements", $safeCookie && !$isUserLoggedIn);
38
  }
39
 
40
  function nitropack_activate() {
@@ -385,6 +398,9 @@ function nitropack_handle_beacon() {
385
  }
386
 
387
  function nitropack_handle_webhook() {
 
 
 
388
  if (!defined("NITROPACK_WEBHOOK_HANDLED")) {
389
  define("NITROPACK_WEBHOOK_HANDLED", 1);
390
  } else {
@@ -460,8 +476,8 @@ function nitropack_sanitize_url_input($url) {
460
 
461
  function nitropack_is_amp_page() {
462
  return
463
- (function_exists('amp_is_request') && amp_is_request() && !nitropack_header("X-Nitro-Disabled-Reason: amp page")) ||
464
- (function_exists('ampforwp_is_amp_endpoint') && ampforwp_is_amp_endpoint() && !nitropack_header("X-Nitro-Disabled-Reason: amp page"));
465
  }
466
 
467
  function nitropack_passes_page_requirements($detectIfNoCachedResult = true) {
@@ -471,24 +487,24 @@ function nitropack_passes_page_requirements($detectIfNoCachedResult = true) {
471
 
472
  if ($cachedResult === NULL && $detectIfNoCachedResult) {
473
  $cachedResult = !(
474
- ( is_404() && !nitropack_header("X-Nitro-Disabled-Reason: 404") ) ||
475
- ( is_preview() && !nitropack_header("X-Nitro-Disabled-Reason: preview page") ) ||
476
- ( is_feed() && !nitropack_header("X-Nitro-Disabled-Reason: feed") ) ||
477
- ( is_comment_feed() && !nitropack_header("X-Nitro-Disabled-Reason: comment feed") ) ||
478
- ( is_trackback() && !nitropack_header("X-Nitro-Disabled-Reason: trackback") ) ||
479
- ( is_user_logged_in() && !nitropack_header("X-Nitro-Disabled-Reason: logged in") ) ||
480
- ( is_search() && !nitropack_header("X-Nitro-Disabled-Reason: search") ) ||
481
- ( nitropack_is_ajax() && !nitropack_header("X-Nitro-Disabled-Reason: ajax") ) ||
482
- ( nitropack_is_post() && !nitropack_header("X-Nitro-Disabled-Reason: post request") ) ||
483
- ( nitropack_is_xmlrpc() && !nitropack_header("X-Nitro-Disabled-Reason: xmlrpc") ) ||
484
- ( nitropack_is_robots() && !nitropack_header("X-Nitro-Disabled-Reason: robots") ) ||
485
  nitropack_is_amp_page() ||
486
  !nitropack_is_allowed_request() ||
487
- ( nitropack_is_wp_cron() && !nitropack_header("X-Nitro-Disabled-Reason: doing cron") ) || // CRON request
488
  ( nitropack_is_wp_cli() ) || // CLI request
489
- ( defined('WC_PLUGIN_FILE') && (is_page( 'cart' ) || ( !$reduceCartChecks && is_cart()) ) && !nitropack_header("X-Nitro-Disabled-Reason: cart page") ) || // WooCommerce
490
- ( defined('WC_PLUGIN_FILE') && (is_page( 'checkout' ) || ( !$reduceCheckoutChecks && is_checkout()) ) && !nitropack_header("X-Nitro-Disabled-Reason: checkout page") ) || // WooCommerce
491
- ( defined('WC_PLUGIN_FILE') && is_account_page() && !nitropack_header("X-Nitro-Disabled-Reason: account page") ) // WooCommerce
492
  );
493
  }
494
 
@@ -500,7 +516,7 @@ function nitropack_is_home() {
500
  }
501
 
502
  function nitropack_is_archive() {
503
- return is_author() || is_archive();
504
  }
505
 
506
  function nitropack_is_allowed_request() {
@@ -509,26 +525,26 @@ function nitropack_is_allowed_request() {
509
  if (is_array($cacheableObjectTypes)) {
510
  if (nitropack_is_home()) {
511
  if (!in_array('home', $cacheableObjectTypes)) {
512
- nitropack_header("X-Nitro-Disabled-Reason: page type not allowed (home)");
513
  return false;
514
  }
515
  } else {
516
  if (is_tax() || is_category() || is_tag()) {
517
  $np_queriedObj = get_queried_object();
518
  if (!empty($np_queriedObj) && !in_array($np_queriedObj->taxonomy, $cacheableObjectTypes)) {
519
- nitropack_header("X-Nitro-Disabled-Reason: page type not allowed ({$np_queriedObj->taxonomy})");
520
  return false;
521
  }
522
  } else {
523
  if (nitropack_is_archive()) {
524
  if (!in_array('archive', $cacheableObjectTypes)) {
525
- nitropack_header("X-Nitro-Disabled-Reason: page type not allowed (archive)");
526
  return false;
527
  }
528
  } else {
529
  $postType = get_post_type();
530
  if (!empty($postType) && !in_array($postType, $cacheableObjectTypes)) {
531
- nitropack_header("X-Nitro-Disabled-Reason: page type not allowed ($postType)");
532
  return false;
533
  }
534
  }
@@ -538,11 +554,11 @@ function nitropack_is_allowed_request() {
538
 
539
  if (null !== $nitro = get_nitropack_sdk() ) {
540
  return
541
- ( $nitro->isAllowedUrl($nitro->getUrl()) || nitropack_header("X-Nitro-Disabled-Reason: url not allowed") ) &&
542
- ( $nitro->isAllowedRequest(true) || nitropack_header("X-Nitro-Disabled-Reason: request type not allowed") );
543
  }
544
 
545
- nitropack_header("X-Nitro-Disabled-Reason: site not connected");
546
  return false;
547
  }
548
 
@@ -642,6 +658,18 @@ function nitropack_init() {
642
  if (is_valid_nitropack_beacon()) {
643
  nitropack_handle_beacon();
644
  } else {
 
 
 
 
 
 
 
 
 
 
 
 
645
  if (!isset($_GET["wpf_action"]) && nitropack_passes_cookie_requirements() && nitropack_passes_page_requirements()) {
646
  add_action('wp_footer', 'nitropack_print_beacon_script');
647
  add_action('get_footer', 'nitropack_print_beacon_script');
@@ -659,17 +687,15 @@ function nitropack_init() {
659
  nitropack_set_custom_expiration();
660
  }
661
 
662
- $layout = nitropack_get_layout();
663
 
664
  /* The following if statement should stay as it is written.
665
  * is_archive() can return true if visiting a tax, category or tag page, so is_acrchive must be checked last
666
  */
667
  if (is_tax() || is_category() || is_tag()) {
668
  $np_queriedObj = get_queried_object();
669
- $GLOBALS["NitroPack.tags"]["pageType:" . $np_queriedObj->taxonomy] = 1;
670
  $GLOBALS["NitroPack.tags"]["tax:" . $np_queriedObj->term_taxonomy_id] = 1;
671
  } else {
672
- $GLOBALS["NitroPack.tags"]["pageType:" . $layout] = 1;
673
  if (is_single() || is_page() || is_attachment()) {
674
  $singlePost = get_post();
675
  if ($singlePost) {
@@ -835,6 +861,7 @@ function nitropack_get_cookie_handler_script() {
835
  function nitropack_print_telemetry_script() {
836
  if (defined("NITROPACK_TELEMETRY_PRINTED")) return;
837
  define("NITROPACK_TELEMETRY_PRINTED", true);
 
838
  echo apply_filters("nitro_script_output", nitropack_get_telemetry_script());
839
  }
840
 
@@ -852,6 +879,37 @@ function nitropack_get_telemetry_script() {
852
  return "";
853
  }
854
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
855
  function nitropack_has_advanced_cache() {
856
  return defined( 'NITROPACK_ADVANCED_CACHE' );
857
  }
@@ -2319,6 +2377,23 @@ function nitropack_set_auto_cache_purge_ajax() {
2319
  update_option("nitropack-autoCachePurge", (int)$autoCachePurgeStatus);
2320
  }
2321
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2322
  function nitropack_set_bb_cache_purge_sync_ajax() {
2323
  $bbCacheSyncPurgeStatus = !empty($_POST["bbCachePurgeSyncStatus"]);
2324
  update_option("nitropack-bbCacheSyncPurge", (int)$bbCacheSyncPurgeStatus);
@@ -2369,6 +2444,32 @@ function nitropack_test_compression_ajax() {
2369
  nitropack_json_and_exit(array("status" => "success", "hasCompression" => $hasCompression));
2370
  }
2371
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2372
  function nitropack_handle_compression_toggle($old_value, $new_value) {
2373
  nitropack_update_blog_compression($new_value == 1);
2374
  }
@@ -2540,6 +2641,44 @@ function nitropack_disable_safemode() {
2540
  ));
2541
  }
2542
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2543
  function nitropack_safemode_status() {
2544
  if (null !== $nitro = get_nitropack_sdk()) {
2545
  try {
@@ -2588,10 +2727,16 @@ function nitropack_event($event, $nitro = null, $additional_meta_data = null) {
2588
  try {
2589
  $eventUrl = get_nitropack_integration_url("extensionEvent", $nitro);
2590
  $domain = !empty($_SERVER["HTTP_HOST"]) ? $_SERVER["HTTP_HOST"] : "Unknown";
 
 
 
 
 
 
2591
 
2592
  $query_data = array(
2593
  'event' => $event,
2594
- 'platform' => 'WordPress',
2595
  'platform_version' => $wp_version,
2596
  'nitropack_extension_version' => NITROPACK_VERSION,
2597
  'additional_meta_data' => $additional_meta_data ? json_encode($additional_meta_data) : "{}",
@@ -3125,6 +3270,12 @@ function nitropack_plugin_notices() {
3125
  }
3126
  }
3127
  }
 
 
 
 
 
 
3128
  }
3129
 
3130
  if (!empty($_COOKIE["nitropack_upgrade_to_1_3_notice"])) {
26
  }
27
 
28
  function nitropack_passes_cookie_requirements() {
29
+ $isUserLoggedIn = nitropack_is_logged_in();
30
  $cookieStr = implode("|", array_keys($_COOKIE));
31
+ $safeCookie = (
32
+ (strpos($cookieStr, "comment_author") === false || !!get_nitropack()->setDisabledReason("comment author"))
33
+ && (strpos($cookieStr, "wp-postpass_") === false || !!get_nitropack()->setDisabledReason("password protected page"))
34
+ );
35
+
36
+ $isItemsInCart = !empty($_COOKIE["woocommerce_items_in_cart"]);
37
+ $nitro = get_nitropack_sdk();
38
+ $useAccountOverride = $nitro !== NULL && $nitro->isStatefulCacheSatisfied("account");
39
+ $useCartOverride = nitropack_is_cart_cache_active();
40
+
41
+ if ($isUserLoggedIn && !$useAccountOverride) {
42
+ get_nitropack()->setDisabledReason("logged in");
43
+ }
44
+
45
+ if ($isItemsInCart && !$useCartOverride) {
46
+ get_nitropack()->setDisabledReason("items in cart");
47
+ }
48
 
49
  // allow registering filters to "nitropack_passes_cookie_requirements"
50
+ return apply_filters("nitropack_passes_cookie_requirements", $safeCookie && (!$isItemsInCart || $useCartOverride) && (!$isUserLoggedIn || $useAccountOverride));
51
  }
52
 
53
  function nitropack_activate() {
398
  }
399
 
400
  function nitropack_handle_webhook() {
401
+ if (defined('NITROPACK_DEBUG_MODE')) {
402
+ do_action('nitropack_debug_webhook', $_REQUEST);
403
+ }
404
  if (!defined("NITROPACK_WEBHOOK_HANDLED")) {
405
  define("NITROPACK_WEBHOOK_HANDLED", 1);
406
  } else {
476
 
477
  function nitropack_is_amp_page() {
478
  return
479
+ (function_exists('amp_is_request') && amp_is_request() && !get_nitropack()->setDisabledReason("amp page")) ||
480
+ (function_exists('ampforwp_is_amp_endpoint') && ampforwp_is_amp_endpoint() && !get_nitropack()->setDisabledReason("amp page"));
481
  }
482
 
483
  function nitropack_passes_page_requirements($detectIfNoCachedResult = true) {
487
 
488
  if ($cachedResult === NULL && $detectIfNoCachedResult) {
489
  $cachedResult = !(
490
+ ( is_404() && !get_nitropack()->setDisabledReason("404") ) ||
491
+ ( is_preview() && !get_nitropack()->setDisabledReason("preview page") ) ||
492
+ ( is_feed() && !get_nitropack()->setDisabledReason("feed") ) ||
493
+ ( is_comment_feed() && !get_nitropack()->setDisabledReason("comment feed") ) ||
494
+ ( is_trackback() && !get_nitropack()->setDisabledReason("trackback") ) ||
495
+ ( is_user_logged_in() && !get_nitropack()->setDisabledReason("logged in") ) ||
496
+ ( is_search() && !get_nitropack()->setDisabledReason("search") ) ||
497
+ ( nitropack_is_ajax() && !get_nitropack()->setDisabledReason("ajax") ) ||
498
+ ( nitropack_is_post() && !get_nitropack()->setDisabledReason("post request") ) ||
499
+ ( nitropack_is_xmlrpc() && !get_nitropack()->setDisabledReason("xmlrpc") ) ||
500
+ ( nitropack_is_robots() && !get_nitropack()->setDisabledReason("robots") ) ||
501
  nitropack_is_amp_page() ||
502
  !nitropack_is_allowed_request() ||
503
+ ( nitropack_is_wp_cron() && !get_nitropack()->setDisabledReason("doing cron") ) || // CRON request
504
  ( nitropack_is_wp_cli() ) || // CLI request
505
+ ( defined('WC_PLUGIN_FILE') && (is_page( 'cart' ) || ( !$reduceCartChecks && is_cart()) ) && !get_nitropack()->setDisabledReason("cart page") ) || // WooCommerce
506
+ ( defined('WC_PLUGIN_FILE') && (is_page( 'checkout' ) || ( !$reduceCheckoutChecks && is_checkout()) ) && !get_nitropack()->setDisabledReason("checkout page") ) || // WooCommerce
507
+ ( defined('WC_PLUGIN_FILE') && is_account_page() && !get_nitropack()->setDisabledReason("account page") ) // WooCommerce
508
  );
509
  }
510
 
516
  }
517
 
518
  function nitropack_is_archive() {
519
+ return apply_filters("nitropack_is_archive_page", is_author() || is_archive());
520
  }
521
 
522
  function nitropack_is_allowed_request() {
525
  if (is_array($cacheableObjectTypes)) {
526
  if (nitropack_is_home()) {
527
  if (!in_array('home', $cacheableObjectTypes)) {
528
+ get_nitropack()->setDisabledReason("page type not allowed (home)");
529
  return false;
530
  }
531
  } else {
532
  if (is_tax() || is_category() || is_tag()) {
533
  $np_queriedObj = get_queried_object();
534
  if (!empty($np_queriedObj) && !in_array($np_queriedObj->taxonomy, $cacheableObjectTypes)) {
535
+ get_nitropack()->setDisabledReason("page type not allowed ({$np_queriedObj->taxonomy})");
536
  return false;
537
  }
538
  } else {
539
  if (nitropack_is_archive()) {
540
  if (!in_array('archive', $cacheableObjectTypes)) {
541
+ get_nitropack()->setDisabledReason("page type not allowed (archive)");
542
  return false;
543
  }
544
  } else {
545
  $postType = get_post_type();
546
  if (!empty($postType) && !in_array($postType, $cacheableObjectTypes)) {
547
+ get_nitropack()->setDisabledReason("page type not allowed ($postType)");
548
  return false;
549
  }
550
  }
554
 
555
  if (null !== $nitro = get_nitropack_sdk() ) {
556
  return
557
+ ( $nitro->isAllowedUrl($nitro->getUrl()) || get_nitropack()->setDisabledReason("url not allowed") ) &&
558
+ ( $nitro->isAllowedRequest(true) || get_nitropack()->setDisabledReason("request type not allowed") );
559
  }
560
 
561
+ get_nitropack()->setDisabledReason("site not connected");
562
  return false;
563
  }
564
 
658
  if (is_valid_nitropack_beacon()) {
659
  nitropack_handle_beacon();
660
  } else {
661
+ /* The following if statement should stay as it is written.
662
+ * is_archive() can return true if visiting a tax, category or tag page, so is_acrchive must be checked last
663
+ */
664
+ if (is_tax() || is_category() || is_tag()) {
665
+ $np_queriedObj = get_queried_object();
666
+ get_nitropack()->setPageType($np_queriedObj->taxonomy);
667
+ } else {
668
+ $layout = nitropack_get_layout();
669
+ get_nitropack()->setPageType($layout);
670
+ }
671
+
672
+ add_action('wp_footer', 'nitropack_print_element_override', 9999999);
673
  if (!isset($_GET["wpf_action"]) && nitropack_passes_cookie_requirements() && nitropack_passes_page_requirements()) {
674
  add_action('wp_footer', 'nitropack_print_beacon_script');
675
  add_action('get_footer', 'nitropack_print_beacon_script');
687
  nitropack_set_custom_expiration();
688
  }
689
 
690
+ $GLOBALS["NitroPack.tags"]["pageType:" . get_nitropack()->getPageType()] = 1;
691
 
692
  /* The following if statement should stay as it is written.
693
  * is_archive() can return true if visiting a tax, category or tag page, so is_acrchive must be checked last
694
  */
695
  if (is_tax() || is_category() || is_tag()) {
696
  $np_queriedObj = get_queried_object();
 
697
  $GLOBALS["NitroPack.tags"]["tax:" . $np_queriedObj->term_taxonomy_id] = 1;
698
  } else {
 
699
  if (is_single() || is_page() || is_attachment()) {
700
  $singlePost = get_post();
701
  if ($singlePost) {
861
  function nitropack_print_telemetry_script() {
862
  if (defined("NITROPACK_TELEMETRY_PRINTED")) return;
863
  define("NITROPACK_TELEMETRY_PRINTED", true);
864
+ echo apply_filters("nitro_script_output", nitropack_get_telemetry_meta());
865
  echo apply_filters("nitro_script_output", nitropack_get_telemetry_script());
866
  }
867
 
879
  return "";
880
  }
881
 
882
+ function nitropack_get_telemetry_meta() {
883
+ $disabledReason = get_nitropack()->getDisabledReason();
884
+ $missReason = $disabledReason !== NULL ? $disabledReason : "cache not found";
885
+ $pageType = get_nitropack()->getPageType();
886
+ $metaObj = "window.NPTelemetryMetadata={";
887
+
888
+ if ($missReason) {
889
+ $metaObj .= "missReason: (!window.NITROPACK_STATE ? '$missReason' : 'hit'),";
890
+ }
891
+
892
+ if ($pageType) {
893
+ $metaObj .= "pageType: '$pageType',";
894
+ }
895
+
896
+ $metaObj .= "}";
897
+
898
+ return "<script id='nitro-telemetry-meta' nitro-exclude>$metaObj</script>";
899
+ }
900
+
901
+ function nitropack_print_element_override() {
902
+ return;
903
+ if (defined("NITROPACK_ELEMENT_OVERRIDE_PRINTED")) return;
904
+ define("NITROPACK_ELEMENT_OVERRIDE_PRINTED", true);
905
+ echo apply_filters("nitro_script_output", nitropack_get_element_override_script());
906
+ }
907
+
908
+ function nitropack_get_element_override_script() {
909
+ $nitro = get_nitropack_sdk();
910
+ return $nitro !== NULL ? $nitro->getStatefulCacheHandlerScript() : "";
911
+ }
912
+
913
  function nitropack_has_advanced_cache() {
914
  return defined( 'NITROPACK_ADVANCED_CACHE' );
915
  }
2377
  update_option("nitropack-autoCachePurge", (int)$autoCachePurgeStatus);
2378
  }
2379
 
2380
+ function nitropack_set_cart_cache_ajax() {
2381
+ if (get_nitropack()->isConnected() && nitropack_render_woocommerce_cart_cache_option()) {
2382
+ $cartCacheStatus = (int) (!empty($_POST["cartCacheStatus"]));
2383
+
2384
+ if ($cartCacheStatus == 1) {
2385
+ nitropack_enable_cart_cache();
2386
+ } else {
2387
+ nitropack_disable_cart_cache();
2388
+ }
2389
+ }
2390
+
2391
+ nitropack_json_and_exit(array(
2392
+ "type" => "error",
2393
+ "message" => "Error! There was an error while updating cart cache!"
2394
+ ));
2395
+ }
2396
+
2397
  function nitropack_set_bb_cache_purge_sync_ajax() {
2398
  $bbCacheSyncPurgeStatus = !empty($_POST["bbCachePurgeSyncStatus"]);
2399
  update_option("nitropack-bbCacheSyncPurge", (int)$bbCacheSyncPurgeStatus);
2444
  nitropack_json_and_exit(array("status" => "success", "hasCompression" => $hasCompression));
2445
  }
2446
 
2447
+ function nitropack_render_woocommerce_cart_cache_option() {
2448
+ return class_exists('WooCommerce');
2449
+ }
2450
+
2451
+ function nitropack_is_cart_cache_active() {
2452
+ $nitro = get_nitropack()->getSdk();
2453
+ if ($nitro) {
2454
+ $config = $nitro->getConfig();
2455
+ if (!empty($config->StatefulCache->Status) && !empty($config->StatefulCache->CartCache)) {
2456
+ return nitropack_is_cart_cache_available();
2457
+ }
2458
+ }
2459
+ return false;
2460
+ }
2461
+
2462
+ function nitropack_is_cart_cache_available() {
2463
+ $nitro = get_nitropack()->getSdk();
2464
+ if ($nitro) {
2465
+ $config = $nitro->getConfig();
2466
+ if (!empty($config->StatefulCache->isCartCacheAvailable)) {
2467
+ return true;
2468
+ }
2469
+ }
2470
+ return false;
2471
+ }
2472
+
2473
  function nitropack_handle_compression_toggle($old_value, $new_value) {
2474
  nitropack_update_blog_compression($new_value == 1);
2475
  }
2641
  ));
2642
  }
2643
 
2644
+ function nitropack_enable_cart_cache() {
2645
+ if (null !== $nitro = get_nitropack_sdk()) {
2646
+ try {
2647
+ $nitro->enableCartCache();
2648
+
2649
+ nitropack_json_and_exit(array(
2650
+ "type" => "success",
2651
+ "message" => "Success! Cart cache has been enabled successfully!"
2652
+ ));
2653
+ } catch (\Exception $e) {
2654
+ }
2655
+ }
2656
+
2657
+ nitropack_json_and_exit(array(
2658
+ "type" => "error",
2659
+ "message" => "Error! There was an error while enabling cart cache!"
2660
+ ));
2661
+ }
2662
+
2663
+ function nitropack_disable_cart_cache() {
2664
+ if (null !== $nitro = get_nitropack_sdk()) {
2665
+ try {
2666
+ $nitro->disableCartCache();
2667
+
2668
+ nitropack_json_and_exit(array(
2669
+ "type" => "success",
2670
+ "message" => "Success! Cart cache has been disabled successfully!"
2671
+ ));
2672
+ } catch (\Exception $e) {
2673
+ }
2674
+ }
2675
+
2676
+ nitropack_json_and_exit(array(
2677
+ "type" => "error",
2678
+ "message" => "Error! There was an error while disabling cart cache!"
2679
+ ));
2680
+ }
2681
+
2682
  function nitropack_safemode_status() {
2683
  if (null !== $nitro = get_nitropack_sdk()) {
2684
  try {
2727
  try {
2728
  $eventUrl = get_nitropack_integration_url("extensionEvent", $nitro);
2729
  $domain = !empty($_SERVER["HTTP_HOST"]) ? $_SERVER["HTTP_HOST"] : "Unknown";
2730
+
2731
+ if (class_exists('WooCommerce')) {
2732
+ $platform = 'WooCommerce';
2733
+ } else {
2734
+ $platform = 'WordPress';
2735
+ }
2736
 
2737
  $query_data = array(
2738
  'event' => $event,
2739
+ 'platform' => $platform,
2740
  'platform_version' => $wp_version,
2741
  'nitropack_extension_version' => NITROPACK_VERSION,
2742
  'additional_meta_data' => $additional_meta_data ? json_encode($additional_meta_data) : "{}",
3270
  }
3271
  }
3272
  }
3273
+
3274
+ if (apply_filters('nitropack_should_modify_htaccess', false) && (empty($_SERVER["NitroPackHtaccessVersion"]) || NITROPACK_VERSION != $_SERVER["NitroPackHtaccessVersion"])) {
3275
+ if (!nitropack_set_htaccess_rules(true)) {
3276
+ $errors[] = "The .htaccess file cannot be modified. Please make sure that it is writable and refresh this page.";
3277
+ }
3278
+ }
3279
  }
3280
 
3281
  if (!empty($_COOKIE["nitropack_upgrade_to_1_3_notice"])) {
main.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: NitroPack
4
  Plugin URI: https://nitropack.io/platform/wordpress
5
  Description: Everything you need for a fast website. Simple set up, easy to use, awesome support. Caching, Lazy Loading, Minification, Defer CSS/JS, CDN and more!
6
- Version: 1.5.16
7
  Author: NitroPack LLC
8
  Author URI: https://nitropack.io/
9
  License: GPL2
@@ -99,6 +99,7 @@ if ( is_admin() ) {
99
  add_action( 'wp_ajax_nitropack_test_compression_ajax', 'nitropack_test_compression_ajax' );
100
  add_action( 'wp_ajax_nitropack_set_compression_ajax', 'nitropack_set_compression_ajax' );
101
  add_action( 'wp_ajax_nitropack_set_auto_cache_purge_ajax', 'nitropack_set_auto_cache_purge_ajax' );
 
102
  add_action( 'wp_ajax_nitropack_set_bb_cache_purge_sync_ajax', 'nitropack_set_bb_cache_purge_sync_ajax' );
103
  add_action( 'wp_ajax_nitropack_set_cacheable_post_types', 'nitropack_set_cacheable_post_types' );
104
  add_action( 'wp_ajax_nitropack_enable_warmup', 'nitropack_enable_warmup' );
3
  Plugin Name: NitroPack
4
  Plugin URI: https://nitropack.io/platform/wordpress
5
  Description: Everything you need for a fast website. Simple set up, easy to use, awesome support. Caching, Lazy Loading, Minification, Defer CSS/JS, CDN and more!
6
+ Version: 1.5.17
7
  Author: NitroPack LLC
8
  Author URI: https://nitropack.io/
9
  License: GPL2
99
  add_action( 'wp_ajax_nitropack_test_compression_ajax', 'nitropack_test_compression_ajax' );
100
  add_action( 'wp_ajax_nitropack_set_compression_ajax', 'nitropack_set_compression_ajax' );
101
  add_action( 'wp_ajax_nitropack_set_auto_cache_purge_ajax', 'nitropack_set_auto_cache_purge_ajax' );
102
+ add_action( 'wp_ajax_nitropack_set_cart_cache_ajax', 'nitropack_set_cart_cache_ajax' );
103
  add_action( 'wp_ajax_nitropack_set_bb_cache_purge_sync_ajax', 'nitropack_set_bb_cache_purge_sync_ajax' );
104
  add_action( 'wp_ajax_nitropack_set_cacheable_post_types', 'nitropack_set_cacheable_post_types' );
105
  add_action( 'wp_ajax_nitropack_enable_warmup', 'nitropack_enable_warmup' );
nitropack-sdk/NitroPack/SDK/Api.php CHANGED
@@ -277,4 +277,12 @@ class Api {
277
  $status = $this->safe_mode->status();
278
  return !empty($status->isEnabled);
279
  }
 
 
 
 
 
 
 
 
280
  }
277
  $status = $this->safe_mode->status();
278
  return !empty($status->isEnabled);
279
  }
280
+
281
+ public function enableCartCache() {
282
+ $this->cache->enableCartCache();
283
+ }
284
+
285
+ public function disableCartCache() {
286
+ $this->cache->disableCartCache();
287
+ }
288
  }
nitropack-sdk/NitroPack/SDK/Api/Cache.php CHANGED
@@ -220,6 +220,34 @@ class Cache extends SignedBase {
220
  return array();
221
  }
222
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
223
  private function isCacheWarmupRequest() {
224
  return isset($_SERVER['HTTP_X_NITRO_WARMUP']);
225
  }
220
  return array();
221
  }
222
 
223
+ public function enableCartCache() {
224
+ $path = 'cache/enablecartcache/' . $this->siteId;
225
+
226
+ $httpResponse = $this->makeRequest($path, array(), array(), 'POST');
227
+
228
+ $status = ResponseStatus::getStatus($httpResponse->getStatusCode());
229
+ switch ($status) {
230
+ case ResponseStatus::OK:
231
+ return true;
232
+ default:
233
+ $this->throwException($httpResponse, 'Error while enabling cart cache: %s');
234
+ }
235
+ }
236
+
237
+ public function disableCartCache() {
238
+ $path = 'cache/disablecartcache/' . $this->siteId;
239
+
240
+ $httpResponse = $this->makeRequest($path, array(), array(), 'POST');
241
+
242
+ $status = ResponseStatus::getStatus($httpResponse->getStatusCode());
243
+ switch ($status) {
244
+ case ResponseStatus::OK:
245
+ return true;
246
+ default:
247
+ $this->throwException($httpResponse, 'Error while disabling cart cache: %s');
248
+ }
249
+ }
250
+
251
  private function isCacheWarmupRequest() {
252
  return isset($_SERVER['HTTP_X_NITRO_WARMUP']);
253
  }
nitropack-sdk/NitroPack/SDK/ElementRevision.php ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace NitroPack\SDK;
3
+
4
+ /**
5
+ * Class Revision
6
+ * @package NitroPack\WordPress
7
+ */
8
+ class ElementRevision
9
+ {
10
+ private $siteId;
11
+ private $revisionFile;
12
+
13
+ private $revisions;
14
+
15
+ /**
16
+ * Revision constructor.
17
+ * @param $siteId
18
+ * @param $dataDir
19
+ */
20
+ public function __construct($siteId, $revisionFile) {
21
+ $this->siteId = $siteId;
22
+ $this->revisionFile = $revisionFile;
23
+ $this->revisions = [];
24
+ }
25
+
26
+ /**
27
+ * @return string
28
+ */
29
+ public function get() {
30
+ if (empty($this->revisions)) {
31
+ $this->load();
32
+ }
33
+
34
+ if (!empty($this->revisions[$this->siteId])) {
35
+ return $this->revisions[$this->siteId];
36
+ }
37
+
38
+ $this->save("nitro-" . substr(md5(microtime(true)), 0, 7));
39
+
40
+ return $this->revisions[$this->siteId];
41
+ }
42
+
43
+ public function refresh() {
44
+ $this->save('');
45
+ }
46
+
47
+ private function load() {
48
+ try {
49
+ if (Filesystem::fileExists($this->revisionFile)) {
50
+ $this->revisions = json_decode(Filesystem::fileGetContents($this->revisionFile), true);
51
+ } else {
52
+ $this->revisions = [];
53
+ }
54
+ } catch (\Exception $e) {
55
+ $this->revisions = [];
56
+ }
57
+ }
58
+
59
+ /**
60
+ * @param string $revision
61
+ */
62
+ private function save($revision) {
63
+ $this->revisions[$this->siteId] = $revision;
64
+ try {
65
+ Filesystem::filePutContents($this->revisionFile, json_encode($this->revisions));
66
+ } catch (\Exception $e) {
67
+ }
68
+ }
69
+ }
nitropack-sdk/NitroPack/SDK/NitroPack.php CHANGED
@@ -10,6 +10,7 @@ class NitroPack {
10
  private $healthStatusFile = array('data', 'service-health');
11
  private $timestampFile = array('data', 'time.mark');
12
  private $pageCacheLockFile = array('data', 'get_cache.lock');
 
13
  private $cachePathSuffix = NULL;
14
  private $configTTL; // In seconds
15
 
@@ -23,6 +24,7 @@ class NitroPack {
23
  private $api;
24
 
25
  public $backlog;
 
26
  public $healthStatus;
27
  public $pageCache; // TODO: consider better ways of protecting/providing this outside the class
28
 
@@ -102,6 +104,7 @@ class NitroPack {
102
  $this->siteSecret = $siteSecret;
103
  $this->dataDir = $dataDir;
104
  $this->backlog = new Backlog($dataDir, $this);
 
105
  $this->healthStatus = HealthStatus::HEALTHY;
106
  $this->loadHealthStatus();
107
 
@@ -227,6 +230,12 @@ class NitroPack {
227
  return Filesystem::getOsPath($cachePath);
228
  }
229
 
 
 
 
 
 
 
230
  public function getHealthStatus() {
231
  return $this->healthStatus;
232
  }
@@ -471,6 +480,8 @@ class NitroPack {
471
 
472
  $localResult = true; // We do not care if $staleCacheDir was not deleted successfully
473
  }
 
 
474
  }
475
 
476
  $this->unlockPageCache(); // Purge cache is done, we can now unlock
@@ -511,6 +522,8 @@ class NitroPack {
511
  Filesystem::deleteDir($staleCacheDir);
512
  }
513
 
 
 
514
  return $staleCacheDir;
515
  }
516
 
@@ -712,6 +725,30 @@ class NitroPack {
712
  return $this->isAllowedRequest() && $this->isAllowedUrl($this->url);
713
  }
714
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
715
  public function purgeLocalUrlCache($url) {
716
  $url = $this->normalizeUrl($url);
717
  $this->purgeProxyCache($url);
@@ -795,6 +832,23 @@ class NitroPack {
795
  $this->fetchConfig();
796
  }
797
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
798
  private function loadConfig() {
799
  $file = $this->getConfigFile();
800
 
10
  private $healthStatusFile = array('data', 'service-health');
11
  private $timestampFile = array('data', 'time.mark');
12
  private $pageCacheLockFile = array('data', 'get_cache.lock');
13
+ private $statefulCacheRevisionsFile = array('data', 'element-revision.json');
14
  private $cachePathSuffix = NULL;
15
  private $configTTL; // In seconds
16
 
24
  private $api;
25
 
26
  public $backlog;
27
+ public $elementRevision;
28
  public $healthStatus;
29
  public $pageCache; // TODO: consider better ways of protecting/providing this outside the class
30
 
104
  $this->siteSecret = $siteSecret;
105
  $this->dataDir = $dataDir;
106
  $this->backlog = new Backlog($dataDir, $this);
107
+ $this->elementRevision = new ElementRevision($siteId, $this->getStatefulCacheRevisionFile());
108
  $this->healthStatus = HealthStatus::HEALTHY;
109
  $this->loadHealthStatus();
110
 
230
  return Filesystem::getOsPath($cachePath);
231
  }
232
 
233
+ public function getStatefulCacheRevisionFile() {
234
+ $revisionFile = $this->statefulCacheRevisionsFile;
235
+ array_unshift($revisionFile, $this->dataDir);
236
+ return Filesystem::getOsPath($revisionFile);
237
+ }
238
+
239
  public function getHealthStatus() {
240
  return $this->healthStatus;
241
  }
480
 
481
  $localResult = true; // We do not care if $staleCacheDir was not deleted successfully
482
  }
483
+
484
+ $this->elementRevision->refresh();
485
  }
486
 
487
  $this->unlockPageCache(); // Purge cache is done, we can now unlock
522
  Filesystem::deleteDir($staleCacheDir);
523
  }
524
 
525
+ $this->elementRevision->refresh();
526
+
527
  return $staleCacheDir;
528
  }
529
 
725
  return $this->isAllowedRequest() && $this->isAllowedUrl($this->url);
726
  }
727
 
728
+ public function isStatefulCacheSatisfied($type = NULL) {
729
+ if ($this->config->StatefulCache->Status) {
730
+ $foundTypeSelectors = false;
731
+ foreach ($this->config->StatefulCache->Selectors as $selector) {
732
+ if ($type !== NULL) {
733
+ if ($selector->type === $type) {
734
+ $foundTypeSelectors = true;
735
+ } else {
736
+ continue;
737
+ }
738
+ }
739
+
740
+ $cookieKey = 'np-' . $selector->type . '-' . base64_encode($selector->string) . '-override';
741
+ if (empty($_COOKIE[$cookieKey]) || $_COOKIE[$cookieKey] != $this->elementRevision->get()) {
742
+ return false;
743
+ }
744
+ }
745
+
746
+ return $type !== NULL ? $foundTypeSelectors : true;
747
+ }
748
+
749
+ return false;
750
+ }
751
+
752
  public function purgeLocalUrlCache($url) {
753
  $url = $this->normalizeUrl($url);
754
  $this->purgeProxyCache($url);
832
  $this->fetchConfig();
833
  }
834
 
835
+ public function enableCartCache() {
836
+ $this->api->enableCartCache();
837
+ }
838
+
839
+ public function disableCartCache() {
840
+ $this->api->disableCartCache();
841
+ }
842
+
843
+ public function getStatefulCacheHandlerScript() {
844
+ if ($this->config->StatefulCache->Status && $this->config->StatefulCache->HandlerScript) {
845
+ $keyRevision = $this->elementRevision->get();
846
+ return '<script id="nitro-stateful-cache" nitro-exclude>' . str_replace("KEY_REVISION", $keyRevision, $this->config->StatefulCache->HandlerScript) . '</script>';
847
+ }
848
+
849
+ return "";
850
+ }
851
+
852
  private function loadConfig() {
853
  $file = $this->getConfigFile();
854
 
readme.txt CHANGED
@@ -4,7 +4,7 @@ Tags: cache,perfomance,optimize,pagespeed,lazy load,cdn,critical css,compression
4
  Requires at least: 4.7
5
  Tested up to: 6.0.2
6
  Requires PHP: 5.6
7
- Stable tag: 1.5.16
8
  License: GNU General Public License, version 2
9
  License URI: https://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -169,6 +169,11 @@ No. We’ve designed NitroPack to be a very lightweight solution that adds no CP
169
 
170
  == Changelog ==
171
 
 
 
 
 
 
172
  = 1.5.16 =
173
  * Improvement: Update the compatibility with SiteGround's Dynamic Cache layer
174
  * Bug fix: Resolve cache bypass issues on LiteSpeed
4
  Requires at least: 4.7
5
  Tested up to: 6.0.2
6
  Requires PHP: 5.6
7
+ Stable tag: 1.5.17
8
  License: GNU General Public License, version 2
9
  License URI: https://www.gnu.org/licenses/gpl-2.0.html
10
 
169
 
170
  == Changelog ==
171
 
172
+ = 1.5.17 =
173
+ * Feature: Introduce a new features "Ecommerce Cart Cache" for WooCommerce sites
174
+ * Improvement: Add new filter "nitropack_is_archive_page"
175
+ * Improvement: Overall stability improvements
176
+
177
  = 1.5.16 =
178
  * Improvement: Update the compatibility with SiteGround's Dynamic Cache layer
179
  * Bug fix: Resolve cache bypass issues on LiteSpeed
view/dashboard.php CHANGED
@@ -162,6 +162,19 @@
162
  </label>
163
  </span>
164
  </li>
 
 
 
 
 
 
 
 
 
 
 
 
 
165
  <li class="list-group-item px-0 d-flex justify-content-between align-items-center">
166
  <span>
167
  <a href="javascript:void(0);" class="btn btn-danger text-white" id="disconnect-btn"><i class="fa fa-power-off text-white"></i>&nbsp;&nbsp;Disconnect</a>
@@ -653,6 +666,20 @@
653
  });
654
  });
655
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
656
  $("#bb-purge-status").on("click", function(e) {
657
  $.post(ajaxurl, {
658
  action: 'nitropack_set_bb_cache_purge_sync_ajax',
162
  </label>
163
  </span>
164
  </li>
165
+ <?php if (nitropack_render_woocommerce_cart_cache_option()) { ?>
166
+ <li class="list-group-item px-0 d-flex justify-content-between align-items-center">
167
+ <span>Ecommerce Cart Cache&nbsp;&nbsp;<span class="badge badge-info"><?php echo nitropack_is_cart_cache_available() ? 'New' : '<a href="https://nitropack.io/pricing" target="_blank" rel="noopener noreferrer" class="text-white">Requires a paid subscription</a>'; ?></span></br>
168
+ <small>Your visitors will enjoy full site speed while browsing with items in cart. Fully optimized page cache will be served.</small>
169
+ </span>
170
+ <span id="cart-cache-toggle">
171
+ <label class="switch" id="cart-cache-status-slider">
172
+ <input type="checkbox" id="cart-cache-status" <?php if (nitropack_is_cart_cache_active()) echo "checked"; ?> <?php if (!nitropack_is_cart_cache_available()) echo "disabled"; ?>>
173
+ <span class="slider"></span>
174
+ </label>
175
+ </span>
176
+ </li>
177
+ <?php } ?>
178
  <li class="list-group-item px-0 d-flex justify-content-between align-items-center">
179
  <span>
180
  <a href="javascript:void(0);" class="btn btn-danger text-white" id="disconnect-btn"><i class="fa fa-power-off text-white"></i>&nbsp;&nbsp;Disconnect</a>
666
  });
667
  });
668
 
669
+ $("#cart-cache-status").on("click", function(e) {
670
+ $.post(ajaxurl, {
671
+ action: 'nitropack_set_cart_cache_ajax',
672
+ cartCacheStatus: $(this).is(":checked") ? 1 : 0
673
+ }, function(response) {
674
+ var resp = JSON.parse(response);
675
+ if (resp.type == "success") {
676
+ Notification.success(resp.message);
677
+ } else {
678
+ Notification.error(resp.message);
679
+ }
680
+ });
681
+ });
682
+
683
  $("#bb-purge-status").on("click", function(e) {
684
  $.post(ajaxurl, {
685
  action: 'nitropack_set_bb_cache_purge_sync_ajax',