NitroPack - Version 1.5.8

Version Description

  • New Feature: Compatibility with Savii hosting
  • New Feature: Basic compatibility with Pressable's caching layer
  • New Feature: Basic compatibility with Sucuri as a caching layer
  • New Feature: Admins can now receive notifications related to system events
  • Improvement: Improved compatibility with Cloudflare's APO
  • Improvement: Improved compatibility with Rocket.net
  • Improvement: Overall stability/compatibility improvements
  • Improvement: A better way to detect the popular Cookie Notice plugin
  • Improvement: Compatibility with WP Engine's Smart Plugin Updater
  • Bug fix: Resolve an issue when running on PHP 5.6
Download this release

Release Info

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

Code changes from version 1.5.7 to 1.5.8

Files changed (46) hide show
  1. batcache-compat.php +6 -0
  2. classes/Integration.php +5 -1
  3. classes/Integration/Hosting/Cloudways.php +4 -1
  4. classes/Integration/Hosting/Pressable.php +113 -0
  5. classes/Integration/Hosting/RocketNet.php +27 -0
  6. classes/Integration/Hosting/Savvii.php +65 -0
  7. classes/Integration/Hosting/SiteGround.php +1 -0
  8. classes/Integration/Hosting/WPEngine.php +6 -0
  9. classes/Integration/Plugin/Cloudflare.php +11 -3
  10. classes/Integration/Plugin/CookieNotice.php +1 -2
  11. classes/Integration/Plugin/RocketNet_Helper.php +15 -0
  12. classes/Integration/Server/Cloudflare.php +9 -4
  13. classes/Integration/Server/Sucuri.php +40 -0
  14. classes/WordPress/Config.php +36 -0
  15. classes/WordPress/NitroPack.php +178 -0
  16. classes/WordPress/Notifications.php +74 -0
  17. constants.php +10 -2
  18. functions.php +132 -202
  19. main.php +8 -4
  20. nitropack-sdk/NitroPack/SDK/Api/RemoteConfigFetcher.php +4 -4
  21. nitropack-sdk/NitroPack/SDK/ChallengeProcessingException.php +4 -0
  22. nitropack-sdk/NitroPack/SDK/ChallengeVerificationException.php +4 -0
  23. nitropack-sdk/NitroPack/SDK/ConfigFetcherException.php +4 -0
  24. nitropack-sdk/NitroPack/SDK/NitroPack.php +5 -1
  25. nitropack-sdk/NitroPack/SDK/Pagecache.php +30 -0
  26. nitropack-sdk/bootstrap.php +6 -1
  27. nitropack-sdk/vendor/autoload.php +1 -1
  28. nitropack-sdk/vendor/composer/ClassLoader.php +142 -15
  29. nitropack-sdk/vendor/composer/InstalledVersions.php +340 -229
  30. nitropack-sdk/vendor/composer/autoload_classmap.php +1 -0
  31. nitropack-sdk/vendor/composer/autoload_psr4.php +1 -1
  32. nitropack-sdk/vendor/composer/autoload_real.php +6 -6
  33. nitropack-sdk/vendor/composer/autoload_static.php +10 -5
  34. nitropack-sdk/vendor/composer/installed.json +72 -64
  35. nitropack-sdk/vendor/composer/installed.php +42 -41
  36. nitropack-sdk/vendor/nitropack/httpclient/src/HttpClient.php +158 -31
  37. nitropack-sdk/vendor/nitropack/httpclient/src/HttpClientMulti.php +36 -2
  38. nitropack-sdk/vendor/nitropack/httpclient/src/HttpClientProxy.php +26 -0
  39. nitropack-sdk/vendor/nitropack/httpclient/src/HttpClientSocks4Proxy.php +100 -0
  40. nitropack-sdk/vendor/nitropack/httpclient/src/HttpClientSocksProxy.php +4 -0
  41. nitropack-sdk/vendor/nitropack/httpclient/src/HttpConfig.php +20 -0
  42. nitropack-sdk/vendor/nitropack/httpclient/src/ProxyConnectException.php +4 -0
  43. readme.txt +14 -2
  44. view/dashboard.php +130 -73
  45. view/javascript/admin_bar_menu.js +1 -1
  46. view/javascript/np_notices.js +10 -1
batcache-compat.php ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
1
+ <?php
2
+ define("NITROPACK_BATCACHE_COMPAT", true);
3
+ $batcache["unique"][] = !empty($_SERVER["HTTP_USER_AGENT"]) && preg_match("/(Android|Mobile|iPod|iPhone|MobileSafari|webOS|BlackBerry|windows phone|symbian|vodafone|opera mini|windows ce|smartphone|palm|midp)/i", $_SERVER["HTTP_USER_AGENT"]) ? "mobile" : "desktop";
4
+ $batcache["cache_control"] = false;
5
+ $batcache["use_stale"] = false;
6
+ $batcache["times"] = 1;
classes/Integration.php CHANGED
@@ -21,15 +21,19 @@ class Integration {
21
  "NitroPack/Integration/Hosting/Kinsta",
22
  "NitroPack/Integration/Hosting/Pagely",
23
  "NitroPack/Integration/Hosting/Vimexx",
 
 
 
24
  "NitroPack/Integration/Server/LiteSpeed",
25
  "NitroPack/Integration/Server/Fastly",
26
  "NitroPack/Integration/Server/Cloudflare",
 
27
  "NitroPack/Integration/Plugin/NginxHelper",
28
  "NitroPack/Integration/Plugin/Cloudflare",
29
  "NitroPack/Integration/Plugin/ShortPixel",
30
  "NitroPack/Integration/Plugin/WPCacheHelper",
31
  "NitroPack/Integration/Plugin/CookieNotice",
32
- "NitroPack/Integration/Plugin/BeaverBuilder"
33
  ];
34
  private static $loadedModules = [];
35
  private static $stage = "very_early";
21
  "NitroPack/Integration/Hosting/Kinsta",
22
  "NitroPack/Integration/Hosting/Pagely",
23
  "NitroPack/Integration/Hosting/Vimexx",
24
+ "NitroPack/Integration/Hosting/Pressable",
25
+ "NitroPack/Integration/Hosting/RocketNet",
26
+ "NitroPack/Integration/Hosting/Savvii",
27
  "NitroPack/Integration/Server/LiteSpeed",
28
  "NitroPack/Integration/Server/Fastly",
29
  "NitroPack/Integration/Server/Cloudflare",
30
+ "NitroPack/Integration/Server/Sucuri",
31
  "NitroPack/Integration/Plugin/NginxHelper",
32
  "NitroPack/Integration/Plugin/Cloudflare",
33
  "NitroPack/Integration/Plugin/ShortPixel",
34
  "NitroPack/Integration/Plugin/WPCacheHelper",
35
  "NitroPack/Integration/Plugin/CookieNotice",
36
+ "NitroPack/Integration/Plugin/BeaverBuilder",
37
  ];
38
  private static $loadedModules = [];
39
  private static $stage = "very_early";
classes/Integration/Hosting/Cloudways.php CHANGED
@@ -30,7 +30,10 @@ class Cloudways extends Hosting {
30
 
31
  public function purgeAll() {
32
  try {
33
- $homepage = home_url().'/.*';
 
 
 
34
  $purger = new \NitroPack\SDK\Integrations\Varnish(array("127.0.0.1"), "PURGE");
35
  $purger->purge($homepage);
36
  } catch (\Exception $e) {
30
 
31
  public function purgeAll() {
32
  try {
33
+ $siteConfig = nitropack_get_site_config();
34
+ if(!empty($siteConfig['home_url'])) {
35
+ $homepage = nitropack_trailingslashit($siteConfig['home_url']) . '.*';
36
+ }
37
  $purger = new \NitroPack\SDK\Integrations\Varnish(array("127.0.0.1"), "PURGE");
38
  $purger->purge($homepage);
39
  } catch (\Exception $e) {
classes/Integration/Hosting/Pressable.php ADDED
@@ -0,0 +1,113 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace NitroPack\Integration\Hosting;
4
+
5
+ class Pressable extends Hosting {
6
+ const STAGE = "very_early";
7
+ private $deviceTypes = ["mobile", "tablet", "desktop"];
8
+ private $configuredCacheGroups = false;
9
+
10
+ public static function detect() {
11
+ return isset($_SERVER["PRESSABLE_PROXIED_REQUEST"]) || strpos(gethostname(), "atomicsites.net") !== false;
12
+ }
13
+
14
+ public function init($stage) {
15
+ if ($this->getHosting() == "pressable") {
16
+ switch ($stage) {
17
+ case "very_early":
18
+ $this->noCache();
19
+ add_action('nitropack_cacheable_cache_headers', [$this, 'cacheShort']);
20
+ add_action('nitropack_cachehit_cache_headers', [$this, 'cacheLong']);
21
+ \NitroPack\Integration::initSemAcquire();
22
+ return true;
23
+ case "early":
24
+ \NitroPack\Integration::initSemRelease();
25
+ add_action('nitropack_execute_purge_url', [$this, 'purgeUrl']);
26
+ add_action('nitropack_execute_purge_all', [$this, 'purgeAll']);
27
+ return;
28
+ default:
29
+ return;
30
+ }
31
+ }
32
+ }
33
+
34
+ public function noCache() {
35
+ global $batcache;
36
+
37
+ if (!empty($batcache)) {
38
+ $batcache->max_age = 0;
39
+ }
40
+ }
41
+
42
+ public function cacheShort() {
43
+ global $batcache;
44
+
45
+ if (!empty($batcache)) {
46
+ $batcache->max_age = 30;
47
+ }
48
+ }
49
+
50
+ public function cacheLong() {
51
+ $this->cacheShort();
52
+ // Purging single cache files doesn't work yet, so we still cannot afford long cache times
53
+ //global $batcache;
54
+
55
+ //if (!empty($batcache)) {
56
+ // $batcache->max_age = 300;
57
+ //}
58
+ }
59
+
60
+ public function purgeUrl($url) {
61
+ global $batcache, $wp_object_cache;
62
+
63
+ if (!$batcache) return;
64
+
65
+ if (!$wp_object_cache) {
66
+ wp_cache_init();
67
+ }
68
+
69
+ /* This doesn't look to be needed based on dumps of the wp_object_cache object
70
+ if (!$this->configuredCacheGroups) {
71
+ $batcache->configure_groups();
72
+ $this->configuredCacheGroups = true;
73
+ }*/
74
+
75
+ $urlObj = new \NitroPack\Url($url);
76
+ if ($urlObj->getHost()) {
77
+ parse_str($urlObj->getQuery(), $query);
78
+
79
+ foreach ($batcache->ignored_query_args as $arg) {
80
+ unset($query[$arg]);
81
+ }
82
+ ksort($query);
83
+
84
+ $keys = array(
85
+ 'host' => $urlObj->getHost(),
86
+ 'method' => "GET",
87
+ 'path' => $urlObj->getPath(),
88
+ 'query' => $query,
89
+ 'extra' => []
90
+ );
91
+
92
+ if ( isset( $batcache->origin ) ) {
93
+ $keys['origin'] = $batcache->origin;
94
+ }
95
+
96
+ if ( $urlObj->getScheme() == "https" )
97
+ $keys['ssl'] = true;
98
+
99
+ foreach ($this->deviceTypes as $deviceType) {
100
+ $keys["extra"] = [$deviceType];
101
+ $url_key = md5(serialize($keys));
102
+
103
+ // The $url_key matches the key which batcache used to cache the page, but for some reason this doesn't delete the cache here
104
+ wp_cache_delete( $url_key, $batcache->group );
105
+ }
106
+ }
107
+ }
108
+
109
+ public function purgeAll() {
110
+ wp_cache_flush();
111
+ }
112
+ }
113
+
classes/Integration/Hosting/RocketNet.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace NitroPack\Integration\Hosting;
4
+
5
+ class RocketNet extends Hosting {
6
+ const STAGE = "early";
7
+
8
+ public static function detect() {
9
+ return defined("ROCKET_SITE_ID") || strpos(gethostname(), "onrocket.com") !== false;
10
+ }
11
+
12
+ public function init($stage) {
13
+ if ($this->getHosting() == "rocketnet" && class_exists("\Rocket_Wordpress")) {
14
+ add_action('nitropack_execute_purge_url', [$this, 'purgeUrl']);
15
+ add_action('nitropack_execute_purge_all', [$this, 'purgeAll']);
16
+ }
17
+ }
18
+
19
+ public function purgeUrl($url) {
20
+ \NitroPack\Integration\Plugin\RocketNet_Helper::purgeUrl($url);
21
+ }
22
+
23
+ public function purgeAll() {
24
+ \Rocket_Wordpress::purge_cache();
25
+ }
26
+ }
27
+
classes/Integration/Hosting/Savvii.php ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace NitroPack\Integration\Hosting;
4
+
5
+ class Savvii extends Hosting
6
+ {
7
+ const STAGE = "very_early";
8
+
9
+ public static function detect()
10
+ {
11
+ return isset($_SERVER['WARPDRIVE_API']) && $_SERVER['WARPDRIVE_API'] == 'https://api.savvii.services';
12
+ }
13
+
14
+ public function init($stage)
15
+ {
16
+ if ($this->getHosting() == "savvii") {
17
+ add_action('nitropack_execute_purge_url', [$this, 'purgeUrl']);
18
+ add_action('nitropack_execute_purge_all', [$this, 'purgeAll']);
19
+ add_action('nitropack_early_cache_headers', [$this, 'setCacheControl']);
20
+ add_action('nitropack_cacheable_cache_headers', [$this, 'setCacheControl']);
21
+ add_action('nitropack_cachehit_cache_headers', [$this, 'setCacheControl']);
22
+ }
23
+ }
24
+
25
+ public function purgeUrl($url)
26
+ {
27
+ try {
28
+ $siteConfig = nitropack_get_site_config();
29
+ if ($siteConfig && !empty($siteConfig['home_url'])) {
30
+ $urlObject = new \NitroPack\Url($url);
31
+
32
+ $http = new \NitroPack\HttpClient(nitropack_trailingslashit($siteConfig['home_url']) . 'purge');
33
+ $http->setHeader('X-PURGE-HOST', $urlObject->getHost());
34
+ $http->setHeader('X-PURGE-PATH-REGEX', $urlObject->getPath() . '.*');
35
+ $http->fetch(false, "PURGE");
36
+ }
37
+ } catch (\Exception $e) {
38
+ // Breeze exception
39
+ }
40
+ }
41
+
42
+ public function purgeAll() {
43
+ try {
44
+ $siteConfig = nitropack_get_site_config();
45
+ if ($siteConfig && !empty($siteConfig['home_url'])) {
46
+ $url = new \NitroPack\Url($siteConfig['home_url']);
47
+
48
+ $http = new \NitroPack\HttpClient($url->getNormalized() . 'purge');
49
+ $http->setHeader('X-PURGE-HOST', $url->getHost());
50
+ $http->fetch(false, "PURGE");
51
+ }
52
+ } catch (\Exception $e) {
53
+ // Exception
54
+ }
55
+ }
56
+
57
+ public function setCacheControl() {
58
+ header("Vary: sec-ch-ua-mobile");
59
+ if (isset($_SERVER["HTTP_SEC_CH_UA_MOBILE"])) {
60
+ header("Cache-Control: public, max-age=0, s-maxage=3600"); // needs to be like that instead of Cache-Control: no-cache in order to allow caching in the provided reverse proxy, but prevent the browsers from doing so
61
+ } else {
62
+ return;
63
+ }
64
+ }
65
+ }
classes/Integration/Hosting/SiteGround.php CHANGED
@@ -6,6 +6,7 @@ class SiteGround extends Hosting {
6
  const STAGE = "very_early";
7
 
8
  public static function detect() {
 
9
  $configFilePath = nitropack_get_wpconfig_path();
10
  if (!$configFilePath) return false;
11
  return strpos(file_get_contents($configFilePath), 'Added by SiteGround WordPress management system') !== false;
6
  const STAGE = "very_early";
7
 
8
  public static function detect() {
9
+ if (strpos(gethostname(), "siteground.eu") !== false) return true;
10
  $configFilePath = nitropack_get_wpconfig_path();
11
  if (!$configFilePath) return false;
12
  return strpos(file_get_contents($configFilePath), 'Added by SiteGround WordPress management system') !== false;
classes/Integration/Hosting/WPEngine.php CHANGED
@@ -18,6 +18,12 @@ class WPEngine extends Hosting {
18
  switch ($stage) {
19
  case "very_early":
20
  define("NITROPACK_USE_MICROTIMEOUT", 20000);
 
 
 
 
 
 
21
  \NitroPack\Integration::initSemAcquire();
22
  return true;
23
  case "early":
18
  switch ($stage) {
19
  case "very_early":
20
  define("NITROPACK_USE_MICROTIMEOUT", 20000);
21
+ if (isset($_COOKIE["wpengine_no_cache"]) || isset($_SERVER["HTTP_AUTOUPDATER"])) {
22
+ add_filter("nitropack_passes_cookie_requirements", function() {
23
+ header("X-Nitro-Disabled-Reason: WP Engine SPM bypass");
24
+ return false;
25
+ });
26
+ }
27
  \NitroPack\Integration::initSemAcquire();
28
  return true;
29
  case "early":
classes/Integration/Plugin/Cloudflare.php CHANGED
@@ -22,8 +22,12 @@ class Cloudflare {
22
  switch ($stage) {
23
  case "very_early":
24
  if (self::isApoRequest()) {
25
- add_action('nitropack_cacheable_cache_headers', [$this, 'allowApoCache'], PHP_INT_MAX);
26
- add_action('nitropack_cachehit_cache_headers', [$this, 'allowApoCache'], PHP_INT_MAX);
 
 
 
 
27
  }
28
  \NitroPack\Integration::initSemAcquire();
29
  return true;
@@ -57,6 +61,10 @@ class Cloudflare {
57
  }
58
 
59
  public function allowApoCache() {
60
- header("CDN-Cache-Control: public, max-age=300, s-maxage=300, stale-while-revalidate=3600");
 
 
 
 
61
  }
62
  }
22
  switch ($stage) {
23
  case "very_early":
24
  if (self::isApoRequest()) {
25
+ $siteConfig = get_nitropack()->getSiteConfig();
26
+ if ($siteConfig && !empty($siteConfig["isApoActive"])) {
27
+ add_action('nitropack_early_cache_headers', [$this, 'preventApoCache'], PHP_INT_MAX);
28
+ add_action('nitropack_cacheable_cache_headers', [$this, 'allowApoCache'], PHP_INT_MAX);
29
+ add_action('nitropack_cachehit_cache_headers', [$this, 'allowApoCache'], PHP_INT_MAX);
30
+ }
31
  }
32
  \NitroPack\Integration::initSemAcquire();
33
  return true;
61
  }
62
 
63
  public function allowApoCache() {
64
+ header("cf-edge-cache: cache,platform=wordpress");
65
+ }
66
+
67
+ public function preventApoCache() {
68
+ header("cf-edge-cache: no-cache");
69
  }
70
  }
classes/Integration/Plugin/CookieNotice.php CHANGED
@@ -8,8 +8,7 @@ class CookieNotice {
8
  public function init($stage) {
9
  # Cookie Notice plugin hack
10
  add_action( 'init', function() {
11
- $cookieNoticePath = 'cookie-notice/cookie-notice.php';
12
- if (function_exists("is_plugin_active") && is_plugin_active($cookieNoticePath)) {
13
  $agent = Cookie_Notice()->bot_detect->get_user_agent();
14
  if ($agent) {
15
  $replaced = str_replace('Nitro-Optimizer-Agent', '', $agent);
8
  public function init($stage) {
9
  # Cookie Notice plugin hack
10
  add_action( 'init', function() {
11
+ if (function_exists("Cookie_Notice")) {
 
12
  $agent = Cookie_Notice()->bot_detect->get_user_agent();
13
  if ($agent) {
14
  $replaced = str_replace('Nitro-Optimizer-Agent', '', $agent);
classes/Integration/Plugin/RocketNet_Helper.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace NitroPack\Integration\Plugin;
4
+
5
+ class RocketNet_Helper extends \Rocket_Wordpress {
6
+ public static function purgeUrl($url) {
7
+ $urlObj = new \NitroPack\Url($url);
8
+ $entry = $urlObj->getPath();
9
+ if ($urlObj->getQuery()) {
10
+ $entry .= "?" . $urlObj->getQuery();
11
+ }
12
+ self::cache_api_call([$entry], "purge");
13
+ }
14
+ }
15
+
classes/Integration/Server/Cloudflare.php CHANGED
@@ -15,7 +15,7 @@ class Cloudflare {
15
  }
16
 
17
  public function init($stage) {
18
- if (self::detect()) {
19
  header("Accept-CH: Sec-CH-UA-Mobile");
20
 
21
  if (self::isCacheEnabled()) {
@@ -29,12 +29,17 @@ class Cloudflare {
29
  }
30
 
31
  public function allowProxyCache() {
32
- header("Vary: sec-ch-ua-mobile");
33
- header("CDN-Cache-Control: public, max-age=0, s-maxage=15, stale-while-revalidate=3600");
 
 
 
 
 
34
  }
35
 
36
  public function preventProxyCache() {
37
- header("CDN-Cache-Control: no-cache");
38
  }
39
  }
40
 
15
  }
16
 
17
  public function init($stage) {
18
+ if (self::detect() && !\NitroPack\Integration\Plugin\Cloudflare::isApoRequest()) {
19
  header("Accept-CH: Sec-CH-UA-Mobile");
20
 
21
  if (self::isCacheEnabled()) {
29
  }
30
 
31
  public function allowProxyCache() {
32
+ $siteConfig = get_nitropack()->getSiteConfig();
33
+ if ($siteConfig && !empty($siteConfig["hosting"]) && $siteConfig["hosting"] == "rocketnet") {
34
+ header("Cloudflare-CDN-Cache-Control: public, max-age=0, s-maxage=300, stale-while-revalidate=3600");
35
+ } else {
36
+ header("Vary: sec-ch-ua-mobile");
37
+ header("Cloudflare-CDN-Cache-Control: public, max-age=0, s-maxage=15, stale-while-revalidate=3600");
38
+ }
39
  }
40
 
41
  public function preventProxyCache() {
42
+ header("Cloudflare-CDN-Cache-Control: no-cache");
43
  }
44
  }
45
 
classes/Integration/Server/Sucuri.php ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace NitroPack\Integration\Server;
4
+
5
+ // We need this to control Sucuri in addition to any other proxy potentially provided by the origin host company
6
+ class Sucuri {
7
+ const STAGE = "very_early";
8
+
9
+ public static function detect() {
10
+ return !empty($_SERVER["HTTP_X_SUCURI_CLIENTIP"]) || !empty($_SERVER["HTTP_X_SUCURI_COUNTRY"]);
11
+ }
12
+
13
+ public static function isCacheEnabled() {
14
+ return self::detect() && !empty($_SERVER["HTTP_SEC_CH_UA_MOBILE"]);
15
+ }
16
+
17
+ public function init($stage) {
18
+ if (self::detect()) {
19
+ header("Accept-CH: Sec-CH-UA-Mobile");
20
+
21
+ if (self::isCacheEnabled()) {
22
+ add_action('nitropack_cacheable_cache_headers', [$this, 'allowProxyCache'], PHP_INT_MAX-1);
23
+ add_action('nitropack_cachehit_cache_headers', [$this, 'allowProxyCache'], PHP_INT_MAX-1);
24
+ } else {
25
+ add_action('nitropack_cacheable_cache_headers', [$this, 'preventProxyCache'], PHP_INT_MAX-1);
26
+ add_action('nitropack_cachehit_cache_headers', [$this, 'preventProxyCache'], PHP_INT_MAX-1);
27
+ }
28
+ }
29
+ }
30
+
31
+ public function allowProxyCache() {
32
+ header("Vary: sec-ch-ua-mobile");
33
+ header("Cache-Control: public, max-age=0, s-maxage=15, stale-while-revalidate=3600");
34
+ }
35
+
36
+ public function preventProxyCache() {
37
+ header("Cache-Control: no-cache");
38
+ }
39
+ }
40
+
classes/WordPress/Config.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace NitroPack\WordPress;
3
+
4
+ class Config {
5
+ private $config;
6
+
7
+ public function __construct() {
8
+ $this->config = NULL;
9
+ }
10
+
11
+ public function get() {
12
+ if ($this->config) {
13
+ return $this->config;
14
+ }
15
+
16
+ $config = array();
17
+
18
+ if ($this->exists()) {
19
+ $config = json_decode(file_get_contents(NITROPACK_CONFIG_FILE), true); // TODO: Convert this to use the Filesystem abstraction for better Redis support
20
+ }
21
+
22
+ $this->config = $config;
23
+ return $config;
24
+ }
25
+
26
+ public function set($config) {
27
+ $np = NitroPack::getInstance();
28
+ if (!$np->dataDirExists() && !$np->initDataDir()) return false;
29
+ $this->config = $config;
30
+ return WP_DEBUG ? file_put_contents(NITROPACK_CONFIG_FILE, json_encode($config, JSON_PRETTY_PRINT)) : @file_put_contents(NITROPACK_CONFIG_FILE, json_encode($config, JSON_PRETTY_PRINT)); // TODO: Convert this to use the Filesystem abstraction for better Redis support
31
+ }
32
+
33
+ public function exists() {
34
+ return defined("NITROPACK_CONFIG_FILE") && file_exists(NITROPACK_CONFIG_FILE); // TODO: Convert this to use the Filesystem abstraction for better Redis support
35
+ }
36
+ }
classes/WordPress/NitroPack.php ADDED
@@ -0,0 +1,178 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace NitroPack\WordPress;
3
+
4
+ class NitroPack {
5
+ private static $instance = NULL;
6
+ public static $preUpdatePosts = array();
7
+ public static $preUpdateTaxonomies = array();
8
+ public static $ignoreUpdatePostIDs = array();
9
+
10
+ public static function getInstance() {
11
+ if (!self::$instance) {
12
+ self::$instance = new NitroPack();
13
+ }
14
+
15
+ return self::$instance;
16
+ }
17
+
18
+ private $sdkObjects;
19
+
20
+ public $Config;
21
+ public $Notification;
22
+
23
+ public function __construct() {
24
+ $this->Config = new Config($this);
25
+ $this->Notifications = new Notifications($this);
26
+ $this->sdkObjects = array();
27
+ }
28
+
29
+ public function getSiteConfig() {
30
+ $siteConfig = null;
31
+ $npConfig = $this->Config->get();
32
+ $host = !empty($_SERVER["HTTP_HOST"]) ? $_SERVER["HTTP_HOST"] : "";
33
+ $uri = !empty($_SERVER["REQUEST_URI"]) ? $_SERVER["REQUEST_URI"] : "";
34
+ $currentUrl = $host . $uri;
35
+ $matchLength = 0;
36
+
37
+ if (stripos($currentUrl, "www.") === 0) {
38
+ $currentUrl = substr($currentUrl, 4);
39
+ }
40
+
41
+ foreach ($npConfig as $siteUrl => $config) {
42
+ if (stripos($siteUrl, "www.") === 0) {
43
+ $siteUrl = substr($siteUrl, 4);
44
+ }
45
+
46
+ if (stripos($currentUrl, $siteUrl) === 0 && strlen($siteUrl) > $matchLength) {
47
+ $siteConfig = $config;
48
+ $matchLength = strlen($siteUrl);
49
+ }
50
+ }
51
+ return $siteConfig;
52
+ }
53
+
54
+ public function getSiteId() {
55
+ $siteConfig = $this->getSiteConfig();
56
+ return $siteConfig ? $siteConfig["siteId"] : NULL;
57
+ }
58
+
59
+ public function getSiteSecret() {
60
+ $siteConfig = $this->getSiteConfig();
61
+ return $siteConfig ? $siteConfig["siteSecret"] : NULL;
62
+ }
63
+
64
+ public function isConnected() {
65
+ if (function_exists("esc_attr") && function_exists("get_option")) {
66
+ $siteId = $this->getSiteId() || esc_attr( get_option('nitropack-siteId') );
67
+ $siteSecret = $this->getSiteSecret() || esc_attr( get_option('nitropack-siteSecret') );
68
+ } else {
69
+ $siteId = $this->getSiteId();
70
+ $siteSecret = $this->getSiteSecret();
71
+ }
72
+ return !empty($siteId) && !empty($siteSecret);
73
+ }
74
+
75
+ public function updateCurrentBlogConfig($siteId, $siteSecret, $blogId, $enableCompression = null) {
76
+ if ($enableCompression === null) {
77
+ $enableCompression = (get_option('nitropack-enableCompression') == 1);
78
+ }
79
+
80
+ $webhookToken = get_option('nitropack-webhookToken');
81
+ $hosting = nitropack_detect_hosting();
82
+
83
+ $home_url = get_home_url();
84
+ $admin_url = admin_url();
85
+ $alwaysBuffer = defined("NITROPACK_ALWAYS_BUFFER") ? NITROPACK_ALWAYS_BUFFER : true;
86
+ $configKey = preg_replace("/^https?:\/\/(.*)/", "$1", $home_url);
87
+ $staticConfig = $this->Config->get();
88
+ $staticConfig[$configKey] = array(
89
+ "siteId" => $siteId,
90
+ "siteSecret" => $siteSecret,
91
+ "blogId" => $blogId,
92
+ "compression" => $enableCompression,
93
+ "webhookToken" => $webhookToken,
94
+ "home_url" => $home_url,
95
+ "admin_url" => $admin_url,
96
+ "hosting" => $hosting,
97
+ "alwaysBuffer" => $alwaysBuffer,
98
+ "isEzoicActive" => \NitroPack\Integration\Plugin\Ezoic::isActive(),
99
+ "isApoActive" => \NitroPack\Integration\Plugin\Cloudflare::isApoActive(),
100
+ "isLateIntegrationInitRequired" => nitropack_is_late_integration_init_required(),
101
+ "isDlmActive" => \NitroPack\Integration\Plugin\DownloadManager::isActive(),
102
+ "dlm_downloading_url" => \NitroPack\Integration\Plugin\DownloadManager::isActive() ? \NitroPack\Integration\Plugin\DownloadManager::downloadingUrl() : NULL,
103
+ "dlm_download_endpoint" => \NitroPack\Integration\Plugin\DownloadManager::isActive() ? \NitroPack\Integration\Plugin\DownloadManager::downloadEndpoint() : NULL,
104
+ "pluginVersion" => NITROPACK_VERSION
105
+ );
106
+ return $this->Config->set($staticConfig);
107
+ }
108
+
109
+ public function unsetCurrentBlogConfig() {
110
+ $home_url = get_home_url();
111
+ $configKey = preg_replace("/^https?:\/\/(.*)/", "$1", $home_url);
112
+ $staticConfig = $this->Config->get();
113
+ if (!empty($staticConfig[$configKey])) {
114
+ unset($staticConfig[$configKey]);
115
+ return $this->Config->set($staticConfig);
116
+ }
117
+
118
+ return true;
119
+ }
120
+
121
+ public function getSdk($siteId = null, $siteSecret = null, $urlOverride = NULL, $forwardExceptions = false) {
122
+ $siteConfig = $this->getSiteConfig();
123
+
124
+ $siteId = $siteId ? $siteId : ($siteConfig ? $siteConfig['siteId'] : get_option('nitropack-siteId'));
125
+ $siteSecret = $siteSecret ? $siteSecret : ($siteConfig ? $siteConfig['siteSecret'] : get_option('nitropack-siteSecret'));
126
+
127
+ if ($siteId && $siteSecret) {
128
+ try {
129
+ $userAgent = NULL; // It will be automatically detected by the SDK
130
+ $dataDir = nitropack_trailingslashit(NITROPACK_DATA_DIR) . $siteId; // dir without a trailing slash, because this is how the SDK expects it
131
+ $cacheKey = "{$siteId}:{$siteSecret}:{$dataDir}";
132
+
133
+ if ($urlOverride) {
134
+ $cacheKey .= ":{$urlOverride}";
135
+ }
136
+
137
+ if (!empty($this->sdkObjects[$cacheKey])) {
138
+ $nitro = $this->sdkObjects[$cacheKey];
139
+ } else {
140
+ if (!defined("NP_COOKIE_FILTER")) {
141
+ \NitroPack\SDK\NitroPack::addCookieFilter("nitropack_filter_non_original_cookies");
142
+ define("NP_COOKIE_FILTER", true);
143
+ }
144
+ if (!defined("NP_STORAGE_CONFIGURED")) {
145
+ if (defined("NITROPACK_USE_REDIS") && NITROPACK_USE_REDIS) {
146
+ \NitroPack\SDK\Filesystem::setStorageDriver(new \NitroPack\SDK\StorageDriver\Redis(
147
+ NITROPACK_REDIS_HOST,
148
+ NITROPACK_REDIS_PORT,
149
+ NITROPACK_REDIS_PASS,
150
+ NITROPACK_REDIS_DB
151
+ ));
152
+ }
153
+ define("NP_STORAGE_CONFIGURED", true);
154
+ }
155
+ $nitro = new \NitroPack\SDK\NitroPack($siteId, $siteSecret, $userAgent, $urlOverride, $dataDir);
156
+ $this->sdkObjects[$cacheKey] = $nitro;
157
+ }
158
+ } catch (\Exception $e) {
159
+ if ($forwardExceptions) {
160
+ throw $e;
161
+ }
162
+ return NULL;
163
+ }
164
+
165
+ return $nitro;
166
+ }
167
+
168
+ return NULL;
169
+ }
170
+
171
+ public function dataDirExists() {
172
+ return defined("NITROPACK_DATA_DIR") && is_dir(NITROPACK_DATA_DIR); // TODO: Convert this to use the Filesystem abstraction for better Redis support
173
+ }
174
+
175
+ public function initDataDir() {
176
+ return $this->dataDirExists() || @mkdir(NITROPACK_DATA_DIR, 0755, true); // TODO: Convert this to use the Filesystem abstraction for better Redis support
177
+ }
178
+ }
classes/WordPress/Notifications.php ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace NitroPack\WordPress;
3
+ use NitroPack\HttpClient;
4
+ use \NitroPack\SDK\Filesystem;
5
+
6
+ class Notifications {
7
+ private $cacheTtl = 3600;
8
+ private $nitro;
9
+ private $notifications;
10
+
11
+ public function __construct($nitro) {
12
+ $this->nitro = $nitro;
13
+ $this->notifications = NULL;
14
+ }
15
+
16
+ public function get($type = NULL) {
17
+ if ($this->notifications === NULL) {
18
+ $this->load();
19
+ }
20
+
21
+ if (isset($this->notifications[$this->nitro->getSiteId()])) {
22
+ $result = $this->notifications[$this->nitro->getSiteId()];
23
+ if ($type) {
24
+ return isset($result['notifications'][$type]) ? $result['notifications'][$type] : [];
25
+ } else {
26
+ return $result['notifications'];
27
+ }
28
+ } else {
29
+ return [];
30
+ }
31
+ }
32
+
33
+ private function load() {
34
+ $this->notifications = [];
35
+
36
+ $notificationsFile = nitropack_trailingslashit(NITROPACK_DATA_DIR) . 'notifications.json';
37
+ if(Filesystem::fileExists($notificationsFile)) {
38
+ $this->notifications = json_decode(Filesystem::fileGetContents($notificationsFile), true);
39
+ if (!empty($this->notifications) && isset($this->notifications[$this->nitro->getSiteId()])) {
40
+ $result = $this->notifications[$this->nitro->getSiteId()];
41
+ if ($result['last_modified'] + $this->cacheTtl > time()) { // The cache is still fresh
42
+ return;
43
+ }
44
+ }
45
+ }
46
+
47
+ if ($this->nitro->isConnected()) {
48
+ try {
49
+ $result = $this->fetch();
50
+ $this->notifications[$this->nitro->getSiteId()] = [
51
+ 'last_modified' => time(),
52
+ 'notifications' => $result
53
+ ];
54
+ Filesystem::filePutContents($notificationsFile, json_encode($this->notifications));
55
+ } catch (\Exception $e) {
56
+ $this->notifications[$this->nitro->getSiteId()] = [ // We need this entry in order to make use of the cache logic
57
+ 'last_modified' => time(),
58
+ 'error' => $e->getMessage(),
59
+ 'notifications' => []
60
+ ];
61
+ Filesystem::filePutContents($notificationsFile, json_encode($this->notifications));
62
+ }
63
+ }
64
+ }
65
+
66
+ private function fetch() {
67
+ $notificationsUrl = get_nitropack_integration_url('notifications_json');
68
+ $client = new HttpClient($notificationsUrl);
69
+ $client->setHeader("x-nitro-platform", "wordpress");
70
+ $client->fetch();
71
+ $resp = $client->getStatusCode() == 200 ? json_decode($client->getBody(), true) : false;
72
+ return $resp ? $resp['notifications'] : [];
73
+ }
74
+ }
constants.php CHANGED
@@ -6,13 +6,12 @@ function nitropack_trailingslashit($string) {
6
  return rtrim( $string, '/\\' ) . '/';
7
  }
8
 
9
- define( 'NITROPACK_VERSION', '1.5.7' );
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' );
13
  define( 'NITROPACK_PLUGIN_DIR', nitropack_trailingslashit(dirname(__FILE__)));
14
  define( 'NITROPACK_CLASSES_DIR', nitropack_trailingslashit(NITROPACK_PLUGIN_DIR . 'classes') );
15
- define( 'NITROPACK_INTEGRATIONS_ACTION', "nitropack_integrations_ready");
16
  define( 'NITROPACK_HEARTBEAT_INTERVAL', 60*5); // 5min
17
 
18
  if (!defined("NITROPACK_USE_REDIS")) define("NITROPACK_USE_REDIS", false); // Set this to true to enable storing cache in Redis
@@ -23,3 +22,12 @@ if (!defined("NITROPACK_REDIS_DB")) define("NITROPACK_REDIS_DB", NULL); // Set t
23
 
24
  if (!defined("NITROPACK_SUPPORT_BUBBLE_VISIBLE")) define("NITROPACK_SUPPORT_BUBBLE_VISIBLE", true);
25
  if (!defined("NITROPACK_SUPPORT_BUBBLE_URL")) define("NITROPACK_SUPPORT_BUBBLE_URL", "https://support.nitropack.io/");
 
 
 
 
 
 
 
 
 
6
  return rtrim( $string, '/\\' ) . '/';
7
  }
8
 
9
+ define( 'NITROPACK_VERSION', '1.5.8' );
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' );
13
  define( 'NITROPACK_PLUGIN_DIR', nitropack_trailingslashit(dirname(__FILE__)));
14
  define( 'NITROPACK_CLASSES_DIR', nitropack_trailingslashit(NITROPACK_PLUGIN_DIR . 'classes') );
 
15
  define( 'NITROPACK_HEARTBEAT_INTERVAL', 60*5); // 5min
16
 
17
  if (!defined("NITROPACK_USE_REDIS")) define("NITROPACK_USE_REDIS", false); // Set this to true to enable storing cache in Redis
22
 
23
  if (!defined("NITROPACK_SUPPORT_BUBBLE_VISIBLE")) define("NITROPACK_SUPPORT_BUBBLE_VISIBLE", true);
24
  if (!defined("NITROPACK_SUPPORT_BUBBLE_URL")) define("NITROPACK_SUPPORT_BUBBLE_URL", "https://support.nitropack.io/");
25
+
26
+ spl_autoload_register(function($class) {
27
+ $filename = str_replace("\\", "/", $class) . ".php";
28
+ $filename = str_replace("NitroPack/", "", $filename);
29
+ $filepath = NITROPACK_CLASSES_DIR . ltrim($filename, "/");
30
+ if (file_exists($filepath)) {
31
+ require_once $filepath;
32
+ }
33
+ });
functions.php CHANGED
@@ -9,13 +9,9 @@ require_once $np_basePath . 'nitropack-sdk/autoload.php';
9
  $np_originalRequestCookies = $_COOKIE;
10
  $np_customExpirationTimes = array();
11
  $np_queriedObj = NULL;
12
- $np_preUpdatePosts = array();
13
- $np_preUpdateTaxonomies = array();
14
  $np_loggedPurges = array();
15
  $np_loggedInvalidations = array();
16
  $np_loggedWarmups = array();
17
- $np_sdkObjects = array();
18
- $np_ignoreUpdatePostIDs = array();
19
  $np_integrationSetupEvent = "muplugins_loaded";
20
 
21
  function nitropack_is_logged_in() {
@@ -34,13 +30,13 @@ function nitropack_passes_cookie_requirements() {
34
  $safeCookie = (strpos($cookieStr, "comment_author") === false && strpos($cookieStr, "wp-postpass_") === false && empty($_COOKIE["woocommerce_items_in_cart"])) || !!header("X-Nitro-Disabled-Reason: cookie bypass");
35
  $isUserLoggedIn = nitropack_is_logged_in() && !header("X-Nitro-Disabled-Reason: logged in");
36
 
37
- return $safeCookie && !$isUserLoggedIn;
38
  }
39
 
40
  function nitropack_activate() {
41
  nitropack_set_wp_cache_const(true);
42
  $htaccessFile = nitropack_trailingslashit(NITROPACK_DATA_DIR) . ".htaccess";
43
- if (!file_exists($htaccessFile) && nitropack_init_data_dir()) {
44
  file_put_contents($htaccessFile, "deny from all");
45
  }
46
  nitropack_install_advanced_cache();
@@ -51,7 +47,7 @@ function nitropack_activate() {
51
  // Exception while signaling our 3rd party integration addons to purge their cache
52
  }
53
 
54
- if (nitropack_is_connected()) {
55
  nitropack_event("enable_extension");
56
  } else {
57
  setcookie("nitropack_after_activate_notice", 1, time() + 3600);
@@ -68,7 +64,7 @@ function nitropack_deactivate() {
68
  // Exception while signaling our 3rd party integration addons to purge their cache
69
  }
70
 
71
- if (nitropack_is_connected()) {
72
  nitropack_event("disable_extension");
73
  }
74
  }
@@ -110,19 +106,13 @@ function nitropack_set_wp_cache_const($status) {
110
  return true;
111
  }
112
 
113
- $configFilePath = nitropack_trailingslashit(ABSPATH) . "wp-config.php";
114
- if (!file_exists($configFilePath) || !is_writable($configFilePath)) {
115
- $configFilePath = nitropack_trailingslashit(dirname(ABSPATH)) . "wp-config.php";
116
- $settingsFilePath = nitropack_trailingslashit(dirname(ABSPATH)) . "wp-settings.php"; // We need to check for this file to avoid confusion if the current installation is a nested directory of another WP installation. Refer to wp-load.php for more information.
117
- if (!file_exists($configFilePath) || !is_writable($configFilePath) || file_exists($settingsFilePath)) {
118
- return false;
119
- }
120
- }
121
-
122
- if (!is_writable($configFilePath)) {
123
- return false;
124
  }
125
 
 
 
 
126
  $newVal = sprintf("define( 'WP_CACHE', %s /* Modified by NitroPack */ );\n", ($status ? "true" : "false") );
127
  $replacementVal = sprintf(" %s /* Modified by NitroPack */ ", ($status ? "true" : "false") );
128
  $lines = file($configFilePath);
@@ -160,6 +150,48 @@ function nitropack_set_wp_cache_const($status) {
160
  return WP_DEBUG ? file_put_contents($configFilePath, implode("", $lines)) : @file_put_contents($configFilePath, implode("", $lines));
161
  }
162
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
163
  function is_valid_nitropack_webhook() {
164
  return !empty($_GET["nitroWebhook"]) && !empty($_GET["token"]) && nitropack_validate_webhook_token($_GET["token"]);
165
  }
@@ -738,7 +770,6 @@ function nitropack_options() {
738
  wp_enqueue_style('nitropack_css', plugin_dir_url(__FILE__) . 'view/stylesheet/nitropack.css?np_v=' . NITROPACK_VERSION);
739
  wp_enqueue_style('nitropack_font-awesome_css', plugin_dir_url(__FILE__) . 'view/stylesheet/fontawesome/font-awesome.min.css?np_v=' . NITROPACK_VERSION, true);
740
  wp_enqueue_script('nitropack_bootstrap_js', plugin_dir_url(__FILE__) . 'view/javascript/bootstrap.min.js?np_v=' . NITROPACK_VERSION, true);
741
- wp_enqueue_script('nitropack_notices_js', plugin_dir_url(__FILE__) . 'view/javascript/np_notices.js?np_v=' . NITROPACK_VERSION, true);
742
  wp_enqueue_script('nitropack_overlay_js', plugin_dir_url(__FILE__) . 'view/javascript/overlay.js?np_v=' . NITROPACK_VERSION, true);
743
  wp_enqueue_script('nitropack_embed_js', 'https://nitropack.io/asset/js/embed.js?np_v=' . NITROPACK_VERSION, true);
744
  wp_enqueue_script( 'jquery-form' );
@@ -775,14 +806,13 @@ function nitropack_options() {
775
  }
776
  }
777
 
778
- function nitropack_is_connected() {
779
- $siteId = esc_attr( get_option('nitropack-siteId') );
780
- $siteSecret = esc_attr( get_option('nitropack-siteSecret') );
781
- return !empty($siteId) && !empty($siteSecret);
782
- }
783
-
784
- function nitropack_print_notice($type, $message) {
785
- echo '<div class="notice notice-' . $type . ' is-dismissible">';
786
  echo '<p><strong>NitroPack:</strong> ' . $message . '</p>';
787
  echo '</div>';
788
  }
@@ -881,7 +911,7 @@ function nitropack_is_conflicting_plugin_active() {
881
 
882
  function nitropack_is_advanced_cache_allowed() {
883
  return !in_array(nitropack_detect_hosting(), array(
884
- //"closte"
885
  ));
886
  }
887
 
@@ -890,6 +920,13 @@ function nitropack_admin_notices() {
890
  nitropack_print_notice("info", "<script>document.cookie = 'nitropack_after_activate_notice=1; expires=Thu, 01 Jan 1970 00:00:01 GMT;';</script>NitroPack has been successfully activated, but it is not connected yet. Please go to <a href='" . admin_url( 'options-general.php?page=nitropack' ) . "'>its settings</a> page to connect it in order to start optimizing your site!");
891
  }
892
 
 
 
 
 
 
 
 
893
  nitropack_print_hosting_notice();
894
  nitropack_print_woocommerce_notice();
895
  }
@@ -900,7 +937,7 @@ function nitropack_get_hosting_notice_file() {
900
 
901
  function nitropack_print_hosting_notice() {
902
  $hostingNoticeFile = nitropack_get_hosting_notice_file();
903
- if (!nitropack_is_connected() || file_exists($hostingNoticeFile)) return;
904
 
905
  $documentedHostingSetups = array(
906
  "flywheel" => array(
@@ -935,7 +972,7 @@ function nitropack_dismiss_hosting_notice() {
935
  }
936
 
937
  function nitropack_print_woocommerce_notice() {
938
- if (nitropack_is_connected()) {
939
  if (class_exists('WooCommerce')) {
940
  $wcOneTimeNotice = get_option('nitropack-wcNotice');
941
  if ($wcOneTimeNotice === false) {
@@ -983,55 +1020,7 @@ function nitropack_print_meta_box($post) {
983
  }
984
 
985
  function get_nitropack_sdk($siteId = null, $siteSecret = null, $urlOverride = NULL, $forwardExceptions = false) {
986
- global $np_sdkObjects;
987
- $siteConfig = nitropack_get_site_config();
988
-
989
- require_once 'nitropack-sdk/autoload.php';
990
- $siteId = $siteId ? $siteId : ($siteConfig ? $siteConfig['siteId'] : get_option('nitropack-siteId'));
991
- $siteSecret = $siteSecret ? $siteSecret : ($siteConfig ? $siteConfig['siteSecret'] : get_option('nitropack-siteSecret'));
992
-
993
- if ($siteId && $siteSecret) {
994
- try {
995
- $userAgent = NULL; // It will be automatically detected by the SDK
996
- $dataDir = nitropack_trailingslashit(NITROPACK_DATA_DIR) . $siteId; // dir without a trailing slash, because this is how the SDK expects it
997
- $cacheKey = "{$siteId}:{$siteSecret}:{$dataDir}";
998
-
999
- if ($urlOverride) {
1000
- $cacheKey .= ":{$urlOverride}";
1001
- }
1002
-
1003
- if (!empty($np_sdkObjects[$cacheKey])) {
1004
- $nitro = $np_sdkObjects[$cacheKey];
1005
- } else {
1006
- if (!defined("NP_COOKIE_FILTER")) {
1007
- NitroPack\SDK\NitroPack::addCookieFilter("nitropack_filter_non_original_cookies");
1008
- define("NP_COOKIE_FILTER", true);
1009
- }
1010
- if (!defined("NP_STORAGE_CONFIGURED")) {
1011
- if (defined("NITROPACK_USE_REDIS") && NITROPACK_USE_REDIS) {
1012
- NitroPack\SDK\Filesystem::setStorageDriver(new NitroPack\SDK\StorageDriver\Redis(
1013
- NITROPACK_REDIS_HOST,
1014
- NITROPACK_REDIS_PORT,
1015
- NITROPACK_REDIS_PASS,
1016
- NITROPACK_REDIS_DB
1017
- ));
1018
- }
1019
- define("NP_STORAGE_CONFIGURED", true);
1020
- }
1021
- $nitro = new NitroPack\SDK\NitroPack($siteId, $siteSecret, $userAgent, $urlOverride, $dataDir);
1022
- $np_sdkObjects[$cacheKey] = $nitro;
1023
- }
1024
- } catch (\Exception $e) {
1025
- if ($forwardExceptions) {
1026
- throw $e;
1027
- }
1028
- return NULL;
1029
- }
1030
-
1031
- return $nitro;
1032
- }
1033
-
1034
- return NULL;
1035
  }
1036
 
1037
  function get_nitropack_integration_url($integration, $nitro = null) {
@@ -1502,7 +1491,7 @@ function nitropack_invalidate_cache() {
1502
  function nitropack_clear_residual_cache() {
1503
  $gde = !empty($_POST["gde"]) ? $_POST["gde"] : NULL;
1504
  if ($gde && array_key_exists($gde, NitroPack\Integration\Plugin\RC::$modules)) {
1505
- $result = NitroPack\Integration\Plugin\RC::$modules[$gde]::clearCache();
1506
  if (!in_array(false, $result)) {
1507
  nitropack_json_and_exit(array(
1508
  "type" => "success",
@@ -1707,8 +1696,8 @@ function nitropack_handle_comment_post($commentID, $isApproved) {
1707
  }
1708
 
1709
  function nitropack_handle_post_transition($new, $old, $post) {
1710
- global $np_ignoreUpdatePostIDs, $np_loggedWarmups;
1711
- if (!empty($post->ID) && in_array($post->ID, $np_ignoreUpdatePostIDs)) return;
1712
  if (!get_option("nitropack-autoCachePurge", 1)) return;
1713
 
1714
  try {
@@ -1804,8 +1793,7 @@ function nitropack_handle_the_post($post) {
1804
  }
1805
 
1806
  function nitropack_ignore_post_updates($postID) {
1807
- global $np_ignoreUpdatePostIDs;
1808
- $np_ignoreUpdatePostIDs[] = $postID;
1809
  }
1810
 
1811
  function nitropack_get_taxonomies($post) {
@@ -1835,22 +1823,19 @@ function nitropack_get_taxonomies_for_update($post) {
1835
  }
1836
 
1837
  function nitropack_get_post_pre_update($post) {
1838
- global $np_preUpdatePosts;
1839
- return !empty($np_preUpdatePosts[$post->ID]) ? $np_preUpdatePosts[$post->ID] : NULL;
1840
  }
1841
 
1842
  function nitropack_get_taxonomies_pre_update($post) {
1843
- global $np_preUpdateTaxonomies;
1844
- return !empty($np_preUpdateTaxonomies[$post->ID]) ? $np_preUpdateTaxonomies[$post->ID] : array();
1845
  }
1846
 
1847
  function nitropack_log_post_pre_update($postID) {
1848
- global $np_preUpdatePosts, $np_preUpdateTaxonomies, $np_ignoreUpdatePostIDs;
1849
- if (in_array($postID, $np_ignoreUpdatePostIDs)) return;
1850
 
1851
  $post = get_post($postID);
1852
- $np_preUpdatePosts[$postID] = $post;
1853
- $np_preUpdateTaxonomies[$postID] = nitropack_get_taxonomies($post);
1854
  }
1855
 
1856
  function nitropack_filter_tag($tag) {
@@ -2005,7 +1990,7 @@ function nitropack_verify_connect($siteId, $siteSecret) {
2005
 
2006
  $nitro->fetchConfig(); // Reload the variation cookies
2007
 
2008
- nitropack_update_current_blog_config($siteId, $siteSecret, $blogId);
2009
  nitropack_install_advanced_cache();
2010
  update_option("nitropack-siteId", $siteId);
2011
  update_option("nitropack-siteSecret", $siteSecret);
@@ -2069,7 +2054,7 @@ function nitropack_disconnect() {
2069
  if (null !== $nitro = get_nitropack_sdk()) {
2070
  nitropack_reset_webhooks($nitro);
2071
  }
2072
- nitropack_unset_current_blog_config();
2073
  delete_option("nitropack-siteId");
2074
  delete_option("nitropack-siteSecret");
2075
 
@@ -2149,11 +2134,11 @@ function nitropack_handle_compression_toggle($old_value, $new_value) {
2149
  }
2150
 
2151
  function nitropack_update_blog_compression($enableCompression = false) {
2152
- if (nitropack_is_connected()) {
2153
  $siteId = esc_attr( get_option('nitropack-siteId') );
2154
  $siteSecret = esc_attr( get_option('nitropack-siteSecret') );
2155
  $blogId = get_current_blog_id();
2156
- nitropack_update_current_blog_config($siteId, $siteSecret, $blogId, $enableCompression);
2157
  }
2158
  }
2159
 
@@ -2349,107 +2334,12 @@ function nitropack_cache_safemode_status($operation = null) {
2349
  return update_option('nitropack-safeModeStatus', $sm);
2350
  }
2351
 
2352
- function nitropack_data_dir_exists() {
2353
- return defined("NITROPACK_DATA_DIR") && is_dir(NITROPACK_DATA_DIR);
2354
- }
2355
-
2356
- function nitropack_init_data_dir() {
2357
- return nitropack_data_dir_exists() || @mkdir(NITROPACK_DATA_DIR, 0755, true);
2358
- }
2359
-
2360
- function nitropack_config_exists() {
2361
- return defined("NITROPACK_CONFIG_FILE") && file_exists(NITROPACK_CONFIG_FILE);
2362
- }
2363
-
2364
  function nitropack_get_site_config() {
2365
- $siteConfig = null;
2366
- $npConfig = nitropack_get_config();
2367
- $host = !empty($_SERVER["HTTP_HOST"]) ? $_SERVER["HTTP_HOST"] : "";
2368
- $uri = !empty($_SERVER["REQUEST_URI"]) ? $_SERVER["REQUEST_URI"] : "";
2369
- $currentUrl = $host . $uri;
2370
- $matchLength = 0;
2371
-
2372
- if (stripos($currentUrl, "www.") === 0) {
2373
- $currentUrl = substr($currentUrl, 4);
2374
- }
2375
-
2376
- foreach ($npConfig as $siteUrl => $config) {
2377
- if (stripos($siteUrl, "www.") === 0) {
2378
- $siteUrl = substr($siteUrl, 4);
2379
- }
2380
-
2381
- if (stripos($currentUrl, $siteUrl) === 0 && strlen($siteUrl) > $matchLength) {
2382
- $siteConfig = $config;
2383
- $matchLength = strlen($siteUrl);
2384
- }
2385
- }
2386
- return $siteConfig;
2387
  }
2388
 
2389
- function nitropack_set_config($config) {
2390
- if (!nitropack_data_dir_exists() && !nitropack_init_data_dir()) return false;
2391
- $GLOBALS["nitropack.config"] = $config;
2392
- return WP_DEBUG ? file_put_contents(NITROPACK_CONFIG_FILE, json_encode($config, JSON_PRETTY_PRINT)) : @file_put_contents(NITROPACK_CONFIG_FILE, json_encode($config, JSON_PRETTY_PRINT));
2393
- }
2394
-
2395
- function nitropack_get_config() {
2396
- if (!empty($GLOBALS["nitropack.config"])) {
2397
- return $GLOBALS["nitropack.config"];
2398
- }
2399
-
2400
- $config = array();
2401
-
2402
- if (nitropack_config_exists()) {
2403
- $config = json_decode(file_get_contents(NITROPACK_CONFIG_FILE), true);
2404
- }
2405
-
2406
- $GLOBALS["nitropack.config"] = $config;
2407
- return $config;
2408
- }
2409
-
2410
- function nitropack_update_current_blog_config($siteId, $siteSecret, $blogId, $enableCompression = null) {
2411
- if ($enableCompression === null) {
2412
- $enableCompression = (get_option('nitropack-enableCompression') == 1);
2413
- }
2414
-
2415
- $webhookToken = get_option('nitropack-webhookToken');
2416
- $hosting = nitropack_detect_hosting();
2417
-
2418
- $home_url = get_home_url();
2419
- $admin_url = admin_url();
2420
- $alwaysBuffer = defined("NITROPACK_ALWAYS_BUFFER") ? NITROPACK_ALWAYS_BUFFER : true;
2421
- $configKey = preg_replace("/^https?:\/\/(.*)/", "$1", $home_url);
2422
- $staticConfig = nitropack_get_config();
2423
- $staticConfig[$configKey] = array(
2424
- "siteId" => $siteId,
2425
- "siteSecret" => $siteSecret,
2426
- "blogId" => $blogId,
2427
- "compression" => $enableCompression,
2428
- "webhookToken" => $webhookToken,
2429
- "home_url" => $home_url,
2430
- "admin_url" => $admin_url,
2431
- "hosting" => $hosting,
2432
- "alwaysBuffer" => $alwaysBuffer,
2433
- "isEzoicActive" => \NitroPack\Integration\Plugin\Ezoic::isActive(),
2434
- "isLateIntegrationInitRequired" => nitropack_is_late_integration_init_required(),
2435
- "isDlmActive" => \NitroPack\Integration\Plugin\DownloadManager::isActive(),
2436
- "dlm_downloading_url" => \NitroPack\Integration\Plugin\DownloadManager::isActive() ? \NitroPack\Integration\Plugin\DownloadManager::downloadingUrl() : NULL,
2437
- "dlm_download_endpoint" => \NitroPack\Integration\Plugin\DownloadManager::isActive() ? \NitroPack\Integration\Plugin\DownloadManager::downloadEndpoint() : NULL,
2438
- "pluginVersion" => NITROPACK_VERSION
2439
- );
2440
- return nitropack_set_config($staticConfig);
2441
- }
2442
-
2443
- function nitropack_unset_current_blog_config() {
2444
- $home_url = get_home_url();
2445
- $configKey = preg_replace("/^https?:\/\/(.*)/", "$1", $home_url);
2446
- $staticConfig = nitropack_get_config();
2447
- if (!empty($staticConfig[$configKey])) {
2448
- unset($staticConfig[$configKey]);
2449
- return nitropack_set_config($staticConfig);
2450
- }
2451
-
2452
- return true;
2453
  }
2454
 
2455
  function nitropack_event($event, $nitro = null, $additional_meta_data = null) {
@@ -2483,6 +2373,10 @@ function nitropack_get_wpconfig_path() {
2483
  return false;
2484
  }
2485
  }
 
 
 
 
2486
 
2487
  return $configFilePath;
2488
  }
@@ -2510,14 +2404,33 @@ function nitropack_detect_hosting() {
2510
  return "wpx";
2511
  } else if (\NitroPack\Integration\Hosting\Vimexx::detect()) {
2512
  return "vimexx";
 
 
 
 
 
 
2513
  } else {
2514
  return "unknown";
2515
  }
2516
  }
2517
 
 
 
 
 
 
2518
  function nitropack_handle_request($servedFrom = "unknown") {
2519
  global $np_integrationSetupEvent;
2520
 
 
 
 
 
 
 
 
 
2521
  header('Cache-Control: no-cache');
2522
  do_action("nitropack_early_cache_headers"); // Overrides the Cache-Control header on supported platforms
2523
  $isManageWpRequest = !empty($_GET["mwprid"]);
@@ -2615,7 +2528,7 @@ function nitropack_admin_bar_menu($wp_admin_bar){
2615
  $pluginStatus = 'ok';
2616
  }
2617
 
2618
- if (!nitropack_is_connected()) {
2619
  $node = array(
2620
  'id' => 'nitropack-top-menu',
2621
  'title' => '&nbsp;&nbsp;<i style="" class="fa fa-circle nitro nitro-status nitro-status-error" aria-hidden="true"></i>&nbsp;&nbsp;NitroPack is disconnected',
@@ -2686,6 +2599,22 @@ function nitropack_admin_bar_menu($wp_admin_bar){
2686
  )
2687
  );
2688
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2689
  }
2690
 
2691
  $wp_admin_bar->add_node($node);
@@ -2782,7 +2711,7 @@ function nitropack_plugin_notices() {
2782
  $warnings[] = "It seems plugins have been activated, deactivated or updated. It is recommended that you purge the cache to reflect the latest changes. <a class=\"btn-sm\" href=\"javascript:void(0);\" id=\"np-onstate-cache-purge\" class=\"acivate\" onclick=\"document.cookie = 'nitropack_apwarning=; expires=Thu, 01 Jan 1970 00:00:01 GMT; path=$cookie_path';window.location.reload();\"> Dismiss</a>";
2783
  }
2784
 
2785
- $nitropackIsConnected = nitropack_is_connected();
2786
 
2787
  if ($nitropackIsConnected) {
2788
  if (nitropack_is_advanced_cache_allowed()) {
@@ -2822,7 +2751,7 @@ function nitropack_plugin_notices() {
2822
  }
2823
  }
2824
 
2825
- if ( !nitropack_data_dir_exists() && !nitropack_init_data_dir()) {
2826
  $errors[] = "The NitroPack data directory cannot be created. Please make sure that the /wp-content/ directory is writable and refresh this page.";
2827
  return [
2828
  'error' => $errors,
@@ -2838,10 +2767,10 @@ function nitropack_plugin_notices() {
2838
  $isConfigOutdated = !nitropack_is_config_up_to_date();
2839
  $siteConfig = nitropack_get_site_config();
2840
 
2841
- if ( !nitropack_config_exists() && !nitropack_update_current_blog_config($siteId, $siteSecret, $blogId)) {
2842
  $errors[] = "The NitroPack static config file cannot be created. Please make sure that the /wp-content/nitropack/ directory is writable and refresh this page.";
2843
  } else if ( $isConfigOutdated ) {
2844
- if (!nitropack_update_current_blog_config($siteId, $siteSecret, $blogId)) {
2845
  $errors[] = "The NitroPack static config file cannot be updated. Please make sure that the /wp-content/nitropack/ directory is writable and refresh this page.";
2846
  } else {
2847
  if (!$siteConfig) {
@@ -2870,7 +2799,7 @@ function nitropack_plugin_notices() {
2870
  (!array_key_exists("isLateIntegrationInitRequired", $siteConfig) || $siteConfig["isLateIntegrationInitRequired"] !== nitropack_is_late_integration_init_required()) ||
2871
  (!array_key_exists("isDlmActive", $siteConfig) || $siteConfig["isDlmActive"] !== \NitroPack\Integration\Plugin\DownloadManager::isActive())
2872
  ) {
2873
- if (!nitropack_update_current_blog_config($siteId, $siteSecret, $blogId)) {
2874
  $errors[] = "The NitroPack static config file cannot be updated. Please make sure that the /wp-content/nitropack/ directory is writable and refresh this page.";
2875
  }
2876
  }
@@ -2955,4 +2884,5 @@ function nitropack_offer_safemode() {
2955
  }
2956
 
2957
  // Init integration action handlers
2958
- require_once 'integrations.php';
 
9
  $np_originalRequestCookies = $_COOKIE;
10
  $np_customExpirationTimes = array();
11
  $np_queriedObj = NULL;
 
 
12
  $np_loggedPurges = array();
13
  $np_loggedInvalidations = array();
14
  $np_loggedWarmups = array();
 
 
15
  $np_integrationSetupEvent = "muplugins_loaded";
16
 
17
  function nitropack_is_logged_in() {
30
  $safeCookie = (strpos($cookieStr, "comment_author") === false && strpos($cookieStr, "wp-postpass_") === false && empty($_COOKIE["woocommerce_items_in_cart"])) || !!header("X-Nitro-Disabled-Reason: cookie bypass");
31
  $isUserLoggedIn = nitropack_is_logged_in() && !header("X-Nitro-Disabled-Reason: logged in");
32
 
33
+ return apply_filters("nitropack_passes_cookie_requirements", $safeCookie && !$isUserLoggedIn);
34
  }
35
 
36
  function nitropack_activate() {
37
  nitropack_set_wp_cache_const(true);
38
  $htaccessFile = nitropack_trailingslashit(NITROPACK_DATA_DIR) . ".htaccess";
39
+ if (!file_exists($htaccessFile) && get_nitropack()->initDataDir()) {
40
  file_put_contents($htaccessFile, "deny from all");
41
  }
42
  nitropack_install_advanced_cache();
47
  // Exception while signaling our 3rd party integration addons to purge their cache
48
  }
49
 
50
+ if (get_nitropack()->isConnected()) {
51
  nitropack_event("enable_extension");
52
  } else {
53
  setcookie("nitropack_after_activate_notice", 1, time() + 3600);
64
  // Exception while signaling our 3rd party integration addons to purge their cache
65
  }
66
 
67
+ if (get_nitropack()->isConnected()) {
68
  nitropack_event("disable_extension");
69
  }
70
  }
106
  return true;
107
  }
108
 
109
+ if (\NitroPack\Integration\Hosting\Pressable::detect()) { // Pressable: We need to deal with Batcache here
110
+ return nitropack_set_batcache_compat($status);
 
 
 
 
 
 
 
 
 
111
  }
112
 
113
+ $configFilePath = nitropack_get_wpconfig_path();
114
+ if (!$configFilePath) return false;
115
+
116
  $newVal = sprintf("define( 'WP_CACHE', %s /* Modified by NitroPack */ );\n", ($status ? "true" : "false") );
117
  $replacementVal = sprintf(" %s /* Modified by NitroPack */ ", ($status ? "true" : "false") );
118
  $lines = file($configFilePath);
150
  return WP_DEBUG ? file_put_contents($configFilePath, implode("", $lines)) : @file_put_contents($configFilePath, implode("", $lines));
151
  }
152
 
153
+ function nitropack_set_batcache_compat($status) {
154
+ $currentCompatStatus = defined("NITROPACK_BATCACHE_COMPAT") && NITROPACK_BATCACHE_COMPAT;
155
+ if ($currentCompatStatus === $status) return true;
156
+
157
+ $configFilePath = nitropack_get_wpconfig_path();
158
+ if (!$configFilePath) return false;
159
+
160
+ $batCacheFilePath = NITROPACK_PLUGIN_DIR . "batcache-compat.php";
161
+ $compatInclude = sprintf("if (file_exists(\"%s\")) { require_once \"%s\"; } // NitroPack compatibility with Batcache\n", $batCacheFilePath, $batCacheFilePath);
162
+ $lines = file($configFilePath);
163
+
164
+ if (empty($lines)) return false;
165
+
166
+ foreach ($lines as $lineIndex => &$line) {
167
+ if (preg_match("/nitropack.*?batcache/i", $line)) {
168
+ $line = "//REMOVE AT FILTER";
169
+ }
170
+ }
171
+
172
+ $newLines = array_filter($lines, function($line) { return $line != "//REMOVE AT FILTER";});
173
+
174
+ if ($status) {
175
+ $phpOpeningTagLine = false;
176
+
177
+ unset($line);
178
+ foreach ($newLines as $lineIndex => $line) {
179
+ if (strpos($line, "<?php") !== false && strpos($line, "?>") === false) {
180
+ $phpOpeningTagLine = $lineIndex;
181
+ break;
182
+ }
183
+ }
184
+
185
+ if ($phpOpeningTagLine !== false) {
186
+ array_splice($newLines, $phpOpeningTagLine + 1, 0, [$compatInclude]);
187
+ } else {
188
+ array_unshift($newLines, "<?php " . trim($compatInclude) . " ?>\n");
189
+ }
190
+ }
191
+
192
+ return WP_DEBUG ? file_put_contents($configFilePath, implode("", $newLines)) : @file_put_contents($configFilePath, implode("", $newLines));
193
+ }
194
+
195
  function is_valid_nitropack_webhook() {
196
  return !empty($_GET["nitroWebhook"]) && !empty($_GET["token"]) && nitropack_validate_webhook_token($_GET["token"]);
197
  }
770
  wp_enqueue_style('nitropack_css', plugin_dir_url(__FILE__) . 'view/stylesheet/nitropack.css?np_v=' . NITROPACK_VERSION);
771
  wp_enqueue_style('nitropack_font-awesome_css', plugin_dir_url(__FILE__) . 'view/stylesheet/fontawesome/font-awesome.min.css?np_v=' . NITROPACK_VERSION, true);
772
  wp_enqueue_script('nitropack_bootstrap_js', plugin_dir_url(__FILE__) . 'view/javascript/bootstrap.min.js?np_v=' . NITROPACK_VERSION, true);
 
773
  wp_enqueue_script('nitropack_overlay_js', plugin_dir_url(__FILE__) . 'view/javascript/overlay.js?np_v=' . NITROPACK_VERSION, true);
774
  wp_enqueue_script('nitropack_embed_js', 'https://nitropack.io/asset/js/embed.js?np_v=' . NITROPACK_VERSION, true);
775
  wp_enqueue_script( 'jquery-form' );
806
  }
807
  }
808
 
809
+ function nitropack_print_notice($type, $message, $dismissibleId = true) {
810
+ if ($dismissibleId) {
811
+ if (!empty($_COOKIE["dismissed_notice_" . $dismissibleId])) return;
812
+ echo '<div class="notice notice-' . $type . ' is-dismissible" data-dismissible-id="' . $dismissibleId . '">';
813
+ } else {
814
+ echo '<div class="notice notice-' . $type . '">';
815
+ }
 
816
  echo '<p><strong>NitroPack:</strong> ' . $message . '</p>';
817
  echo '</div>';
818
  }
911
 
912
  function nitropack_is_advanced_cache_allowed() {
913
  return !in_array(nitropack_detect_hosting(), array(
914
+ "pressable"
915
  ));
916
  }
917
 
920
  nitropack_print_notice("info", "<script>document.cookie = 'nitropack_after_activate_notice=1; expires=Thu, 01 Jan 1970 00:00:01 GMT;';</script>NitroPack has been successfully activated, but it is not connected yet. Please go to <a href='" . admin_url( 'options-general.php?page=nitropack' ) . "'>its settings</a> page to connect it in order to start optimizing your site!");
921
  }
922
 
923
+ $screen = get_current_screen();
924
+ if ($screen->id != 'settings_page_nitropack') {
925
+ foreach (get_nitropack()->Notifications->get('system') as $notification) {
926
+ nitropack_print_notice('info', $notification['message'], $notification["id"]);
927
+ }
928
+ }
929
+
930
  nitropack_print_hosting_notice();
931
  nitropack_print_woocommerce_notice();
932
  }
937
 
938
  function nitropack_print_hosting_notice() {
939
  $hostingNoticeFile = nitropack_get_hosting_notice_file();
940
+ if (!get_nitropack()->isConnected() || file_exists($hostingNoticeFile)) return;
941
 
942
  $documentedHostingSetups = array(
943
  "flywheel" => array(
972
  }
973
 
974
  function nitropack_print_woocommerce_notice() {
975
+ if (get_nitropack()->isConnected()) {
976
  if (class_exists('WooCommerce')) {
977
  $wcOneTimeNotice = get_option('nitropack-wcNotice');
978
  if ($wcOneTimeNotice === false) {
1020
  }
1021
 
1022
  function get_nitropack_sdk($siteId = null, $siteSecret = null, $urlOverride = NULL, $forwardExceptions = false) {
1023
+ return get_nitropack()->getSdk($siteId, $siteSecret, $urlOverride, $forwardExceptions);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1024
  }
1025
 
1026
  function get_nitropack_integration_url($integration, $nitro = null) {
1491
  function nitropack_clear_residual_cache() {
1492
  $gde = !empty($_POST["gde"]) ? $_POST["gde"] : NULL;
1493
  if ($gde && array_key_exists($gde, NitroPack\Integration\Plugin\RC::$modules)) {
1494
+ $result = call_user_func(array(NitroPack\Integration\Plugin\RC::$modules[$gde], "clearCache")); // This needs to be like this because of compatibility with PHP 5.6
1495
  if (!in_array(false, $result)) {
1496
  nitropack_json_and_exit(array(
1497
  "type" => "success",
1696
  }
1697
 
1698
  function nitropack_handle_post_transition($new, $old, $post) {
1699
+ global $np_loggedWarmups;
1700
+ if (!empty($post->ID) && in_array($post->ID, \NitroPack\WordPress\NitroPack::$ignoreUpdatePostIDs)) return;
1701
  if (!get_option("nitropack-autoCachePurge", 1)) return;
1702
 
1703
  try {
1793
  }
1794
 
1795
  function nitropack_ignore_post_updates($postID) {
1796
+ \NitroPack\WordPress\NitroPack::$ignoreUpdatePostIDs[] = $postID;
 
1797
  }
1798
 
1799
  function nitropack_get_taxonomies($post) {
1823
  }
1824
 
1825
  function nitropack_get_post_pre_update($post) {
1826
+ return !empty(\NitroPack\WordPress\NitroPack::$preUpdatePosts[$post->ID]) ? \NitroPack\WordPress\NitroPack::$preUpdatePosts[$post->ID] : NULL;
 
1827
  }
1828
 
1829
  function nitropack_get_taxonomies_pre_update($post) {
1830
+ return !empty(\NitroPack\WordPress\NitroPack::$preUpdateTaxonomies[$post->ID]) ? \NitroPack\WordPress\NitroPack::$preUpdateTaxonomies[$post->ID] : array();
 
1831
  }
1832
 
1833
  function nitropack_log_post_pre_update($postID) {
1834
+ if (in_array($postID, \NitroPack\WordPress\NitroPack::$ignoreUpdatePostIDs)) return;
 
1835
 
1836
  $post = get_post($postID);
1837
+ \NitroPack\WordPress\NitroPack::$preUpdatePosts[$postID] = $post;
1838
+ \NitroPack\WordPress\NitroPack::$preUpdateTaxonomies[$postID] = nitropack_get_taxonomies($post);
1839
  }
1840
 
1841
  function nitropack_filter_tag($tag) {
1990
 
1991
  $nitro->fetchConfig(); // Reload the variation cookies
1992
 
1993
+ get_nitropack()->updateCurrentBlogConfig($siteId, $siteSecret, $blogId);
1994
  nitropack_install_advanced_cache();
1995
  update_option("nitropack-siteId", $siteId);
1996
  update_option("nitropack-siteSecret", $siteSecret);
2054
  if (null !== $nitro = get_nitropack_sdk()) {
2055
  nitropack_reset_webhooks($nitro);
2056
  }
2057
+ get_nitropack()->unsetCurrentBlogConfig();
2058
  delete_option("nitropack-siteId");
2059
  delete_option("nitropack-siteSecret");
2060
 
2134
  }
2135
 
2136
  function nitropack_update_blog_compression($enableCompression = false) {
2137
+ if (get_nitropack()->isConnected()) {
2138
  $siteId = esc_attr( get_option('nitropack-siteId') );
2139
  $siteSecret = esc_attr( get_option('nitropack-siteSecret') );
2140
  $blogId = get_current_blog_id();
2141
+ get_nitropack()->updateCurrentBlogConfig($siteId, $siteSecret, $blogId, $enableCompression);
2142
  }
2143
  }
2144
 
2334
  return update_option('nitropack-safeModeStatus', $sm);
2335
  }
2336
 
 
 
 
 
 
 
 
 
 
 
 
 
2337
  function nitropack_get_site_config() {
2338
+ return get_nitropack()->getSiteConfig();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2339
  }
2340
 
2341
+ function get_nitropack() {
2342
+ return \NitroPack\WordPress\NitroPack::getInstance();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2343
  }
2344
 
2345
  function nitropack_event($event, $nitro = null, $additional_meta_data = null) {
2373
  return false;
2374
  }
2375
  }
2376
+
2377
+ if (!is_writable($configFilePath)) {
2378
+ return false;
2379
+ }
2380
 
2381
  return $configFilePath;
2382
  }
2404
  return "wpx";
2405
  } else if (\NitroPack\Integration\Hosting\Vimexx::detect()) {
2406
  return "vimexx";
2407
+ } else if (\NitroPack\Integration\Hosting\Pressable::detect()) {
2408
+ return "pressable";
2409
+ } else if (\NitroPack\Integration\Hosting\RocketNet::detect()) {
2410
+ return "rocketnet";
2411
+ } else if (\NitroPack\Integration\Hosting\Savvii::detect()) {
2412
+ return "savvii";
2413
  } else {
2414
  return "unknown";
2415
  }
2416
  }
2417
 
2418
+ function nitropack_removeCacheBustParam($content) {
2419
+ $content = preg_replace("/(\?|%26|&#0?38;|&#x0?26;|&(amp;)?)ignorenitro(%3D|=)[a-fA-F0-9]{32}(?!%26|&#0?38;|&#x0?26;|&(amp;)?)\/?/mu", "", $content);
2420
+ return preg_replace("/(\?|%26|&#0?38;|&#x0?26;|&(amp;)?)ignorenitro(%3D|=)[a-fA-F0-9]{32}(%26|&#0?38;|&#x0?26;|&(amp;)?)/mu", "$1", $content);
2421
+ }
2422
+
2423
  function nitropack_handle_request($servedFrom = "unknown") {
2424
  global $np_integrationSetupEvent;
2425
 
2426
+ if (isset($_GET["ignorenitro"])) {
2427
+ unset($_GET["ignorenitro"]);
2428
+ }
2429
+
2430
+ if (defined("NITROPACK_STRIP_IGNORENITRO") && NITROPACK_STRIP_IGNORENITRO && $_SERVER['REQUEST_URI'] != '') {
2431
+ $_SERVER['REQUEST_URI'] = nitropack_removeCacheBustParam($_SERVER['REQUEST_URI']);
2432
+ }
2433
+
2434
  header('Cache-Control: no-cache');
2435
  do_action("nitropack_early_cache_headers"); // Overrides the Cache-Control header on supported platforms
2436
  $isManageWpRequest = !empty($_GET["mwprid"]);
2528
  $pluginStatus = 'ok';
2529
  }
2530
 
2531
+ if (!get_nitropack()->isConnected()) {
2532
  $node = array(
2533
  'id' => 'nitropack-top-menu',
2534
  'title' => '&nbsp;&nbsp;<i style="" class="fa fa-circle nitro nitro-status nitro-status-error" aria-hidden="true"></i>&nbsp;&nbsp;NitroPack is disconnected',
2599
  )
2600
  );
2601
  }
2602
+
2603
+ $notificationCount = count(get_nitropack()->Notifications->get('system'));
2604
+ if ($notificationCount) {
2605
+ $node['title'] .= '&nbsp;&nbsp;<span style="color:#fff;background-color:#72aee6;border-radius:11px;padding: 2px 7px">' . $notificationCount . '</span>';
2606
+ $wp_admin_bar->add_node(
2607
+ array(
2608
+ 'parent' => 'nitropack-top-menu',
2609
+ 'id' => 'nitropack-notifications',
2610
+ 'title' => 'Notifications&nbsp;&nbsp;<span style="color:#fff;background-color:#72aee6;border-radius:11px;padding: 2px 7px">' . $notificationCount . '</span>',
2611
+ 'href' => admin_url( 'options-general.php?page=nitropack' ),
2612
+ 'meta' => array(
2613
+ 'class' => 'nitropack-notifications',
2614
+ )
2615
+ )
2616
+ );
2617
+ }
2618
  }
2619
 
2620
  $wp_admin_bar->add_node($node);
2711
  $warnings[] = "It seems plugins have been activated, deactivated or updated. It is recommended that you purge the cache to reflect the latest changes. <a class=\"btn-sm\" href=\"javascript:void(0);\" id=\"np-onstate-cache-purge\" class=\"acivate\" onclick=\"document.cookie = 'nitropack_apwarning=; expires=Thu, 01 Jan 1970 00:00:01 GMT; path=$cookie_path';window.location.reload();\"> Dismiss</a>";
2712
  }
2713
 
2714
+ $nitropackIsConnected = get_nitropack()->isConnected();
2715
 
2716
  if ($nitropackIsConnected) {
2717
  if (nitropack_is_advanced_cache_allowed()) {
2751
  }
2752
  }
2753
 
2754
+ if ( !get_nitropack()->dataDirExists() && !get_nitropack()->initDataDir()) {
2755
  $errors[] = "The NitroPack data directory cannot be created. Please make sure that the /wp-content/ directory is writable and refresh this page.";
2756
  return [
2757
  'error' => $errors,
2767
  $isConfigOutdated = !nitropack_is_config_up_to_date();
2768
  $siteConfig = nitropack_get_site_config();
2769
 
2770
+ if ( !get_nitropack()->Config->exists() && !get_nitropack()->updateCurrentBlogConfig($siteId, $siteSecret, $blogId)) {
2771
  $errors[] = "The NitroPack static config file cannot be created. Please make sure that the /wp-content/nitropack/ directory is writable and refresh this page.";
2772
  } else if ( $isConfigOutdated ) {
2773
+ if (!get_nitropack()->updateCurrentBlogConfig($siteId, $siteSecret, $blogId)) {
2774
  $errors[] = "The NitroPack static config file cannot be updated. Please make sure that the /wp-content/nitropack/ directory is writable and refresh this page.";
2775
  } else {
2776
  if (!$siteConfig) {
2799
  (!array_key_exists("isLateIntegrationInitRequired", $siteConfig) || $siteConfig["isLateIntegrationInitRequired"] !== nitropack_is_late_integration_init_required()) ||
2800
  (!array_key_exists("isDlmActive", $siteConfig) || $siteConfig["isDlmActive"] !== \NitroPack\Integration\Plugin\DownloadManager::isActive())
2801
  ) {
2802
+ if (!get_nitropack()->updateCurrentBlogConfig($siteId, $siteSecret, $blogId)) {
2803
  $errors[] = "The NitroPack static config file cannot be updated. Please make sure that the /wp-content/nitropack/ directory is writable and refresh this page.";
2804
  }
2805
  }
2884
  }
2885
 
2886
  // Init integration action handlers
2887
+ $integration = NitroPack\Integration::getInstance();
2888
+ $integration->init();
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.7
7
  Author: NitroPack LLC
8
  Author URI: https://nitropack.io/
9
  License: GPL2
@@ -39,9 +39,9 @@ add_action( 'transition_post_status', 'nitropack_handle_post_transition', 10, 3)
39
  add_action( 'transition_comment_status', 'nitropack_handle_comment_transition', 10, 3);
40
  add_action( 'comment_post', 'nitropack_handle_comment_post', 10, 2);
41
  add_action( 'switch_theme', 'nitropack_theme_handler' );
42
- add_action( 'shutdown', 'nitropack_execute_purges', -1000 );
43
- add_action( 'shutdown', 'nitropack_execute_invalidations', -1000 );
44
- add_action( 'shutdown', 'nitropack_execute_warmups', -1000 );
45
 
46
  add_action( 'woocommerce_product_object_updated_props', 'nitropack_handle_product_updates', 0, 2);
47
  add_action( 'woocommerce_rest_insert_product', function($post, $request, $creating) {
@@ -154,5 +154,9 @@ add_action( 'init', function() {
154
  // Add our admin menu bar entry
155
  add_action('admin_bar_menu', 'nitropack_admin_bar_menu', 50);
156
  add_action('plugins_loaded', 'nitropack_plugin_notices'); // Run the checks early, because we need to set some headers. The results from the checks will be cached, so future calls will work as expected.
 
 
 
 
157
  }
158
  });
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.8
7
  Author: NitroPack LLC
8
  Author URI: https://nitropack.io/
9
  License: GPL2
39
  add_action( 'transition_comment_status', 'nitropack_handle_comment_transition', 10, 3);
40
  add_action( 'comment_post', 'nitropack_handle_comment_post', 10, 2);
41
  add_action( 'switch_theme', 'nitropack_theme_handler' );
42
+ register_shutdown_function('nitropack_execute_purges');
43
+ register_shutdown_function('nitropack_execute_invalidations');
44
+ register_shutdown_function('nitropack_execute_warmups');
45
 
46
  add_action( 'woocommerce_product_object_updated_props', 'nitropack_handle_product_updates', 0, 2);
47
  add_action( 'woocommerce_rest_insert_product', function($post, $request, $creating) {
154
  // Add our admin menu bar entry
155
  add_action('admin_bar_menu', 'nitropack_admin_bar_menu', 50);
156
  add_action('plugins_loaded', 'nitropack_plugin_notices'); // Run the checks early, because we need to set some headers. The results from the checks will be cached, so future calls will work as expected.
157
+
158
+ add_action( 'admin_enqueue_scripts', function() {
159
+ wp_enqueue_script('nitropack_notices_js', plugin_dir_url(__FILE__) . 'view/javascript/np_notices.js?np_v=' . NITROPACK_VERSION);
160
+ });
161
  }
162
  });
nitropack-sdk/NitroPack/SDK/Api/RemoteConfigFetcher.php CHANGED
@@ -18,7 +18,7 @@ class RemoteConfigFetcher extends Base {
18
  // initiate the config request, expecting to receive a challenge
19
  $initiation = $this->initiateConfigRequest();
20
  if ($initiation->getStatus() != ResponseStatus::OK) {
21
- throw new \Exception('Error while attempting to fetch remote config'); // TODO better error message and/or custom exception class and logging
22
  }
23
 
24
  try {
@@ -27,20 +27,20 @@ class RemoteConfigFetcher extends Base {
27
  * where cid is the challenge id, sc0/1 are the two challenge strings, and resp is the challenge response for sc0 to verify the server knows the secret */
28
  $challenge = json_decode($initiation->getBody(), true);
29
  } catch (\Exception $e) {
30
- throw new \Exception('Error while processing remote config challenge'); // TODO better error message and/or custom exception class and logging
31
  }
32
 
33
  // verify that the challenge came from the API server
34
  $expectedResponse = $this->calculateChallengeResponse($challenge['sc0']);
35
 
36
  if (!$this->internal_hash_equals($expectedResponse, $challenge['resp'])) {
37
- throw new \Exception('API server failed challenge verification when fetching the remote config'); // TODO better error message and/or custom exception class and logging
38
  }
39
 
40
  $challengeResponse = $this->respondToChallenge($challenge['sc1'], $challenge['cid']);
41
 
42
  if ($challengeResponse->getStatus() != ResponseStatus::OK) {
43
- throw new \Exception('Error while receiving remote config - Received ' . $challengeResponse->getStatus()); // TODO better error message and/or custom exception class and logging
44
  }
45
 
46
  return $challengeResponse->getBody();
18
  // initiate the config request, expecting to receive a challenge
19
  $initiation = $this->initiateConfigRequest();
20
  if ($initiation->getStatus() != ResponseStatus::OK) {
21
+ throw new \NitroPack\SDK\ConfigFetcherException('Error while initializing remote config fetch request. Response code: ' . $initiation->getStatus()); // TODO better error message and logging
22
  }
23
 
24
  try {
27
  * where cid is the challenge id, sc0/1 are the two challenge strings, and resp is the challenge response for sc0 to verify the server knows the secret */
28
  $challenge = json_decode($initiation->getBody(), true);
29
  } catch (\Exception $e) {
30
+ throw new \NitroPack\SDK\ChallengeProcessingException('Error while processing remote config challenge'); // TODO better error message and logging
31
  }
32
 
33
  // verify that the challenge came from the API server
34
  $expectedResponse = $this->calculateChallengeResponse($challenge['sc0']);
35
 
36
  if (!$this->internal_hash_equals($expectedResponse, $challenge['resp'])) {
37
+ throw new \NitroPack\SDK\ChallengeVerificationException('API server failed challenge verification when fetching the remote config'); // TODO better error message and logging
38
  }
39
 
40
  $challengeResponse = $this->respondToChallenge($challenge['sc1'], $challenge['cid']);
41
 
42
  if ($challengeResponse->getStatus() != ResponseStatus::OK) {
43
+ throw new \NitroPack\SDK\ConfigFetcherException('Error while receiving remote config. Response code: ' . $challengeResponse->getStatus()); // TODO better error message and logging
44
  }
45
 
46
  return $challengeResponse->getBody();
nitropack-sdk/NitroPack/SDK/ChallengeProcessingException.php ADDED
@@ -0,0 +1,4 @@
 
 
 
 
1
+ <?php
2
+ namespace NitroPack\SDK;
3
+
4
+ class ChallengeProcessingException extends \Exception {}
nitropack-sdk/NitroPack/SDK/ChallengeVerificationException.php ADDED
@@ -0,0 +1,4 @@
 
 
 
 
1
+ <?php
2
+ namespace NitroPack\SDK;
3
+
4
+ class ChallengeVerificationException extends \Exception {}
nitropack-sdk/NitroPack/SDK/ConfigFetcherException.php ADDED
@@ -0,0 +1,4 @@
 
 
 
 
1
+ <?php
2
+ namespace NitroPack\SDK;
3
+
4
+ class ConfigFetcherException extends \Exception {}
nitropack-sdk/NitroPack/SDK/NitroPack.php CHANGED
@@ -2,7 +2,7 @@
2
  namespace NitroPack\SDK;
3
 
4
  class NitroPack {
5
- const VERSION = '0.30.0';
6
  const PAGECACHE_LOCK_EXPIRATION_TIME = 300; // in seconds
7
  private $dataDir;
8
  private $cachePath = array('data', 'pagecache');
@@ -252,6 +252,10 @@ class NitroPack {
252
  }
253
  }
254
 
 
 
 
 
255
  public function hasCache($layout = 'default') {
256
  if ($this->hasLocalCache()) {
257
  return true;
2
  namespace NitroPack\SDK;
3
 
4
  class NitroPack {
5
+ const VERSION = '0.30.1';
6
  const PAGECACHE_LOCK_EXPIRATION_TIME = 300; // in seconds
7
  private $dataDir;
8
  private $cachePath = array('data', 'pagecache');
252
  }
253
  }
254
 
255
+ public function getRemainingCacheTtl() {
256
+ return $this->pageCache->getRemainingTtl($this->config->PageCache->ExpireTime);
257
+ }
258
+
259
  public function hasCache($layout = 'default') {
260
  if ($this->hasLocalCache()) {
261
  return true;
nitropack-sdk/NitroPack/SDK/Pagecache.php CHANGED
@@ -144,6 +144,36 @@ class Pagecache {
144
  return false;
145
  }
146
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
147
  public function setContent($content, $headers = NULL) {
148
  if (!$this->dataDir) return;
149
 
144
  return false;
145
  }
146
 
147
+ public function getRemainingTtl($ttl = 86400) {
148
+ // If there is a parent cache file return its remaining TTL
149
+ if ($this->parent) return $this->parent->getRemainingTtl();
150
+
151
+ if ($this->useInvalidated) {
152
+ return 0;
153
+ } else {
154
+ $cachefilePath = $this->getCachefilePath();
155
+ }
156
+
157
+ $now = time();
158
+ try {
159
+ $headers = Filesystem::fileGetHeaders($cachefilePath);
160
+ if (!empty($headers["x-nitro-expires"])) {
161
+ $expireTime = (int) $headers["x-nitro-expires"];
162
+ } else if (!empty($headers["x-cache-ctime"])) {
163
+ $expireTime = (int) $headers["x-cache-ctime"] + $ttl;
164
+ } else {
165
+ $mtime = Filesystem::fileMtime($cachefilePath);
166
+ $expireTime = $mtime + $ttl;
167
+ }
168
+
169
+ return max($expireTime - $now, 0);
170
+ } catch (\Exception $e) {
171
+ return 0;
172
+ }
173
+
174
+ return 0;
175
+ }
176
+
177
  public function setContent($content, $headers = NULL) {
178
  if (!$this->dataDir) return;
179
 
nitropack-sdk/bootstrap.php CHANGED
@@ -10,6 +10,7 @@ define("NITROPACK_SITE_SECRET", "your site secret");
10
  */
11
  if (!defined("NITROPACK_ENABLE_COMPRESSION")) define("NITROPACK_ENABLE_COMPRESSION", false); // Set this to true to enable compression. Only do this if your server does not already have compression enabled
12
  if (!defined("NITROPACK_WEBHOOK_TOKEN")) define("NITROPACK_WEBHOOK_TOKEN", md5(__FILE__)); // Feel free to set this to a value of your liking
 
13
  if (!defined("NITROPACK_USE_REDIS")) define("NITROPACK_USE_REDIS", false); // Set this to true to enable storing cache in Redis
14
  if (!defined("NITROPACK_REDIS_HOST")) define("NITROPACK_REDIS_HOST", "127.0.0.1"); // Set this to the IP of your Redis server
15
  if (!defined("NITROPACK_REDIS_PORT")) define("NITROPACK_REDIS_PORT", 6379); // Set this to the port of your Redis server
@@ -53,6 +54,10 @@ function nitropack_get_instance($siteId = NULL, $siteSecret = NULL, $url = NULL)
53
  }
54
 
55
  function nitropack_handle_request() {
 
 
 
 
56
  header('Cache-Control: no-cache');
57
  header('X-Nitro-Cache: MISS');
58
  if ( !empty($_SERVER["HTTP_HOST"]) && !empty($_SERVER["REQUEST_URI"]) ) {
@@ -255,7 +260,7 @@ function nitropack_sdk_purge_local($url = NULL) {
255
  if ($url) {
256
  $nitro->purgeLocalUrlCache($url);
257
  } else {
258
- $nitro->purgeLocalCache();
259
  }
260
  } catch (\Exception $e) {
261
  return false;
10
  */
11
  if (!defined("NITROPACK_ENABLE_COMPRESSION")) define("NITROPACK_ENABLE_COMPRESSION", false); // Set this to true to enable compression. Only do this if your server does not already have compression enabled
12
  if (!defined("NITROPACK_WEBHOOK_TOKEN")) define("NITROPACK_WEBHOOK_TOKEN", md5(__FILE__)); // Feel free to set this to a value of your liking
13
+ if (!defined("NITROPACK_USE_QUICK_PURGE")) define("NITROPACK_USE_QUICK_PURGE", false); // Feel free to set this to a value of your liking
14
  if (!defined("NITROPACK_USE_REDIS")) define("NITROPACK_USE_REDIS", false); // Set this to true to enable storing cache in Redis
15
  if (!defined("NITROPACK_REDIS_HOST")) define("NITROPACK_REDIS_HOST", "127.0.0.1"); // Set this to the IP of your Redis server
16
  if (!defined("NITROPACK_REDIS_PORT")) define("NITROPACK_REDIS_PORT", 6379); // Set this to the port of your Redis server
54
  }
55
 
56
  function nitropack_handle_request() {
57
+ if (isset($_GET["ignorenitro"])) {
58
+ unset($_GET["ignorenitro"]);
59
+ }
60
+
61
  header('Cache-Control: no-cache');
62
  header('X-Nitro-Cache: MISS');
63
  if ( !empty($_SERVER["HTTP_HOST"]) && !empty($_SERVER["REQUEST_URI"]) ) {
260
  if ($url) {
261
  $nitro->purgeLocalUrlCache($url);
262
  } else {
263
+ $nitro->purgeLocalCache(NITROPACK_USE_QUICK_PURGE);
264
  }
265
  } catch (\Exception $e) {
266
  return false;
nitropack-sdk/vendor/autoload.php CHANGED
@@ -4,4 +4,4 @@
4
 
5
  require_once __DIR__ . '/composer/autoload_real.php';
6
 
7
- return ComposerAutoloaderInit8fcbb1a5ffa2542d92b974779798cb81::getLoader();
4
 
5
  require_once __DIR__ . '/composer/autoload_real.php';
6
 
7
+ return ComposerAutoloaderInit2e3dba6aa37dfe49fb3ede88169cdef9::getLoader();
nitropack-sdk/vendor/composer/ClassLoader.php CHANGED
@@ -37,57 +37,130 @@ namespace Composer\Autoload;
37
  *
38
  * @author Fabien Potencier <fabien@symfony.com>
39
  * @author Jordi Boggiano <j.boggiano@seld.be>
40
- * @see http://www.php-fig.org/psr/psr-0/
41
- * @see http://www.php-fig.org/psr/psr-4/
42
  */
43
  class ClassLoader
44
  {
 
 
 
45
  // PSR-4
 
 
 
 
46
  private $prefixLengthsPsr4 = array();
 
 
 
 
47
  private $prefixDirsPsr4 = array();
 
 
 
 
48
  private $fallbackDirsPsr4 = array();
49
 
50
  // PSR-0
 
 
 
 
51
  private $prefixesPsr0 = array();
 
 
 
 
52
  private $fallbackDirsPsr0 = array();
53
 
 
54
  private $useIncludePath = false;
 
 
 
 
 
55
  private $classMap = array();
 
 
56
  private $classMapAuthoritative = false;
 
 
 
 
 
57
  private $missingClasses = array();
 
 
58
  private $apcuPrefix;
59
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
  public function getPrefixes()
61
  {
62
  if (!empty($this->prefixesPsr0)) {
63
- return call_user_func_array('array_merge', $this->prefixesPsr0);
64
  }
65
 
66
  return array();
67
  }
68
 
 
 
 
 
69
  public function getPrefixesPsr4()
70
  {
71
  return $this->prefixDirsPsr4;
72
  }
73
 
 
 
 
 
74
  public function getFallbackDirs()
75
  {
76
  return $this->fallbackDirsPsr0;
77
  }
78
 
 
 
 
 
79
  public function getFallbackDirsPsr4()
80
  {
81
  return $this->fallbackDirsPsr4;
82
  }
83
 
 
 
 
 
84
  public function getClassMap()
85
  {
86
  return $this->classMap;
87
  }
88
 
89
  /**
90
- * @param array $classMap Class to filename map
 
 
 
91
  */
92
  public function addClassMap(array $classMap)
93
  {
@@ -102,9 +175,11 @@ class ClassLoader
102
  * Registers a set of PSR-0 directories for a given prefix, either
103
  * appending or prepending to the ones previously set for this prefix.
104
  *
105
- * @param string $prefix The prefix
106
- * @param array|string $paths The PSR-0 root directories
107
- * @param bool $prepend Whether to prepend the directories
 
 
108
  */
109
  public function add($prefix, $paths, $prepend = false)
110
  {
@@ -147,11 +222,13 @@ class ClassLoader
147
  * Registers a set of PSR-4 directories for a given namespace, either
148
  * appending or prepending to the ones previously set for this namespace.
149
  *
150
- * @param string $prefix The prefix/namespace, with trailing '\\'
151
- * @param array|string $paths The PSR-4 base directories
152
- * @param bool $prepend Whether to prepend the directories
153
  *
154
  * @throws \InvalidArgumentException
 
 
155
  */
156
  public function addPsr4($prefix, $paths, $prepend = false)
157
  {
@@ -195,8 +272,10 @@ class ClassLoader
195
  * Registers a set of PSR-0 directories for a given prefix,
196
  * replacing any others previously set for this prefix.
197
  *
198
- * @param string $prefix The prefix
199
- * @param array|string $paths The PSR-0 base directories
 
 
200
  */
201
  public function set($prefix, $paths)
202
  {
@@ -211,10 +290,12 @@ class ClassLoader
211
  * Registers a set of PSR-4 directories for a given namespace,
212
  * replacing any others previously set for this namespace.
213
  *
214
- * @param string $prefix The prefix/namespace, with trailing '\\'
215
- * @param array|string $paths The PSR-4 base directories
216
  *
217
  * @throws \InvalidArgumentException
 
 
218
  */
219
  public function setPsr4($prefix, $paths)
220
  {
@@ -234,6 +315,8 @@ class ClassLoader
234
  * Turns on searching the include path for class files.
235
  *
236
  * @param bool $useIncludePath
 
 
237
  */
238
  public function setUseIncludePath($useIncludePath)
239
  {
@@ -256,6 +339,8 @@ class ClassLoader
256
  * that have not been registered with the class map.
257
  *
258
  * @param bool $classMapAuthoritative
 
 
259
  */
260
  public function setClassMapAuthoritative($classMapAuthoritative)
261
  {
@@ -276,6 +361,8 @@ class ClassLoader
276
  * APCu prefix to use to cache found/not-found classes, if the extension is enabled.
277
  *
278
  * @param string|null $apcuPrefix
 
 
279
  */
280
  public function setApcuPrefix($apcuPrefix)
281
  {
@@ -296,25 +383,44 @@ class ClassLoader
296
  * Registers this instance as an autoloader.
297
  *
298
  * @param bool $prepend Whether to prepend the autoloader or not
 
 
299
  */
300
  public function register($prepend = false)
301
  {
302
  spl_autoload_register(array($this, 'loadClass'), true, $prepend);
 
 
 
 
 
 
 
 
 
 
 
303
  }
304
 
305
  /**
306
  * Unregisters this instance as an autoloader.
 
 
307
  */
308
  public function unregister()
309
  {
310
  spl_autoload_unregister(array($this, 'loadClass'));
 
 
 
 
311
  }
312
 
313
  /**
314
  * Loads the given class or interface.
315
  *
316
  * @param string $class The name of the class
317
- * @return bool|null True if loaded, null otherwise
318
  */
319
  public function loadClass($class)
320
  {
@@ -323,6 +429,8 @@ class ClassLoader
323
 
324
  return true;
325
  }
 
 
326
  }
327
 
328
  /**
@@ -367,6 +475,21 @@ class ClassLoader
367
  return $file;
368
  }
369
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
370
  private function findFileWithExtension($class, $ext)
371
  {
372
  // PSR-4 lookup
@@ -438,6 +561,10 @@ class ClassLoader
438
  * Scope isolated include.
439
  *
440
  * Prevents access to $this/self from included files.
 
 
 
 
441
  */
442
  function includeFile($file)
443
  {
37
  *
38
  * @author Fabien Potencier <fabien@symfony.com>
39
  * @author Jordi Boggiano <j.boggiano@seld.be>
40
+ * @see https://www.php-fig.org/psr/psr-0/
41
+ * @see https://www.php-fig.org/psr/psr-4/
42
  */
43
  class ClassLoader
44
  {
45
+ /** @var ?string */
46
+ private $vendorDir;
47
+
48
  // PSR-4
49
+ /**
50
+ * @var array[]
51
+ * @psalm-var array<string, array<string, int>>
52
+ */
53
  private $prefixLengthsPsr4 = array();
54
+ /**
55
+ * @var array[]
56
+ * @psalm-var array<string, array<int, string>>
57
+ */
58
  private $prefixDirsPsr4 = array();
59
+ /**
60
+ * @var array[]
61
+ * @psalm-var array<string, string>
62
+ */
63
  private $fallbackDirsPsr4 = array();
64
 
65
  // PSR-0
66
+ /**
67
+ * @var array[]
68
+ * @psalm-var array<string, array<string, string[]>>
69
+ */
70
  private $prefixesPsr0 = array();
71
+ /**
72
+ * @var array[]
73
+ * @psalm-var array<string, string>
74
+ */
75
  private $fallbackDirsPsr0 = array();
76
 
77
+ /** @var bool */
78
  private $useIncludePath = false;
79
+
80
+ /**
81
+ * @var string[]
82
+ * @psalm-var array<string, string>
83
+ */
84
  private $classMap = array();
85
+
86
+ /** @var bool */
87
  private $classMapAuthoritative = false;
88
+
89
+ /**
90
+ * @var bool[]
91
+ * @psalm-var array<string, bool>
92
+ */
93
  private $missingClasses = array();
94
+
95
+ /** @var ?string */
96
  private $apcuPrefix;
97
 
98
+ /**
99
+ * @var self[]
100
+ */
101
+ private static $registeredLoaders = array();
102
+
103
+ /**
104
+ * @param ?string $vendorDir
105
+ */
106
+ public function __construct($vendorDir = null)
107
+ {
108
+ $this->vendorDir = $vendorDir;
109
+ }
110
+
111
+ /**
112
+ * @return string[]
113
+ */
114
  public function getPrefixes()
115
  {
116
  if (!empty($this->prefixesPsr0)) {
117
+ return call_user_func_array('array_merge', array_values($this->prefixesPsr0));
118
  }
119
 
120
  return array();
121
  }
122
 
123
+ /**
124
+ * @return array[]
125
+ * @psalm-return array<string, array<int, string>>
126
+ */
127
  public function getPrefixesPsr4()
128
  {
129
  return $this->prefixDirsPsr4;
130
  }
131
 
132
+ /**
133
+ * @return array[]
134
+ * @psalm-return array<string, string>
135
+ */
136
  public function getFallbackDirs()
137
  {
138
  return $this->fallbackDirsPsr0;
139
  }
140
 
141
+ /**
142
+ * @return array[]
143
+ * @psalm-return array<string, string>
144
+ */
145
  public function getFallbackDirsPsr4()
146
  {
147
  return $this->fallbackDirsPsr4;
148
  }
149
 
150
+ /**
151
+ * @return string[] Array of classname => path
152
+ * @psalm-var array<string, string>
153
+ */
154
  public function getClassMap()
155
  {
156
  return $this->classMap;
157
  }
158
 
159
  /**
160
+ * @param string[] $classMap Class to filename map
161
+ * @psalm-param array<string, string> $classMap
162
+ *
163
+ * @return void
164
  */
165
  public function addClassMap(array $classMap)
166
  {
175
  * Registers a set of PSR-0 directories for a given prefix, either
176
  * appending or prepending to the ones previously set for this prefix.
177
  *
178
+ * @param string $prefix The prefix
179
+ * @param string[]|string $paths The PSR-0 root directories
180
+ * @param bool $prepend Whether to prepend the directories
181
+ *
182
+ * @return void
183
  */
184
  public function add($prefix, $paths, $prepend = false)
185
  {
222
  * Registers a set of PSR-4 directories for a given namespace, either
223
  * appending or prepending to the ones previously set for this namespace.
224
  *
225
+ * @param string $prefix The prefix/namespace, with trailing '\\'
226
+ * @param string[]|string $paths The PSR-4 base directories
227
+ * @param bool $prepend Whether to prepend the directories
228
  *
229
  * @throws \InvalidArgumentException
230
+ *
231
+ * @return void
232
  */
233
  public function addPsr4($prefix, $paths, $prepend = false)
234
  {
272
  * Registers a set of PSR-0 directories for a given prefix,
273
  * replacing any others previously set for this prefix.
274
  *
275
+ * @param string $prefix The prefix
276
+ * @param string[]|string $paths The PSR-0 base directories
277
+ *
278
+ * @return void
279
  */
280
  public function set($prefix, $paths)
281
  {
290
  * Registers a set of PSR-4 directories for a given namespace,
291
  * replacing any others previously set for this namespace.
292
  *
293
+ * @param string $prefix The prefix/namespace, with trailing '\\'
294
+ * @param string[]|string $paths The PSR-4 base directories
295
  *
296
  * @throws \InvalidArgumentException
297
+ *
298
+ * @return void
299
  */
300
  public function setPsr4($prefix, $paths)
301
  {
315
  * Turns on searching the include path for class files.
316
  *
317
  * @param bool $useIncludePath
318
+ *
319
+ * @return void
320
  */
321
  public function setUseIncludePath($useIncludePath)
322
  {
339
  * that have not been registered with the class map.
340
  *
341
  * @param bool $classMapAuthoritative
342
+ *
343
+ * @return void
344
  */
345
  public function setClassMapAuthoritative($classMapAuthoritative)
346
  {
361
  * APCu prefix to use to cache found/not-found classes, if the extension is enabled.
362
  *
363
  * @param string|null $apcuPrefix
364
+ *
365
+ * @return void
366
  */
367
  public function setApcuPrefix($apcuPrefix)
368
  {
383
  * Registers this instance as an autoloader.
384
  *
385
  * @param bool $prepend Whether to prepend the autoloader or not
386
+ *
387
+ * @return void
388
  */
389
  public function register($prepend = false)
390
  {
391
  spl_autoload_register(array($this, 'loadClass'), true, $prepend);
392
+
393
+ if (null === $this->vendorDir) {
394
+ return;
395
+ }
396
+
397
+ if ($prepend) {
398
+ self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders;
399
+ } else {
400
+ unset(self::$registeredLoaders[$this->vendorDir]);
401
+ self::$registeredLoaders[$this->vendorDir] = $this;
402
+ }
403
  }
404
 
405
  /**
406
  * Unregisters this instance as an autoloader.
407
+ *
408
+ * @return void
409
  */
410
  public function unregister()
411
  {
412
  spl_autoload_unregister(array($this, 'loadClass'));
413
+
414
+ if (null !== $this->vendorDir) {
415
+ unset(self::$registeredLoaders[$this->vendorDir]);
416
+ }
417
  }
418
 
419
  /**
420
  * Loads the given class or interface.
421
  *
422
  * @param string $class The name of the class
423
+ * @return true|null True if loaded, null otherwise
424
  */
425
  public function loadClass($class)
426
  {
429
 
430
  return true;
431
  }
432
+
433
+ return null;
434
  }
435
 
436
  /**
475
  return $file;
476
  }
477
 
478
+ /**
479
+ * Returns the currently registered loaders indexed by their corresponding vendor directories.
480
+ *
481
+ * @return self[]
482
+ */
483
+ public static function getRegisteredLoaders()
484
+ {
485
+ return self::$registeredLoaders;
486
+ }
487
+
488
+ /**
489
+ * @param string $class
490
+ * @param string $ext
491
+ * @return string|false
492
+ */
493
  private function findFileWithExtension($class, $ext)
494
  {
495
  // PSR-4 lookup
561
  * Scope isolated include.
562
  *
563
  * Prevents access to $this/self from included files.
564
+ *
565
+ * @param string $file
566
+ * @return void
567
+ * @private
568
  */
569
  function includeFile($file)
570
  {
nitropack-sdk/vendor/composer/InstalledVersions.php CHANGED
@@ -1,239 +1,350 @@
1
  <?php
2
 
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
 
13
  namespace Composer;
14
 
 
15
  use Composer\Semver\VersionParser;
16
 
17
-
18
-
19
-
20
-
21
-
 
 
22
  class InstalledVersions
23
  {
24
- private static $installed = array (
25
- 'root' =>
26
- array (
27
- 'pretty_version' => 'dev-master',
28
- 'version' => 'dev-master',
29
- 'aliases' =>
30
- array (
31
- ),
32
- 'reference' => 'e50e27c8dfb5f2ad66e67c0f414ba8cd3ceacf66',
33
- 'name' => 'nitropack/nitropackcloud-sdk',
34
- ),
35
- 'versions' =>
36
- array (
37
- 'nitropack/httpclient' =>
38
- array (
39
- 'pretty_version' => 'dev-master',
40
- 'version' => 'dev-master',
41
- 'aliases' =>
42
- array (
43
- 0 => '9999999-dev',
44
- ),
45
- 'reference' => '2322728997a9a3e7f4adbb41229b347cce2ebab0',
46
- ),
47
- 'nitropack/nitropackcloud-sdk' =>
48
- array (
49
- 'pretty_version' => 'dev-master',
50
- 'version' => 'dev-master',
51
- 'aliases' =>
52
- array (
53
- ),
54
- 'reference' => 'e50e27c8dfb5f2ad66e67c0f414ba8cd3ceacf66',
55
- ),
56
- 'nitropack/url' =>
57
- array (
58
- 'pretty_version' => 'dev-master',
59
- 'version' => 'dev-master',
60
- 'aliases' =>
61
- array (
62
- 0 => '9999999-dev',
63
- ),
64
- 'reference' => 'd10e616a333f5a5107137f88313c7ceba638c8a0',
65
- ),
66
- ),
67
- );
68
-
69
-
70
-
71
-
72
-
73
-
74
-
75
- public static function getInstalledPackages()
76
- {
77
- return array_keys(self::$installed['versions']);
78
- }
79
-
80
-
81
-
82
-
83
-
84
-
85
-
86
-
87
-
88
- public static function isInstalled($packageName)
89
- {
90
- return isset(self::$installed['versions'][$packageName]);
91
- }
92
-
93
-
94
-
95
-
96
-
97
-
98
-
99
-
100
-
101
-
102
-
103
-
104
-
105
-
106
- public static function satisfies(VersionParser $parser, $packageName, $constraint)
107
- {
108
- $constraint = $parser->parseConstraints($constraint);
109
- $provided = $parser->parseConstraints(self::getVersionRanges($packageName));
110
-
111
- return $provided->matches($constraint);
112
- }
113
-
114
-
115
-
116
-
117
-
118
-
119
-
120
-
121
-
122
-
123
- public static function getVersionRanges($packageName)
124
- {
125
- if (!isset(self::$installed['versions'][$packageName])) {
126
- throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
127
- }
128
-
129
- $ranges = array();
130
- if (isset(self::$installed['versions'][$packageName]['pretty_version'])) {
131
- $ranges[] = self::$installed['versions'][$packageName]['pretty_version'];
132
- }
133
- if (array_key_exists('aliases', self::$installed['versions'][$packageName])) {
134
- $ranges = array_merge($ranges, self::$installed['versions'][$packageName]['aliases']);
135
- }
136
- if (array_key_exists('replaced', self::$installed['versions'][$packageName])) {
137
- $ranges = array_merge($ranges, self::$installed['versions'][$packageName]['replaced']);
138
- }
139
- if (array_key_exists('provided', self::$installed['versions'][$packageName])) {
140
- $ranges = array_merge($ranges, self::$installed['versions'][$packageName]['provided']);
141
- }
142
-
143
- return implode(' || ', $ranges);
144
- }
145
-
146
-
147
-
148
-
149
-
150
- public static function getVersion($packageName)
151
- {
152
- if (!isset(self::$installed['versions'][$packageName])) {
153
- throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
154
- }
155
-
156
- if (!isset(self::$installed['versions'][$packageName]['version'])) {
157
- return null;
158
- }
159
-
160
- return self::$installed['versions'][$packageName]['version'];
161
- }
162
-
163
-
164
-
165
-
166
-
167
- public static function getPrettyVersion($packageName)
168
- {
169
- if (!isset(self::$installed['versions'][$packageName])) {
170
- throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
171
- }
172
-
173
- if (!isset(self::$installed['versions'][$packageName]['pretty_version'])) {
174
- return null;
175
- }
176
-
177
- return self::$installed['versions'][$packageName]['pretty_version'];
178
- }
179
-
180
-
181
-
182
-
183
-
184
- public static function getReference($packageName)
185
- {
186
- if (!isset(self::$installed['versions'][$packageName])) {
187
- throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
188
- }
189
-
190
- if (!isset(self::$installed['versions'][$packageName]['reference'])) {
191
- return null;
192
- }
193
-
194
- return self::$installed['versions'][$packageName]['reference'];
195
- }
196
-
197
-
198
-
199
-
200
-
201
- public static function getRootPackage()
202
- {
203
- return self::$installed['root'];
204
- }
205
-
206
-
207
-
208
-
209
-
210
-
211
-
212
- public static function getRawData()
213
- {
214
- return self::$installed;
215
- }
216
-
217
-
218
-
219
-
220
-
221
-
222
-
223
-
224
-
225
-
226
-
227
-
228
-
229
-
230
-
231
-
232
-
233
-
234
-
235
- public static function reload($data)
236
- {
237
- self::$installed = $data;
238
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
239
  }
1
  <?php
2
 
3
+ /*
4
+ * This file is part of Composer.
5
+ *
6
+ * (c) Nils Adermann <naderman@naderman.de>
7
+ * Jordi Boggiano <j.boggiano@seld.be>
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
 
13
  namespace Composer;
14
 
15
+ use Composer\Autoload\ClassLoader;
16
  use Composer\Semver\VersionParser;
17
 
18
+ /**
19
+ * This class is copied in every Composer installed project and available to all
20
+ *
21
+ * See also https://getcomposer.org/doc/07-runtime.md#installed-versions
22
+ *
23
+ * To require its presence, you can require `composer-runtime-api ^2.0`
24
+ */
25
  class InstalledVersions
26
  {
27
+ /**
28
+ * @var mixed[]|null
29
+ * @psalm-var array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}|array{}|null
30
+ */
31
+ private static $installed;
32
+
33
+ /**
34
+ * @var bool|null
35
+ */
36
+ private static $canGetVendors;
37
+
38
+ /**
39
+ * @var array[]
40
+ * @psalm-var array<string, array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}>
41
+ */
42
+ private static $installedByVendor = array();
43
+
44
+ /**
45
+ * Returns a list of all package names which are present, either by being installed, replaced or provided
46
+ *
47
+ * @return string[]
48
+ * @psalm-return list<string>
49
+ */
50
+ public static function getInstalledPackages()
51
+ {
52
+ $packages = array();
53
+ foreach (self::getInstalled() as $installed) {
54
+ $packages[] = array_keys($installed['versions']);
55
+ }
56
+
57
+ if (1 === \count($packages)) {
58
+ return $packages[0];
59
+ }
60
+
61
+ return array_keys(array_flip(\call_user_func_array('array_merge', $packages)));
62
+ }
63
+
64
+ /**
65
+ * Returns a list of all package names with a specific type e.g. 'library'
66
+ *
67
+ * @param string $type
68
+ * @return string[]
69
+ * @psalm-return list<string>
70
+ */
71
+ public static function getInstalledPackagesByType($type)
72
+ {
73
+ $packagesByType = array();
74
+
75
+ foreach (self::getInstalled() as $installed) {
76
+ foreach ($installed['versions'] as $name => $package) {
77
+ if (isset($package['type']) && $package['type'] === $type) {
78
+ $packagesByType[] = $name;
79
+ }
80
+ }
81
+ }
82
+
83
+ return $packagesByType;
84
+ }
85
+
86
+ /**
87
+ * Checks whether the given package is installed
88
+ *
89
+ * This also returns true if the package name is provided or replaced by another package
90
+ *
91
+ * @param string $packageName
92
+ * @param bool $includeDevRequirements
93
+ * @return bool
94
+ */
95
+ public static function isInstalled($packageName, $includeDevRequirements = true)
96
+ {
97
+ foreach (self::getInstalled() as $installed) {
98
+ if (isset($installed['versions'][$packageName])) {
99
+ return $includeDevRequirements || empty($installed['versions'][$packageName]['dev_requirement']);
100
+ }
101
+ }
102
+
103
+ return false;
104
+ }
105
+
106
+ /**
107
+ * Checks whether the given package satisfies a version constraint
108
+ *
109
+ * e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call:
110
+ *
111
+ * Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3')
112
+ *
113
+ * @param VersionParser $parser Install composer/semver to have access to this class and functionality
114
+ * @param string $packageName
115
+ * @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package
116
+ * @return bool
117
+ */
118
+ public static function satisfies(VersionParser $parser, $packageName, $constraint)
119
+ {
120
+ $constraint = $parser->parseConstraints($constraint);
121
+ $provided = $parser->parseConstraints(self::getVersionRanges($packageName));
122
+
123
+ return $provided->matches($constraint);
124
+ }
125
+
126
+ /**
127
+ * Returns a version constraint representing all the range(s) which are installed for a given package
128
+ *
129
+ * It is easier to use this via isInstalled() with the $constraint argument if you need to check
130
+ * whether a given version of a package is installed, and not just whether it exists
131
+ *
132
+ * @param string $packageName
133
+ * @return string Version constraint usable with composer/semver
134
+ */
135
+ public static function getVersionRanges($packageName)
136
+ {
137
+ foreach (self::getInstalled() as $installed) {
138
+ if (!isset($installed['versions'][$packageName])) {
139
+ continue;
140
+ }
141
+
142
+ $ranges = array();
143
+ if (isset($installed['versions'][$packageName]['pretty_version'])) {
144
+ $ranges[] = $installed['versions'][$packageName]['pretty_version'];
145
+ }
146
+ if (array_key_exists('aliases', $installed['versions'][$packageName])) {
147
+ $ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']);
148
+ }
149
+ if (array_key_exists('replaced', $installed['versions'][$packageName])) {
150
+ $ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']);
151
+ }
152
+ if (array_key_exists('provided', $installed['versions'][$packageName])) {
153
+ $ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']);
154
+ }
155
+
156
+ return implode(' || ', $ranges);
157
+ }
158
+
159
+ throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
160
+ }
161
+
162
+ /**
163
+ * @param string $packageName
164
+ * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
165
+ */
166
+ public static function getVersion($packageName)
167
+ {
168
+ foreach (self::getInstalled() as $installed) {
169
+ if (!isset($installed['versions'][$packageName])) {
170
+ continue;
171
+ }
172
+
173
+ if (!isset($installed['versions'][$packageName]['version'])) {
174
+ return null;
175
+ }
176
+
177
+ return $installed['versions'][$packageName]['version'];
178
+ }
179
+
180
+ throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
181
+ }
182
+
183
+ /**
184
+ * @param string $packageName
185
+ * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
186
+ */
187
+ public static function getPrettyVersion($packageName)
188
+ {
189
+ foreach (self::getInstalled() as $installed) {
190
+ if (!isset($installed['versions'][$packageName])) {
191
+ continue;
192
+ }
193
+
194
+ if (!isset($installed['versions'][$packageName]['pretty_version'])) {
195
+ return null;
196
+ }
197
+
198
+ return $installed['versions'][$packageName]['pretty_version'];
199
+ }
200
+
201
+ throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
202
+ }
203
+
204
+ /**
205
+ * @param string $packageName
206
+ * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference
207
+ */
208
+ public static function getReference($packageName)
209
+ {
210
+ foreach (self::getInstalled() as $installed) {
211
+ if (!isset($installed['versions'][$packageName])) {
212
+ continue;
213
+ }
214
+
215
+ if (!isset($installed['versions'][$packageName]['reference'])) {
216
+ return null;
217
+ }
218
+
219
+ return $installed['versions'][$packageName]['reference'];
220
+ }
221
+
222
+ throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
223
+ }
224
+
225
+ /**
226
+ * @param string $packageName
227
+ * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path.
228
+ */
229
+ public static function getInstallPath($packageName)
230
+ {
231
+ foreach (self::getInstalled() as $installed) {
232
+ if (!isset($installed['versions'][$packageName])) {
233
+ continue;
234
+ }
235
+
236
+ return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null;
237
+ }
238
+
239
+ throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
240
+ }
241
+
242
+ /**
243
+ * @return array
244
+ * @psalm-return array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}
245
+ */
246
+ public static function getRootPackage()
247
+ {
248
+ $installed = self::getInstalled();
249
+
250
+ return $installed[0]['root'];
251
+ }
252
+
253
+ /**
254
+ * Returns the raw installed.php data for custom implementations
255
+ *
256
+ * @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect.
257
+ * @return array[]
258
+ * @psalm-return array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}
259
+ */
260
+ public static function getRawData()
261
+ {
262
+ @trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED);
263
+
264
+ if (null === self::$installed) {
265
+ // only require the installed.php file if this file is loaded from its dumped location,
266
+ // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
267
+ if (substr(__DIR__, -8, 1) !== 'C') {
268
+ self::$installed = include __DIR__ . '/installed.php';
269
+ } else {
270
+ self::$installed = array();
271
+ }
272
+ }
273
+
274
+ return self::$installed;
275
+ }
276
+
277
+ /**
278
+ * Returns the raw data of all installed.php which are currently loaded for custom implementations
279
+ *
280
+ * @return array[]
281
+ * @psalm-return list<array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}>
282
+ */
283
+ public static function getAllRawData()
284
+ {
285
+ return self::getInstalled();
286
+ }
287
+
288
+ /**
289
+ * Lets you reload the static array from another file
290
+ *
291
+ * This is only useful for complex integrations in which a project needs to use
292
+ * this class but then also needs to execute another project's autoloader in process,
293
+ * and wants to ensure both projects have access to their version of installed.php.
294
+ *
295
+ * A typical case would be PHPUnit, where it would need to make sure it reads all
296
+ * the data it needs from this class, then call reload() with
297
+ * `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure
298
+ * the project in which it runs can then also use this class safely, without
299
+ * interference between PHPUnit's dependencies and the project's dependencies.
300
+ *
301
+ * @param array[] $data A vendor/composer/installed.php data set
302
+ * @return void
303
+ *
304
+ * @psalm-param array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>} $data
305
+ */
306
+ public static function reload($data)
307
+ {
308
+ self::$installed = $data;
309
+ self::$installedByVendor = array();
310
+ }
311
+
312
+ /**
313
+ * @return array[]
314
+ * @psalm-return list<array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}>
315
+ */
316
+ private static function getInstalled()
317
+ {
318
+ if (null === self::$canGetVendors) {
319
+ self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders');
320
+ }
321
+
322
+ $installed = array();
323
+
324
+ if (self::$canGetVendors) {
325
+ foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
326
+ if (isset(self::$installedByVendor[$vendorDir])) {
327
+ $installed[] = self::$installedByVendor[$vendorDir];
328
+ } elseif (is_file($vendorDir.'/composer/installed.php')) {
329
+ $installed[] = self::$installedByVendor[$vendorDir] = require $vendorDir.'/composer/installed.php';
330
+ if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) {
331
+ self::$installed = $installed[count($installed) - 1];
332
+ }
333
+ }
334
+ }
335
+ }
336
+
337
+ if (null === self::$installed) {
338
+ // only require the installed.php file if this file is loaded from its dumped location,
339
+ // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
340
+ if (substr(__DIR__, -8, 1) !== 'C') {
341
+ self::$installed = require __DIR__ . '/installed.php';
342
+ } else {
343
+ self::$installed = array();
344
+ }
345
+ }
346
+ $installed[] = self::$installed;
347
+
348
+ return $installed;
349
+ }
350
  }
nitropack-sdk/vendor/composer/autoload_classmap.php CHANGED
@@ -6,4 +6,5 @@ $vendorDir = dirname(dirname(__FILE__));
6
  $baseDir = dirname($vendorDir);
7
 
8
  return array(
 
9
  );
6
  $baseDir = dirname($vendorDir);
7
 
8
  return array(
9
+ 'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
10
  );
nitropack-sdk/vendor/composer/autoload_psr4.php CHANGED
@@ -7,5 +7,5 @@ $baseDir = dirname($vendorDir);
7
 
8
  return array(
9
  'NitroPack\\SDK\\' => array($baseDir . '/NitroPack/SDK'),
10
- 'NitroPack\\' => array($vendorDir . '/nitropack/httpclient/src', $vendorDir . '/nitropack/url/src'),
11
  );
7
 
8
  return array(
9
  'NitroPack\\SDK\\' => array($baseDir . '/NitroPack/SDK'),
10
+ 'NitroPack\\' => array($vendorDir . '/nitropack/url/src', $vendorDir . '/nitropack/httpclient/src'),
11
  );
nitropack-sdk/vendor/composer/autoload_real.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
- class ComposerAutoloaderInit8fcbb1a5ffa2542d92b974779798cb81
6
  {
7
  private static $loader;
8
 
@@ -22,15 +22,15 @@ class ComposerAutoloaderInit8fcbb1a5ffa2542d92b974779798cb81
22
  return self::$loader;
23
  }
24
 
25
- spl_autoload_register(array('ComposerAutoloaderInit8fcbb1a5ffa2542d92b974779798cb81', 'loadClassLoader'), true, true);
26
- self::$loader = $loader = new \Composer\Autoload\ClassLoader();
27
- spl_autoload_unregister(array('ComposerAutoloaderInit8fcbb1a5ffa2542d92b974779798cb81', 'loadClassLoader'));
28
 
29
  $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
30
  if ($useStaticLoader) {
31
- require_once __DIR__ . '/autoload_static.php';
32
 
33
- call_user_func(\Composer\Autoload\ComposerStaticInit8fcbb1a5ffa2542d92b974779798cb81::getInitializer($loader));
34
  } else {
35
  $map = require __DIR__ . '/autoload_namespaces.php';
36
  foreach ($map as $namespace => $path) {
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
+ class ComposerAutoloaderInit2e3dba6aa37dfe49fb3ede88169cdef9
6
  {
7
  private static $loader;
8
 
22
  return self::$loader;
23
  }
24
 
25
+ spl_autoload_register(array('ComposerAutoloaderInit2e3dba6aa37dfe49fb3ede88169cdef9', 'loadClassLoader'), true, true);
26
+ self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(\dirname(__FILE__)));
27
+ spl_autoload_unregister(array('ComposerAutoloaderInit2e3dba6aa37dfe49fb3ede88169cdef9', 'loadClassLoader'));
28
 
29
  $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
30
  if ($useStaticLoader) {
31
+ require __DIR__ . '/autoload_static.php';
32
 
33
+ call_user_func(\Composer\Autoload\ComposerStaticInit2e3dba6aa37dfe49fb3ede88169cdef9::getInitializer($loader));
34
  } else {
35
  $map = require __DIR__ . '/autoload_namespaces.php';
36
  foreach ($map as $namespace => $path) {
nitropack-sdk/vendor/composer/autoload_static.php CHANGED
@@ -4,7 +4,7 @@
4
 
5
  namespace Composer\Autoload;
6
 
7
- class ComposerStaticInit8fcbb1a5ffa2542d92b974779798cb81
8
  {
9
  public static $prefixLengthsPsr4 = array (
10
  'N' =>
@@ -21,16 +21,21 @@ class ComposerStaticInit8fcbb1a5ffa2542d92b974779798cb81
21
  ),
22
  'NitroPack\\' =>
23
  array (
24
- 0 => __DIR__ . '/..' . '/nitropack/httpclient/src',
25
- 1 => __DIR__ . '/..' . '/nitropack/url/src',
26
  ),
27
  );
28
 
 
 
 
 
29
  public static function getInitializer(ClassLoader $loader)
30
  {
31
  return \Closure::bind(function () use ($loader) {
32
- $loader->prefixLengthsPsr4 = ComposerStaticInit8fcbb1a5ffa2542d92b974779798cb81::$prefixLengthsPsr4;
33
- $loader->prefixDirsPsr4 = ComposerStaticInit8fcbb1a5ffa2542d92b974779798cb81::$prefixDirsPsr4;
 
34
 
35
  }, null, ClassLoader::class);
36
  }
4
 
5
  namespace Composer\Autoload;
6
 
7
+ class ComposerStaticInit2e3dba6aa37dfe49fb3ede88169cdef9
8
  {
9
  public static $prefixLengthsPsr4 = array (
10
  'N' =>
21
  ),
22
  'NitroPack\\' =>
23
  array (
24
+ 0 => __DIR__ . '/..' . '/nitropack/url/src',
25
+ 1 => __DIR__ . '/..' . '/nitropack/httpclient/src',
26
  ),
27
  );
28
 
29
+ public static $classMap = array (
30
+ 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
31
+ );
32
+
33
  public static function getInitializer(ClassLoader $loader)
34
  {
35
  return \Closure::bind(function () use ($loader) {
36
+ $loader->prefixLengthsPsr4 = ComposerStaticInit2e3dba6aa37dfe49fb3ede88169cdef9::$prefixLengthsPsr4;
37
+ $loader->prefixDirsPsr4 = ComposerStaticInit2e3dba6aa37dfe49fb3ede88169cdef9::$prefixDirsPsr4;
38
+ $loader->classMap = ComposerStaticInit2e3dba6aa37dfe49fb3ede88169cdef9::$classMap;
39
 
40
  }, null, ClassLoader::class);
41
  }
nitropack-sdk/vendor/composer/installed.json CHANGED
@@ -1,65 +1,73 @@
1
- [
2
- {
3
- "name": "nitropack/httpclient",
4
- "version": "dev-master",
5
- "version_normalized": "9999999-dev",
6
- "source": {
7
- "type": "git",
8
- "url": "git@bitbucket.org:nitropack/httpclient.git",
9
- "reference": "b1e792a4e99279d5c5b12cb0a35921d90f0043c2"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  },
11
- "require": {
12
- "nitropack/url": "dev-master"
13
- },
14
- "time": "2020-11-04T09:25:18+00:00",
15
- "type": "library",
16
- "installation-source": "source",
17
- "autoload": {
18
- "psr-4": {
19
- "NitroPack\\": "src/"
20
- }
21
- },
22
- "authors": [
23
- {
24
- "name": "Ivailo Hristov"
25
- }
26
- ],
27
- "description": "HttpClient library written in PHP, without relying on cURL nor url_fopen",
28
- "keywords": [
29
- "client",
30
- "http",
31
- "library",
32
- "php"
33
- ]
34
- },
35
- {
36
- "name": "nitropack/url",
37
- "version": "dev-master",
38
- "version_normalized": "9999999-dev",
39
- "source": {
40
- "type": "git",
41
- "url": "git@bitbucket.org:nitropack/url.git",
42
- "reference": "d10e616a333f5a5107137f88313c7ceba638c8a0"
43
- },
44
- "time": "2020-11-04T10:08:34+00:00",
45
- "type": "library",
46
- "installation-source": "source",
47
- "autoload": {
48
- "psr-4": {
49
- "NitroPack\\": "src/"
50
- }
51
- },
52
- "authors": [
53
- {
54
- "name": "Ivailo Hristov"
55
- }
56
- ],
57
- "description": "URL manipulation library",
58
- "keywords": [
59
- "library",
60
- "manipulation",
61
- "php",
62
- "url"
63
- ]
64
- }
65
- ]
1
+ {
2
+ "packages": [
3
+ {
4
+ "name": "nitropack/httpclient",
5
+ "version": "dev-master",
6
+ "version_normalized": "dev-master",
7
+ "source": {
8
+ "type": "git",
9
+ "url": "git@bitbucket.org:nitropack/httpclient.git",
10
+ "reference": "ae92c176c1800a7ebf817f39d76324664290c958"
11
+ },
12
+ "require": {
13
+ "nitropack/url": "dev-master"
14
+ },
15
+ "time": "2021-11-05T10:15:43+00:00",
16
+ "default-branch": true,
17
+ "type": "library",
18
+ "installation-source": "source",
19
+ "autoload": {
20
+ "psr-4": {
21
+ "NitroPack\\": "src/"
22
+ }
23
+ },
24
+ "authors": [
25
+ {
26
+ "name": "Ivailo Hristov"
27
+ }
28
+ ],
29
+ "description": "HttpClient library written in PHP, without relying on cURL nor url_fopen",
30
+ "keywords": [
31
+ "client",
32
+ "http",
33
+ "library",
34
+ "php"
35
+ ],
36
+ "install-path": "../nitropack/httpclient"
37
  },
38
+ {
39
+ "name": "nitropack/url",
40
+ "version": "dev-master",
41
+ "version_normalized": "dev-master",
42
+ "source": {
43
+ "type": "git",
44
+ "url": "git@bitbucket.org:nitropack/url.git",
45
+ "reference": "55b4d631e69a697a9de0fd8e1cbbfa063226a5b8"
46
+ },
47
+ "time": "2021-06-10T15:14:52+00:00",
48
+ "default-branch": true,
49
+ "type": "library",
50
+ "installation-source": "source",
51
+ "autoload": {
52
+ "psr-4": {
53
+ "NitroPack\\": "src/"
54
+ }
55
+ },
56
+ "authors": [
57
+ {
58
+ "name": "Ivailo Hristov"
59
+ }
60
+ ],
61
+ "description": "URL manipulation library",
62
+ "keywords": [
63
+ "library",
64
+ "manipulation",
65
+ "php",
66
+ "url"
67
+ ],
68
+ "install-path": "../nitropack/url"
69
+ }
70
+ ],
71
+ "dev": true,
72
+ "dev-package-names": []
73
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
nitropack-sdk/vendor/composer/installed.php CHANGED
@@ -1,44 +1,45 @@
1
- <?php return array (
2
- 'root' =>
3
- array (
4
- 'pretty_version' => 'dev-master',
5
- 'version' => 'dev-master',
6
- 'aliases' =>
7
- array (
 
 
 
8
  ),
9
- 'reference' => 'e50e27c8dfb5f2ad66e67c0f414ba8cd3ceacf66',
10
- 'name' => 'nitropack/nitropackcloud-sdk',
11
- ),
12
- 'versions' =>
13
- array (
14
- 'nitropack/httpclient' =>
15
- array (
16
- 'pretty_version' => 'dev-master',
17
- 'version' => 'dev-master',
18
- 'aliases' =>
19
- array (
20
- 0 => '9999999-dev',
21
- ),
22
- 'reference' => '2322728997a9a3e7f4adbb41229b347cce2ebab0',
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
  ),
24
- 'nitropack/nitropackcloud-sdk' =>
25
- array (
26
- 'pretty_version' => 'dev-master',
27
- 'version' => 'dev-master',
28
- 'aliases' =>
29
- array (
30
- ),
31
- 'reference' => 'e50e27c8dfb5f2ad66e67c0f414ba8cd3ceacf66',
32
- ),
33
- 'nitropack/url' =>
34
- array (
35
- 'pretty_version' => 'dev-master',
36
- 'version' => 'dev-master',
37
- 'aliases' =>
38
- array (
39
- 0 => '9999999-dev',
40
- ),
41
- 'reference' => 'd10e616a333f5a5107137f88313c7ceba638c8a0',
42
- ),
43
- ),
44
  );
1
+ <?php return array(
2
+ 'root' => array(
3
+ 'pretty_version' => 'dev-master',
4
+ 'version' => 'dev-master',
5
+ 'type' => 'package',
6
+ 'install_path' => __DIR__ . '/../../',
7
+ 'aliases' => array(),
8
+ 'reference' => '13fbb0581464ff6224e9905cc422ba0f91e5a232',
9
+ 'name' => 'nitropack/nitropackcloud-sdk',
10
+ 'dev' => true,
11
  ),
12
+ 'versions' => array(
13
+ 'nitropack/httpclient' => array(
14
+ 'pretty_version' => 'dev-master',
15
+ 'version' => 'dev-master',
16
+ 'type' => 'library',
17
+ 'install_path' => __DIR__ . '/../nitropack/httpclient',
18
+ 'aliases' => array(
19
+ 0 => '9999999-dev',
20
+ ),
21
+ 'reference' => 'ae92c176c1800a7ebf817f39d76324664290c958',
22
+ 'dev_requirement' => false,
23
+ ),
24
+ 'nitropack/nitropackcloud-sdk' => array(
25
+ 'pretty_version' => 'dev-master',
26
+ 'version' => 'dev-master',
27
+ 'type' => 'package',
28
+ 'install_path' => __DIR__ . '/../../',
29
+ 'aliases' => array(),
30
+ 'reference' => '13fbb0581464ff6224e9905cc422ba0f91e5a232',
31
+ 'dev_requirement' => false,
32
+ ),
33
+ 'nitropack/url' => array(
34
+ 'pretty_version' => 'dev-master',
35
+ 'version' => 'dev-master',
36
+ 'type' => 'library',
37
+ 'install_path' => __DIR__ . '/../nitropack/url',
38
+ 'aliases' => array(
39
+ 0 => '9999999-dev',
40
+ ),
41
+ 'reference' => '55b4d631e69a697a9de0fd8e1cbbfa063226a5b8',
42
+ 'dev_requirement' => false,
43
+ ),
44
  ),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
  );
nitropack-sdk/vendor/nitropack/httpclient/src/HttpClient.php CHANGED
@@ -40,6 +40,25 @@ class HttpClient {
40
  }
41
  }
42
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
  public static function _isConnectionValid($sock, $readRemainder = false) {
44
  $isValidStream = is_resource($sock) && get_resource_type($sock) != "Unknown";
45
  if ($isValidStream && $readRemainder) {
@@ -120,6 +139,7 @@ class HttpClient {
120
  public $buffer = '';
121
  public $headers = array();
122
  public $post_data = "";
 
123
  public $request_headers = array();
124
  public $http_version = '1.1';
125
  public $status_code = -1;
@@ -183,9 +203,9 @@ class HttpClient {
183
  private $hostsOverride;
184
  private $portsOverride;
185
 
186
- private $proxyAddr;
187
- private $proxyPort;
188
- private $proxyScheme;
189
 
190
  public function __construct($URL, $httpConfig = NULL) {
191
  $this->prevUrl = NULL;
@@ -211,6 +231,16 @@ class HttpClient {
211
  $this->setHeader('User-Agent', $this->config->getUserAgent());
212
  }
213
 
 
 
 
 
 
 
 
 
 
 
214
  $this->initBodyStream();
215
 
216
  $this->isAsync = false;
@@ -221,6 +251,25 @@ class HttpClient {
221
  $this->state = HttpClientState::READY;
222
  $this->hostsOverride = array();
223
  $this->portsOverride = array();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
224
  }
225
 
226
  public function __destruct() {
@@ -252,6 +301,13 @@ class HttpClient {
252
  self::_disconnect($this->sock);
253
  }
254
 
 
 
 
 
 
 
 
255
  public function setURL($URL, $resetRedirects = true) {
256
  if ($resetRedirects) {
257
  $this->redirects_count = 0;
@@ -262,8 +318,18 @@ class HttpClient {
262
  $this->parseURL();
263
  }
264
 
265
- public function setPostData($data) {
266
- $this->post_data = !empty($data) ? http_build_query($data) : "";
 
 
 
 
 
 
 
 
 
 
267
  }
268
 
269
  public function setVerifySSL($status) {
@@ -451,16 +517,28 @@ class HttpClient {
451
  }
452
 
453
  public function setProxy($proxy = NULL) {
454
- if ($proxy) {
455
- $url = new Url($proxy);
456
- $this->proxyScheme = strtolower($url->getScheme());
457
- $this->proxyAddr = $this->gethostbyname($url->getHost());
458
- $this->proxyPort = $url->getPort();
459
- } else {
460
- $this->proxyScheme = NULL;
461
- $this->proxyAddr = NULL;
462
- $this->proxyPort = NULL;
 
 
 
 
 
 
 
 
 
 
463
  }
 
 
464
  }
465
 
466
  public function hostOverride($host, $dest) {
@@ -549,6 +627,9 @@ class HttpClient {
549
  if ($this->isAsync) {
550
  $this->asyncQueue = array();
551
  $this->asyncQueue[] = array($this, 'connect');
 
 
 
552
  $this->asyncQueue[] = array($this, 'enableSSL');
553
  $this->asyncQueue[] = array($this, 'sendRequest');
554
  $this->asyncQueue[] = array($this, 'download');
@@ -558,6 +639,9 @@ class HttpClient {
558
  call_user_func(HttpClient::$fetch_start_callback, $this->URL, false);
559
  }
560
  $this->connect();
 
 
 
561
  $this->enableSSL();
562
  $this->sendRequest();
563
  $this->download();
@@ -673,9 +757,17 @@ class HttpClient {
673
  public function connect() {
674
  $this->state = HttpClientState::CONNECT;
675
  BEGIN_CONNECT:
676
- $addr = $this->proxyAddr ? $this->proxyAddr : $this->addr;
677
- $port = $this->proxyPort ? $this->proxyPort : $this->port;
678
- $reuseKey = implode(':', array($addr, $port));
 
 
 
 
 
 
 
 
679
  if (isset(self::$connections[$reuseKey])) {
680
  foreach (self::$connections[$reuseKey] as $sock) {
681
  if (!in_array($sock, HttpClient::$free_connections)) continue;
@@ -683,6 +775,7 @@ class HttpClient {
683
  $this->sock = $sock;
684
  if ($this->isConnectionValid()) {// check if the connection is still alive
685
  $this->acquireConnection();
 
686
  return true;
687
  } else {
688
  $this->disconnect(); // Remove the inactive connection
@@ -736,7 +829,7 @@ class HttpClient {
736
 
737
  if($this->sock === false) {
738
  $this->addr = $this->gethostbyname($this->host, true);
739
- if ($this->addr) {
740
  if ($this->isAsync) {
741
  return false;
742
  } else {
@@ -758,9 +851,29 @@ class HttpClient {
758
 
759
  HttpClient::$secure_connections[(int)$this->sock] = false;
760
  $this->acquireConnection();
 
761
  return true;
762
  }
763
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
764
  public function enableSSL() {
765
  $this->state = HttpClientState::SSL_HANDSHAKE;
766
  if ($this->isSecure()) return true;
@@ -768,13 +881,17 @@ class HttpClient {
768
 
769
  $crypto_method = STREAM_CRYPTO_METHOD_TLS_CLIENT;
770
 
771
- if (defined('STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT')) {
 
 
 
 
772
  $crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT;
773
  $crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT;
774
  }
775
 
776
  //set_error_handler(array($this, 'error_sink'));
777
- $scheme = $this->proxyScheme ? $this->proxyScheme : $this->scheme;
778
  if ($scheme == 'https') {
779
  if (!$this->ssl_negotiation_start) {
780
  $this->ssl_negotiation_start = microtime(true);
@@ -1220,16 +1337,18 @@ class HttpClient {
1220
  }
1221
 
1222
  $cookies_combined = array();
1223
- foreach ($this->cookies as $domain=>$cookies) {
1224
- if (preg_match("/".preg_quote(ltrim($domain, "."))."$/", $this->host)) {
1225
- foreach ($cookies as $name=>$value) {
1226
- if (is_array($value)) {
1227
- foreach ($value as $k=>$v) {
1228
- $key = $name . "[$k]";
1229
- $cookies_combined[] = $key."=".$v;
 
 
 
 
1230
  }
1231
- } else {
1232
- $cookies_combined[] = $name."=".$value;
1233
  }
1234
  }
1235
  }
@@ -1245,8 +1364,14 @@ class HttpClient {
1245
  }
1246
  }
1247
 
1248
- if ($this->post_data && $this->http_method == "POST") {
1249
- $headers[] = "content-type: application/x-www-form-urlencoded";
 
 
 
 
 
 
1250
  $headers[] = "content-length: " . strlen($this->post_data);
1251
  if ($this->debug) {
1252
  var_dump($headers);
@@ -1309,6 +1434,8 @@ class HttpClient {
1309
  private function error_sink($errno, $errstr) {}
1310
  }
1311
 
 
 
1312
  class URLException extends Exception {}
1313
  class URLEmptyException extends Exception {}
1314
  class URLInvalidException extends Exception {}
40
  }
41
  }
42
 
43
+ public static function drainConnections() {
44
+ $connectionsCount = 0;
45
+ $connectionsRemovedCount = 0;
46
+ foreach (self::$connections as $key => &$connections) {
47
+ $connectionsCount += count($connections);
48
+ foreach ($connections as $index => $con) {
49
+ if (self::_isConnectionValid($con, true)) {
50
+ $connectionsRemovedCount++;
51
+ self::_disconnect($con);
52
+ }
53
+ array_splice($connections, $index, 1);
54
+ }
55
+
56
+ if (empty($connections)) {
57
+ unset(self::$connections[$key]);
58
+ }
59
+ }
60
+ }
61
+
62
  public static function _isConnectionValid($sock, $readRemainder = false) {
63
  $isValidStream = is_resource($sock) && get_resource_type($sock) != "Unknown";
64
  if ($isValidStream && $readRemainder) {
139
  public $buffer = '';
140
  public $headers = array();
141
  public $post_data = "";
142
+ public $post_data_type = NULL;
143
  public $request_headers = array();
144
  public $http_version = '1.1';
145
  public $status_code = -1;
203
  private $hostsOverride;
204
  private $portsOverride;
205
 
206
+ private $proxy;
207
+ private $privateIpRanges;
208
+ private $isReusingConnection;
209
 
210
  public function __construct($URL, $httpConfig = NULL) {
211
  $this->prevUrl = NULL;
231
  $this->setHeader('User-Agent', $this->config->getUserAgent());
232
  }
233
 
234
+ if ($this->config->getProxy()) {
235
+ $this->setProxy($this->config->getProxy());
236
+ }
237
+
238
+ if ($this->config->getHostOverrides()) {
239
+ foreach ($this->config->getHostOverrides() as $host => $dest) {
240
+ $this->hostOverride($host, $dest);
241
+ }
242
+ }
243
+
244
  $this->initBodyStream();
245
 
246
  $this->isAsync = false;
251
  $this->state = HttpClientState::READY;
252
  $this->hostsOverride = array();
253
  $this->portsOverride = array();
254
+
255
+ if (function_exists("getenv")) {
256
+ $proxyVars = ["NITROPACK_HTTP_PROXY", "ALL_PROXY", "HTTP_PROXY", "http_proxy"];
257
+ foreach ($proxyVars as $varName) {
258
+ $proxyEnv = getenv($varName);
259
+ if (!empty($proxyEnv)) {
260
+ $proxyUrl = new Url($proxyEnv);
261
+ switch ($proxyUrl->getScheme()) {
262
+ case "socks":
263
+ case "socks4":
264
+ case "socks4a":
265
+ if ($proxyUrl->getHost()) {
266
+ $this->setProxy(new HttpClientSocks4Proxy($proxyUrl->getHost(), $proxyUrl->getPort()));
267
+ }
268
+ }
269
+ break;
270
+ }
271
+ }
272
+ }
273
  }
274
 
275
  public function __destruct() {
301
  self::_disconnect($this->sock);
302
  }
303
 
304
+ public function abort() {
305
+ $this->disconnect();
306
+ if (!empty($this->asyncQueue)) {
307
+ $this->asyncQueue = [];
308
+ }
309
+ }
310
+
311
  public function setURL($URL, $resetRedirects = true) {
312
  if ($resetRedirects) {
313
  $this->redirects_count = 0;
318
  $this->parseURL();
319
  }
320
 
321
+ public function setPostData($data, $type = NULL) {
322
+ if (!empty($data)) {
323
+ $this->post_data = is_array($data) ? http_build_query($data) : $data;
324
+ } else {
325
+ $this->post_data = "";
326
+ }
327
+
328
+ if (!$type) {
329
+ $this->post_data_type = "application/x-www-form-urlencoded";
330
+ } else {
331
+ $this->post_data_type = $type;
332
+ }
333
  }
334
 
335
  public function setVerifySSL($status) {
517
  }
518
 
519
  public function setProxy($proxy = NULL) {
520
+ $this->proxy = $proxy;
521
+ }
522
+
523
+ private function shouldUseProxy() {
524
+ return $this->proxy && (!$this->isPrivateIp($this->addr) || $this->proxy->shouldForceOnPrivate());
525
+ }
526
+
527
+ private function isPrivateIp($ip) {
528
+ if (!$this->privateIpRanges) {
529
+ $this->privateIpRanges = array(
530
+ array(ip2long("10.0.0.0"), ip2long("10.255.255.255")),
531
+ array(ip2long("172.16.0.0"), ip2long("172.31.255.255")),
532
+ array(ip2long("192.168.0.0"), ip2long("192.168.255.255"))
533
+ );
534
+ }
535
+
536
+ $ipLong = ip2long($ip);
537
+ foreach ($this->privateIpRanges as $range) {
538
+ if ($ipLong >= $range[0] && $ipLong <= $range[1]) return true;
539
  }
540
+
541
+ return false;
542
  }
543
 
544
  public function hostOverride($host, $dest) {
627
  if ($this->isAsync) {
628
  $this->asyncQueue = array();
629
  $this->asyncQueue[] = array($this, 'connect');
630
+ if ($this->shouldUseProxy() && $this->proxy instanceof HttpClientSocksProxy) {
631
+ $this->asyncQueue[] = array($this, 'socksProxyConnect');
632
+ }
633
  $this->asyncQueue[] = array($this, 'enableSSL');
634
  $this->asyncQueue[] = array($this, 'sendRequest');
635
  $this->asyncQueue[] = array($this, 'download');
639
  call_user_func(HttpClient::$fetch_start_callback, $this->URL, false);
640
  }
641
  $this->connect();
642
+ if ($this->shouldUseProxy() && $this->proxy instanceof HttpClientSocksProxy) {
643
+ $this->socksProxyConnect();
644
+ }
645
  $this->enableSSL();
646
  $this->sendRequest();
647
  $this->download();
757
  public function connect() {
758
  $this->state = HttpClientState::CONNECT;
759
  BEGIN_CONNECT:
760
+ $this->isReusingConnection = false;
761
+ if ($this->shouldUseProxy()) {
762
+ $addr = $this->proxy->getAddr();
763
+ $port = $this->proxy->getPort();
764
+ } else {
765
+ $addr = $this->addr;
766
+ $port = $this->port;
767
+ }
768
+
769
+ $host = $this->host;
770
+ $reuseKey = implode(':', array($host, $port));
771
  if (isset(self::$connections[$reuseKey])) {
772
  foreach (self::$connections[$reuseKey] as $sock) {
773
  if (!in_array($sock, HttpClient::$free_connections)) continue;
775
  $this->sock = $sock;
776
  if ($this->isConnectionValid()) {// check if the connection is still alive
777
  $this->acquireConnection();
778
+ $this->isReusingConnection = true;
779
  return true;
780
  } else {
781
  $this->disconnect(); // Remove the inactive connection
829
 
830
  if($this->sock === false) {
831
  $this->addr = $this->gethostbyname($this->host, true);
832
+ if ($this->addr && !$this->shouldUseProxy()) {
833
  if ($this->isAsync) {
834
  return false;
835
  } else {
851
 
852
  HttpClient::$secure_connections[(int)$this->sock] = false;
853
  $this->acquireConnection();
854
+
855
  return true;
856
  }
857
 
858
+ public function socksProxyConnect() {
859
+ if ($this->shouldUseProxy() && !$this->isReusingConnection) {
860
+ try {
861
+ if ($this->isAsync) {
862
+ return $this->proxy->connectAsync($this->sock, $this->addr, $this->port, $this->host);
863
+ } else {
864
+ stream_set_blocking($this->sock, true);
865
+ $this->proxy->connect($this->sock, $this->addr, $this->port, $this->host);
866
+ stream_set_blocking($this->sock, false);
867
+ }
868
+ } catch (ProxyConnectException $e) {
869
+ $this->disconnect();
870
+ throw $e;
871
+ }
872
+ } else {
873
+ return true;
874
+ }
875
+ }
876
+
877
  public function enableSSL() {
878
  $this->state = HttpClientState::SSL_HANDSHAKE;
879
  if ($this->isSecure()) return true;
881
 
882
  $crypto_method = STREAM_CRYPTO_METHOD_TLS_CLIENT;
883
 
884
+ if (defined('STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT')) {
885
+ $crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT;
886
+ $crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT;
887
+ $crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT;
888
+ } else if (defined('STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT')) {
889
  $crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT;
890
  $crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT;
891
  }
892
 
893
  //set_error_handler(array($this, 'error_sink'));
894
+ $scheme = $this->scheme;
895
  if ($scheme == 'https') {
896
  if (!$this->ssl_negotiation_start) {
897
  $this->ssl_negotiation_start = microtime(true);
1337
  }
1338
 
1339
  $cookies_combined = array();
1340
+ if (is_array($this->cookies)) {
1341
+ foreach ($this->cookies as $domain=>$cookies) {
1342
+ if (preg_match("/".preg_quote(ltrim($domain, "."))."$/", $this->host)) {
1343
+ foreach ($cookies as $name=>$value) {
1344
+ if (is_array($value)) {
1345
+ foreach ($value as $k=>$v) {
1346
+ $key = $name . "[$k]";
1347
+ $cookies_combined[] = $key."=".$v;
1348
+ }
1349
+ } else {
1350
+ $cookies_combined[] = $name."=".$value;
1351
  }
 
 
1352
  }
1353
  }
1354
  }
1364
  }
1365
  }
1366
 
1367
+ if (empty($this->request_headers["accept"])) {
1368
+ $headers[] = "accept: */*";
1369
+ }
1370
+
1371
+ if ($this->post_data && ($this->http_method == "POST" || $this->http_method == "PUT") ) {
1372
+ if ($this->post_data_type) {
1373
+ $headers[] = "content-type: " . $this->post_data_type;
1374
+ }
1375
  $headers[] = "content-length: " . strlen($this->post_data);
1376
  if ($this->debug) {
1377
  var_dump($headers);
1434
  private function error_sink($errno, $errstr) {}
1435
  }
1436
 
1437
+ register_shutdown_function(array("\NitroPack\HttpClient", "drainConnections"));
1438
+
1439
  class URLException extends Exception {}
1440
  class URLEmptyException extends Exception {}
1441
  class URLInvalidException extends Exception {}
nitropack-sdk/vendor/nitropack/httpclient/src/HttpClientMulti.php CHANGED
@@ -8,6 +8,7 @@ class HttpClientMulti {
8
  private $errorCallback;
9
  private $returnClients;
10
  private $intervals;
 
11
 
12
  public function __construct() {
13
  $this->clients = array();
@@ -15,6 +16,7 @@ class HttpClientMulti {
15
  $this->successCallback = NULL;
16
  $this->errorCallback = NULL;
17
  $this->returnClients = true;
 
18
  }
19
 
20
  public function returnClients($status) {
@@ -23,6 +25,7 @@ class HttpClientMulti {
23
 
24
  public function push($client) {
25
  $this->clients[] = $client;
 
26
  }
27
 
28
  public function getClients() {
@@ -139,7 +142,10 @@ class HttpClientMulti {
139
  } else {
140
  $microtimeout = (int)(min($remainingTimeouts) * 1000000);
141
  if ($microtimeout > 0) {
142
- stream_select($read, $write, $except, 0, $microtimeout);
 
 
 
143
  }
144
  }
145
  }
@@ -171,8 +177,36 @@ class HttpClientMulti {
171
  return [$succeededClients, $failedClients];
172
  }
173
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
174
  private function removeClient($client) {
175
  $index = array_search($client, $this->clients, true);
176
- array_splice($this->clients, $index, 1);
 
 
 
 
 
 
177
  }
178
  }
8
  private $errorCallback;
9
  private $returnClients;
10
  private $intervals;
11
+ private $clientRegistrationTimes;
12
 
13
  public function __construct() {
14
  $this->clients = array();
16
  $this->successCallback = NULL;
17
  $this->errorCallback = NULL;
18
  $this->returnClients = true;
19
+ $this->clientRegistrationTimes = new \SplObjectStorage();
20
  }
21
 
22
  public function returnClients($status) {
25
 
26
  public function push($client) {
27
  $this->clients[] = $client;
28
+ $this->clientRegistrationTimes->attach($client, time());
29
  }
30
 
31
  public function getClients() {
142
  } else {
143
  $microtimeout = (int)(min($remainingTimeouts) * 1000000);
144
  if ($microtimeout > 0) {
145
+ $streamsWithChange = stream_select($read, $write, $except, 0, 0);
146
+ if ($streamsWithChange === 0) {
147
+ usleep(20000);// 20ms
148
+ }
149
  }
150
  }
151
  }
177
  return [$succeededClients, $failedClients];
178
  }
179
 
180
+ public function evictStuckClients($timeout = 300) {
181
+ $evictedClients = [];
182
+ $now = time();
183
+ foreach ($this->clients as $client) {
184
+ try {
185
+ $clientRegistrationTime = $this->clientRegistrationTimes->offsetGet($client);
186
+ } catch (\UnexpectedValueException $e) {
187
+ $clientRegistrationTime = 0;
188
+ // Weird client - remove it
189
+ }
190
+
191
+ if ($now - $clientRegistrationTime >= $timeout) {
192
+ $evictedClients[] = $client;
193
+ //echo sprintf("Evicting stuck client for %s in state %s \n", $client->URL, $client->getState());
194
+ $client->abort();
195
+ $this->removeClient($client);
196
+ }
197
+ }
198
+
199
+ return $evictedClients;
200
+ }
201
+
202
  private function removeClient($client) {
203
  $index = array_search($client, $this->clients, true);
204
+ if ($index !== false) { // Index can be false if the client has been evicted earlier
205
+ array_splice($this->clients, $index, 1);
206
+ }
207
+
208
+ if ($this->clientRegistrationTimes->offsetExists($client)) { // Offset may not exist if the client has been evicted earlier
209
+ $this->clientRegistrationTimes->detach($client);
210
+ }
211
  }
212
  }
nitropack-sdk/vendor/nitropack/httpclient/src/HttpClientProxy.php ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace NitroPack;
3
+
4
+ class HttpClientProxy {
5
+ protected $addr;
6
+ protected $port;
7
+ protected $forceOnPrivate;
8
+
9
+ public function __construct($ip, $port, $forceOnPrivate = false) {
10
+ $this->addr = $ip;
11
+ $this->port = $port ? $port : 1080;
12
+ $this->forceOnPrivate = $forceOnPrivate;
13
+ }
14
+
15
+ public function getAddr() {
16
+ return $this->addr;
17
+ }
18
+
19
+ public function getPort() {
20
+ return $this->port;
21
+ }
22
+
23
+ public function shouldForceOnPrivate() {
24
+ return $this->forceOnPrivate;
25
+ }
26
+ }
nitropack-sdk/vendor/nitropack/httpclient/src/HttpClientSocks4Proxy.php ADDED
@@ -0,0 +1,100 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace NitroPack;
4
+
5
+ class HttpClientSocks4Proxy extends HttpClientSocksProxy {
6
+ private $isConnectPending;
7
+ private $resolveOnProxy;
8
+ private $sendFrame;
9
+ private $recvFrame;
10
+
11
+ public function __construct($ip, $port, $resolveOnProxy = false) {
12
+ parent::__construct($ip, $port);
13
+
14
+ $this->isConnectPending = false;
15
+ $this->resolveOnProxy = $resolveOnProxy;
16
+ $this->sendFrame = "";
17
+ $this->recvFrame = "";
18
+ }
19
+
20
+ public function resolveOnProxy($status) {
21
+ $this->resolveOnProxy = $status;
22
+ }
23
+
24
+ public function connect($sock, $ip, $port, $domain = NULL) {
25
+ $this->prepareSendFrame($ip, $port, $domain);
26
+ $this->recvFrame = "";
27
+
28
+ if (@fwrite($sock, $this->sendFrame) === false) {
29
+ throw new ProxyConnectException("Proxy communication error: cannot send CONNECT frame");
30
+ }
31
+
32
+ $this->recvFrame = @fread($sock, 8);
33
+
34
+ if (!$this->recvFrame) {
35
+ throw new ProxyConnectException("Empty proxy response");
36
+ }
37
+
38
+ $bytes = unpack("CVN/CCD/SDSTPORT/LDSTIP", $this->recvFrame);
39
+
40
+ if ($bytes["CD"] != 90) {
41
+ throw new ProxyConnectException("Connection rejected by proxy with code " . $bytes["CD"]);
42
+ }
43
+
44
+ return true;
45
+ }
46
+
47
+ public function connectAsync($sock, $ip, $port, $domain = NULL) {
48
+ if (!$this->isConnectPending) {
49
+ $this->prepareSendFrame($ip, $port, $domain);
50
+ $this->recvFrame = "";
51
+ $this->isConnectPending = true;
52
+ }
53
+
54
+ if ($this->sendFrame) { // We have more data to send here
55
+ $written = @fwrite($sock, $this->sendFrame);
56
+ if ($written === false) {
57
+ $this->isConnectPending = false;
58
+ throw new ProxyConnectException("Proxy communication error: cannot send CONNECT frame");
59
+ } else {
60
+ $this->sendFrame = substr($this->sendFrame, $written);
61
+ return false;
62
+ }
63
+ } else { // Read te proxy's reply
64
+ $this->recvFrame .= @fread($sock, 8);
65
+
66
+ if ($this->recvFrame === false) {
67
+ throw new ProxyConnectException("Proxy communication error: cannot read CONNECT reply frame");
68
+ } else if (strlen($this->recvFrame) == 8) {
69
+ $bytes = unpack("CVN/CCD/SDSTPORT/LDSTIP", $this->recvFrame);
70
+
71
+ if ($bytes["CD"] != 90) {
72
+ throw new ProxyConnectException("Connection rejected by proxy with code " . $bytes["CD"]);
73
+ }
74
+
75
+ $this->isConnectPending = false;
76
+ return true;
77
+ } else {
78
+ return false;
79
+ }
80
+ }
81
+
82
+ $this->isConnectPending = false;
83
+ return true;
84
+ }
85
+
86
+ private function prepareSendFrame($ip, $port, $domain = NULL) {
87
+ if ($domain && $this->resolveOnProxy) $ip = "0.0.0.1";
88
+
89
+ $ipInt = ip2long($ip);
90
+ if ($ipInt === -1 || $ipInt === false) {
91
+ throw new ProxyConnectException("Invalid destination IP");
92
+ }
93
+
94
+ $this->sendFrame = pack("CCnNx", 4, 1, $port, $ipInt);
95
+
96
+ if ($domain && $this->resolveOnProxy) {
97
+ $this->sendFrame .= $domain . pack("x");
98
+ }
99
+ }
100
+ }
nitropack-sdk/vendor/nitropack/httpclient/src/HttpClientSocksProxy.php ADDED
@@ -0,0 +1,4 @@
 
 
 
 
1
+ <?php
2
+ namespace NitroPack;
3
+
4
+ class HttpClientSocksProxy extends HttpClientProxy {}
nitropack-sdk/vendor/nitropack/httpclient/src/HttpConfig.php CHANGED
@@ -5,11 +5,15 @@ class HttpConfig {
5
  private $cookieJar;
6
  private $referer;
7
  private $userAgent;
 
 
8
 
9
  public function __construct() {
10
  $this->cookieJar = NULL;
11
  $this->referer = NULL;
12
  $this->userAgent = NULL;
 
 
13
  }
14
 
15
  public function setCookieJar($cookieJar = NULL) {
@@ -35,4 +39,20 @@ class HttpConfig {
35
  public function getUserAgent() {
36
  return $this->userAgent;
37
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
  }
5
  private $cookieJar;
6
  private $referer;
7
  private $userAgent;
8
+ private $proxy;
9
+ private $hostOverrides;
10
 
11
  public function __construct() {
12
  $this->cookieJar = NULL;
13
  $this->referer = NULL;
14
  $this->userAgent = NULL;
15
+ $this->proxy = NULL;
16
+ $this->hostOverrides = array();
17
  }
18
 
19
  public function setCookieJar($cookieJar = NULL) {
39
  public function getUserAgent() {
40
  return $this->userAgent;
41
  }
42
+
43
+ public function setProxy($proxy) {
44
+ $this->proxy = $proxy;
45
+ }
46
+
47
+ public function getProxy() {
48
+ return $this->proxy;
49
+ }
50
+
51
+ public function setHostOverride($host, $dest) {
52
+ $this->hostOverrides[$host] = $dest;
53
+ }
54
+
55
+ public function getHostOverrides() {
56
+ return $this->hostOverrides;
57
+ }
58
  }
nitropack-sdk/vendor/nitropack/httpclient/src/ProxyConnectException.php ADDED
@@ -0,0 +1,4 @@
 
 
 
 
1
+ <?php
2
+ namespace NitroPack;
3
+
4
+ class ProxyConnectException extends \RuntimeException {}
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: 5.8
6
  Requires PHP: 5.3
7
- Stable tag: 1.5.7
8
  License: GNU General Public License, version 2
9
  License URI: https://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -13,7 +13,7 @@ Everything you need for a fast website. Simple set up, easy to use, awesome supp
13
  == Description ==
14
  NitroPack is the all-in-one performance optimization service. It combines **everything** you need for a lightning-fast website. Image optimization, code minification, caching, CDN, lazy loading - you name it, NitroPack has it.
15
 
16
- [youtube https://www.youtube.com/watch?v=IKbHcOZ3Plw]
17
 
18
  NitroPack performs all optimizations in the cloud. This makes it a **very lightweight** solution with a **lower CPU overhead** compared to standard caching plugins.
19
 
@@ -169,6 +169,18 @@ No. We’ve designed NitroPack to be a very lightweight solution that adds no CP
169
 
170
  == Changelog ==
171
 
 
 
 
 
 
 
 
 
 
 
 
 
172
  = 1.5.7 =
173
  * New Feature: Compatibility with Vimexx
174
  * Improvement: Make some of NitroPack's requests even lighter weight
4
  Requires at least: 4.7
5
  Tested up to: 5.8
6
  Requires PHP: 5.3
7
+ Stable tag: 1.5.8
8
  License: GNU General Public License, version 2
9
  License URI: https://www.gnu.org/licenses/gpl-2.0.html
10
 
13
  == Description ==
14
  NitroPack is the all-in-one performance optimization service. It combines **everything** you need for a lightning-fast website. Image optimization, code minification, caching, CDN, lazy loading - you name it, NitroPack has it.
15
 
16
+ [youtube https://www.youtube.com/watch?v=jLzYUKSo5Jo]
17
 
18
  NitroPack performs all optimizations in the cloud. This makes it a **very lightweight** solution with a **lower CPU overhead** compared to standard caching plugins.
19
 
169
 
170
  == Changelog ==
171
 
172
+ = 1.5.8 =
173
+ * New Feature: Compatibility with Savii hosting
174
+ * New Feature: Basic compatibility with Pressable's caching layer
175
+ * New Feature: Basic compatibility with Sucuri as a caching layer
176
+ * New Feature: Admins can now receive notifications related to system events
177
+ * Improvement: Improved compatibility with Cloudflare's APO
178
+ * Improvement: Improved compatibility with Rocket.net
179
+ * Improvement: Overall stability/compatibility improvements
180
+ * Improvement: A better way to detect the popular Cookie Notice plugin
181
+ * Improvement: Compatibility with WP Engine's Smart Plugin Updater
182
+ * Bug fix: Resolve an issue when running on PHP 5.6
183
+
184
  = 1.5.7 =
185
  * New Feature: Compatibility with Vimexx
186
  * Improvement: Make some of NitroPack's requests even lighter weight
view/dashboard.php CHANGED
@@ -4,6 +4,26 @@
4
  <?php nitropack_display_admin_notices(); ?>
5
  </div>
6
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7
  <div class="row">
8
  <div class="col-md-6 mb-3">
9
  <div class="card-overlay-blurrable np-widget" id="optimizations-widget">
@@ -443,95 +463,132 @@
443
  }
444
 
445
  var getOptimizations = _ => {
446
- $.ajax({
447
- url: '<?php echo $optimizationDetailsUrl; ?>',
448
- type: 'GET',
449
- dataType: 'json',
450
- success: function(data) {
451
- $('[data-last-cache-purge]').text(data.last_cache_purge.timeAgo);
452
- if (data.last_cache_purge.reason) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
453
  $('[data-purge-reason]').text(data.last_cache_purge.reason);
454
  $('#last-cache-purge-reason').show();
455
  } else {
456
- $('#last-cache-purge-reason').hide();
457
- }
458
 
459
- if (data.pending_count) {
460
- $("#pending-optimizations-count").text(data.pending_count);
461
- $("#pending-optimizations-section").show();
462
  } else {
463
  $("#pending-optimizations-section").hide();
464
- }
465
-
466
- $('[data-optimized-pages-desktop]').text(data.optimized_pages.desktop);
467
- $('[data-optimized-pages-mobile]').text(data.optimized_pages.mobile);
468
- $('[data-optimized-pages-tablet]').text(data.optimized_pages.tablet);
469
- $('[data-optimized-pages-total]').text(data.optimized_pages.total);
470
 
471
- $("#optimizations-widget").cardOverlay("clear");
472
- },
473
- error: function() {
474
- //Overlay.error("An unexpected error has occurred.", 10000, true);
475
- },
476
- complete: function() {
477
- if (!getOptimizationsTimeout) {
478
- getOptimizationsTimeout = setTimeout(function() {getOptimizationsTimeout = null; getOptimizations();}, 60000);
479
- }
 
 
480
  }
481
- })
482
  }
483
 
484
  var getPlan = _ => {
485
- $.ajax({
486
- url: '<?php echo $planDetailsUrl; ?>',
487
- type: 'GET',
488
- dataType: 'json',
489
- success: function(data) {
490
- $('[data-plan-title]').text(data.plan_title);
491
- $('[data-next-billing]').text(data.next_billing ? data.next_billing : 'N/A');
492
- $('[data-next-reset]').text(data.next_reset ? data.next_reset : 'N/A');
493
-
494
- for (prop in data) {
495
- if (prop.indexOf("show_") === 0) continue;
496
- if (prop.indexOf("label_") === 0) continue;
497
- if (prop.indexOf("max_") === 0) continue;
498
- if (
499
- typeof data["show_" + prop] != "undefined" &&
500
- data["show_" + prop] &&
501
- typeof data["label_" + prop] != "undefined" &&
502
- typeof data["max_" + prop] != "undefined"
503
- ) {
504
- let propertyLabel = data["label_" + prop];
505
- let propertyValue = data[prop];
506
- let propertyLimit = data["max_" + prop];
507
- $("#plan-quotas").append('<li class="list-group-item px-0 d-flex justify-content-between align-items-center">' + propertyLabel + ' <span><span data-optimizations>' + propertyValue + '</span> out of <span data-max-optimizations>' + propertyLimit + '</span></span></li>');
508
- }
509
- }
510
-
511
- $("#plan-details-widget").cardOverlay("clear");
512
- },
513
- error: function() {
514
- $("#plan-details-widget").cardOverlay("error", {message: "Error while fetching plan data"});
 
 
 
 
 
 
 
 
515
  }
516
- })
 
 
 
 
 
517
  }
518
 
519
  var getQuickSetup = _ => {
520
- $.ajax({
521
- url: '<?php echo $quickSetupUrl; ?>',
522
- type: 'GET',
523
- dataType: 'json',
524
- success: function(data) {
525
- $('#range').val(data.optimization_level);
526
- $('#manual-settings-url').attr('href', data.manual_settings_url);
527
-
528
- document.getElementById('range').oninput(false);
529
- $("#quicksetup-widget").cardOverlay("clear");
530
- },
531
- error: function() {
532
- $("#plan-details-widget").cardOverlay("error", {message: "Error while fetching the optimization level settings"});
 
 
 
 
533
  }
534
- })
 
 
 
 
 
 
 
 
 
535
  }
536
 
537
  window.addEventListener("cache.invalidate.success", getOptimizations);
4
  <?php nitropack_display_admin_notices(); ?>
5
  </div>
6
  </div>
7
+ <?php if (count(get_nitropack()->Notifications->get('system')) > 0) { ?>
8
+ <div class="row">
9
+ <div class="col-12 mb-3">
10
+ <div class="card-overlay-blurrable np-widget" id="notifications">
11
+ <div class="card card-d-item">
12
+ <div class="card-body">
13
+ <h5 class="card-title">Notifications</h5>
14
+ <ul class="list-group list-group-flush" id="notifications-list">
15
+ <?php foreach(get_nitropack()->Notifications->get('system') as $notification) : ?>
16
+ <li class="list-group-item px-0 d-flex justify-content-between align-items-center">
17
+ <?php echo $notification['message']; ?>
18
+ </li>
19
+ <?php endforeach; ?>
20
+ </ul>
21
+ </div>
22
+ </div>
23
+ </div>
24
+ </div>
25
+ </div>
26
+ <?php } ?>
27
  <div class="row">
28
  <div class="col-md-6 mb-3">
29
  <div class="card-overlay-blurrable np-widget" id="optimizations-widget">
463
  }
464
 
465
  var getOptimizations = _ => {
466
+ var url = '<?php echo $optimizationDetailsUrl; ?>';
467
+ ((s, e, f) => {
468
+ if (window.fetch) {
469
+ fetch(url)
470
+ .then(resp => resp.json())
471
+ .then(s)
472
+ .catch(e)
473
+ .finally(f);
474
+ } else {
475
+ $.ajax({
476
+ url: url,
477
+ type: 'GET',
478
+ dataType: 'json',
479
+ success: s,
480
+ error: e,
481
+ complete: f
482
+ })
483
+ }
484
+ })(data => {
485
+ $('[data-last-cache-purge]').text(data.last_cache_purge.timeAgo);
486
+ if (data.last_cache_purge.reason) {
487
  $('[data-purge-reason]').text(data.last_cache_purge.reason);
488
  $('#last-cache-purge-reason').show();
489
  } else {
490
+ $('#last-cache-purge-reason').hide();
491
+ }
492
 
493
+ if (data.pending_count) {
494
+ $("#pending-optimizations-count").text(data.pending_count);
495
+ $("#pending-optimizations-section").show();
496
  } else {
497
  $("#pending-optimizations-section").hide();
498
+ }
 
 
 
 
 
499
 
500
+ $('[data-optimized-pages-desktop]').text(data.optimized_pages.desktop);
501
+ $('[data-optimized-pages-mobile]').text(data.optimized_pages.mobile);
502
+ $('[data-optimized-pages-tablet]').text(data.optimized_pages.tablet);
503
+ $('[data-optimized-pages-total]').text(data.optimized_pages.total);
504
+
505
+ $("#optimizations-widget").cardOverlay("clear");
506
+ }, __ => {
507
+ $("#optimizations-widget").cardOverlay("error", {message: "Error while fetching optimizations data"});
508
+ }, __ => {
509
+ if (!getOptimizationsTimeout) {
510
+ getOptimizationsTimeout = setTimeout(function() {getOptimizationsTimeout = null; getOptimizations();}, 60000);
511
  }
512
+ });
513
  }
514
 
515
  var getPlan = _ => {
516
+ var url = '<?php echo $planDetailsUrl; ?>';
517
+ ((s, e, f) => {
518
+ if (window.fetch) {
519
+ fetch(url)
520
+ .then(resp => resp.json())
521
+ .then(s)
522
+ .catch(e)
523
+ .finally(f);
524
+ } else {
525
+ $.ajax({
526
+ url: url,
527
+ type: 'GET',
528
+ dataType: 'json',
529
+ success: s,
530
+ error: e,
531
+ complete: f
532
+ })
533
+ }
534
+ })(data => {
535
+ $('[data-plan-title]').text(data.plan_title);
536
+ $('[data-next-billing]').text(data.next_billing ? data.next_billing : 'N/A');
537
+ $('[data-next-reset]').text(data.next_reset ? data.next_reset : 'N/A');
538
+
539
+ for (prop in data) {
540
+ if (prop.indexOf("show_") === 0) continue;
541
+ if (prop.indexOf("label_") === 0) continue;
542
+ if (prop.indexOf("max_") === 0) continue;
543
+ if (
544
+ typeof data["show_" + prop] != "undefined" &&
545
+ data["show_" + prop] &&
546
+ typeof data["label_" + prop] != "undefined" &&
547
+ typeof data["max_" + prop] != "undefined"
548
+ ) {
549
+ let propertyLabel = data["label_" + prop];
550
+ let propertyValue = data[prop];
551
+ let propertyLimit = data["max_" + prop];
552
+ $("#plan-quotas").append('<li class="list-group-item px-0 d-flex justify-content-between align-items-center">' + propertyLabel + ' <span><span data-optimizations>' + propertyValue + '</span> out of <span data-max-optimizations>' + propertyLimit + '</span></span></li>');
553
+ }
554
  }
555
+
556
+ $("#plan-details-widget").cardOverlay("clear");
557
+ }, __ => {
558
+ $("#plan-details-widget").cardOverlay("error", {message: "Error while fetching plan data"});
559
+ }, __ => {
560
+ });
561
  }
562
 
563
  var getQuickSetup = _ => {
564
+ var url = '<?php echo $quickSetupUrl; ?>';
565
+ ((s, e, f) => {
566
+ if (window.fetch) {
567
+ fetch(url)
568
+ .then(resp => resp.json())
569
+ .then(s)
570
+ .catch(e)
571
+ .finally(f);
572
+ } else {
573
+ $.ajax({
574
+ url: url,
575
+ type: 'GET',
576
+ dataType: 'json',
577
+ success: s,
578
+ error: e,
579
+ complete: f
580
+ })
581
  }
582
+ })(data => {
583
+ $('#range').val(data.optimization_level);
584
+ $('#manual-settings-url').attr('href', data.manual_settings_url);
585
+
586
+ document.getElementById('range').oninput(false);
587
+ $("#quicksetup-widget").cardOverlay("clear");
588
+ }, __ => {
589
+ $("#quicksetup-widget").cardOverlay("error", {message: "Error while fetching the optimization level settings"});
590
+ }, __ => {
591
+ });
592
  }
593
 
594
  window.addEventListener("cache.invalidate.success", getOptimizations);
view/javascript/admin_bar_menu.js CHANGED
@@ -6,7 +6,7 @@ jQuery(window).on("load", _ => {
6
  type: 'POST',
7
  data: {
8
  action: "nitropack_" + clearCacheAction + "_single_cache",
9
- postUrl: window.location.href,
10
  postId: -1
11
  },
12
  dataType: 'json',
6
  type: 'POST',
7
  data: {
8
  action: "nitropack_" + clearCacheAction + "_single_cache",
9
+ postUrl: window.location.href.split('#')[0],
10
  postId: -1
11
  },
12
  dataType: 'json',
view/javascript/np_notices.js CHANGED
@@ -1,4 +1,13 @@
1
- loadDismissibleNotices = function() {
 
 
 
 
 
 
 
 
 
2
  var $ = jQuery;
3
 
4
  $(".notice.is-dismissible").each(function() {
1
+ (function() {
2
+ document.addEventListener("click", function(e) {
3
+ if (e.target.matches(".notice.is-dismissible[data-dismissible-id] button.notice-dismiss")) {
4
+ let noticeId = e.target.closest(".notice.is-dismissible[data-dismissible-id]").dataset.dismissibleId;
5
+ document.cookie = "dismissed_notice_" + noticeId + "=1;path=/;max-age=" + (86400 * 30) + "; secure";
6
+ }
7
+ }, true);
8
+ })();
9
+
10
+ var loadDismissibleNotices = function() {
11
  var $ = jQuery;
12
 
13
  $(".notice.is-dismissible").each(function() {