PluginProbe ʕ •ᴥ•ʔ
NitroPack – Performance, Page Speed & Cache Plugin for Core Web Vitals, CDN & Image Optimization / 1.15.0
NitroPack – Performance, Page Speed & Cache Plugin for Core Web Vitals, CDN & Image Optimization v1.15.0
1.19.8 1.19.7 1.19.6 1.19.5 trunk 1.10.0 1.10.1 1.10.2 1.10.3 1.10.4 1.11.0 1.12.0 1.13.0 1.14.0 1.15.0 1.15.1 1.15.2 1.15.3 1.16.0 1.16.1 1.16.2 1.16.3 1.16.4 1.16.5 1.16.6 1.16.7 1.16.8 1.17.0 1.17.6 1.17.7 1.17.8 1.17.9 1.18.0 1.18.1 1.18.2 1.18.3 1.18.4 1.18.5 1.18.6 1.18.7 1.18.8 1.18.9 1.19.0 1.19.1 1.19.2 1.19.3 1.19.4 1.3.19 1.3.20 1.4.0 1.4.1 1.5.0 1.5.1 1.5.10 1.5.11 1.5.12 1.5.13 1.5.14 1.5.15 1.5.16 1.5.17 1.5.18 1.5.19 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.5.9 1.6.0 1.6.1 1.7.0 1.7.1 1.8.0 1.8.1 1.8.3 1.9.0 1.9.1 1.9.2
nitropack / classes / WordPress / NitroPack.php
nitropack / classes / WordPress Last commit date
Config.php 2 years ago NitroPack.php 2 years ago Notifications.php 3 years ago
NitroPack.php
462 lines
1 <?php
2 namespace NitroPack\WordPress;
3
4 use \NitroPack\SDK\Filesystem;
5
6 class NitroPack {
7 private static $instance = NULL;
8 public static $nitroDirMigrated = false;
9 public static $nitroConfigMigrated = false;
10 public static $preUpdatePosts = array();
11 public static $preUpdateTaxonomies = array();
12 public static $preUpdateMeta = array();
13 public static $ignoreUpdatePostIDs = array();
14 public static $np_loggedWarmups = array();
15 public static $optionsToCache = [
16 'cache_handler_cache_handler',
17 'woocommerce_default_customer_address',
18 [ "wc_aelia_currency_switcher" => "ipgeolocation_enabled"]
19 ];
20
21 public static function getInstance() {
22 if (!self::$instance) {
23 self::$instance = new NitroPack();
24 }
25
26 return self::$instance;
27 }
28
29 public static function getDataDir() {
30 $isRaidBoxes = \NitroPack\Integration\Hosting\Raidboxes::detect();
31 $isPantheon = \NitroPack\Integration\Hosting\Pantheon::detect();
32 $isWpe = \NitroPack\Integration\Hosting\WPEngine::detect();
33 $isCloudways = \NitroPack\Integration\Hosting\Cloudways::detect();
34 $isRocketNet = \NitroPack\Integration\Hosting\RocketNet::detect();
35 $currentFilePath = __FILE__;
36
37 if ($isWpe) {
38 $currentFilePath = preg_replace("@^/sites/@", "/nas/content/live/", $currentFilePath);
39 }
40
41 $oldNitroDirs = [
42 nitropack_trailingslashit(WP_CONTENT_DIR) . 'nitropack',
43 nitropack_trailingslashit(WP_CONTENT_DIR) . 'cache/' . substr(md5($currentFilePath), 0, 7) . "-nitropack",
44 ];
45 $newNitroDir = nitropack_trailingslashit(WP_CONTENT_DIR) . 'cache/' . NITROPACK_CACHE_DIR_NAME;
46 $nitroDir = $newNitroDir;
47
48 if ($isRaidBoxes || $isRocketNet || $isCloudways) {
49 $nitroDir = $oldNitroDirs[0];
50 } else if ($isPantheon) {
51 $nitroDir = nitropack_trailingslashit(WP_CONTENT_DIR) . 'uploads/' . NITROPACK_CACHE_DIR_NAME;
52 }
53
54 $possibleDirs = array_unique(array_merge($oldNitroDirs, [$newNitroDir]));
55 $existingDirs = [];
56
57 foreach ($possibleDirs as $possibleDir) {
58 if (Filesystem::fileExists($possibleDir)) {
59 $existingDirs[] = $possibleDir;
60 }
61 }
62
63 if (count($existingDirs) == 1) {
64 $existingDir = array_shift($existingDirs);
65 if (is_link($existingDir)) {
66 $existingDir = readlink($existingDir);
67 }
68
69 if ($existingDir != $nitroDir) {
70 if (!Filesystem::fileExists($nitroDir) && !NITROPACK_USE_REDIS) {
71 // Existing installation, move to the new location
72
73 if (Filesystem::createDir(dirname($nitroDir)) && Filesystem::rename($existingDir, $nitroDir)) {
74 self::$nitroDirMigrated = true;
75 } else {
76 define('NITROPACK_DATA_DIR_WARNING', 'Unable to initialize cache dir because the PHP user does not have permission to create/rename directories under wp-content/. Running in legacy mode. Please contact support for help.');
77 $nitroDir = $existingDir;
78 }
79 }
80 }
81 }
82
83 return $nitroDir;
84 }
85
86 public static function getPluginDataDir() {
87 $isPantheon = \NitroPack\Integration\Hosting\Pantheon::detect();
88 $nitroDir = nitropack_trailingslashit(WP_CONTENT_DIR) . 'config-' . NITROPACK_CACHE_DIR_NAME;
89 if ($isPantheon) {
90 $nitroDir = nitropack_trailingslashit(WP_CONTENT_DIR) . 'uploads/config-' . NITROPACK_CACHE_DIR_NAME;
91 }
92
93 $oldConfigFile = nitropack_trailingslashit(NITROPACK_DATA_DIR) . 'config.json';
94 $newConfigFile = nitropack_trailingslashit($nitroDir) . 'config.json';
95 if (Filesystem::fileExists($oldConfigFile) && !Filesystem::fileExists($newConfigFile)) {
96 // Existing installation, move config to the new location
97
98 if (Filesystem::createDir($nitroDir) && Filesystem::rename($oldConfigFile, $newConfigFile)) {
99 self::$nitroConfigMigrated = true;
100 $oldHtaccessFile = nitropack_trailingslashit(NITROPACK_DATA_DIR) . '.htaccess';
101 $newHtaccessFile = nitropack_trailingslashit($nitroDir) . '.htaccess';
102 if (Filesystem::fileExists($oldHtaccessFile) && !Filesystem::fileExists($newHtaccessFile)) {
103 Filesystem::filePutContents($newHtaccessFile, Filesystem::fileGetContents($oldHtaccessFile));
104 }
105 } else {
106 define('NITROPACK_PLUGIN_DATA_DIR_WARNING', 'Unable to initialize plugin data dir because the PHP user does not have permission to create/rename directories under wp-content/. Running in legacy mode. Please contact support for help.');
107 $nitroDir = NITROPACK_DATA_DIR;
108 }
109 }
110
111 return $nitroDir;
112 }
113
114 private $sdkObjects;
115 private $disabledReason;
116 private $pageType;
117
118 public $Config;
119 public $Notifications;
120
121 public function __construct() {
122 $this->Config = new Config($this);
123 $this->Notifications = new Notifications($this);
124 $this->sdkObjects = array();
125 $this->disabledReason = NULL;
126 $this->pageType = NULL;
127 }
128
129 public function getDistribution() {
130 $dist = "regular";
131 $dbDist = NULL;
132
133 try {
134 if (function_exists("get_option")) {
135 $dbDist = get_option("nitropack-distribution", NULL);
136 }
137
138 if ($this->isConnected()) {
139 $sdk = $this->getSdk();
140 if (!$sdk) return $dbDist ? $dbDist : $dist;
141
142 $config = $sdk->getConfig();
143 if ($config) {
144 $dist = $config->Distribution;
145 }
146 } else if ($dbDist !== NULL) {
147 $dist = $dbDist;
148 }
149
150 if ($dbDist != $dist && function_exists("update_option")) {
151 update_option("nitropack-distribution", $dist);
152 }
153
154 return $dist;
155 } catch (Exception $e) {
156 return $dist;
157 }
158 }
159
160 public function getSiteConfig() {
161 $siteConfig = null;
162 $npConfig = $this->Config->get();
163 $currentUrl = $this -> getCurrentUrl();
164
165 $matchLength = 0;
166
167 foreach ($npConfig as $siteUrl => $config) {
168 if (stripos($siteUrl, "www.") === 0) {
169 $siteUrl = substr($siteUrl, 4);
170 }
171
172 if (stripos($currentUrl, $siteUrl) === 0 && strlen($siteUrl) > $matchLength) {
173 $siteConfig = $config;
174 $matchLength = strlen($siteUrl);
175 }
176 }
177
178 if (!$siteConfig) {
179 $matchLength = 0;
180 foreach ($npConfig as $siteUrl => $config) {
181 if (isset($config['additional_domains'])) {
182 foreach ($config['additional_domains'] as $additionalDomain) {
183 if (stripos($additionalDomain, "www.") === 0) {
184 $additionalDomain = substr($additionalDomain, 4);
185 }
186
187 if (stripos($currentUrl, $additionalDomain) === 0 && strlen($additionalDomain) > $matchLength) {
188 $siteConfig = $config;
189 $matchLength = strlen($additionalDomain);
190 }
191 }
192 }
193 }
194 }
195
196 return $siteConfig;
197 }
198
199 public function getSiteId() {
200 $siteConfig = $this->getSiteConfig();
201 return $siteConfig ? $siteConfig["siteId"] : NULL;
202 }
203
204 public function getSiteSecret() {
205 $siteConfig = $this->getSiteConfig();
206 return $siteConfig ? $siteConfig["siteSecret"] : NULL;
207 }
208
209 /**
210 * Bear in mind that get_home_url() is not defined in the context of advanced_cache.php
211 * so this will throw a fatal error if you call it at that point!
212 */
213 public static function getConfigKey() {
214 return preg_replace("/^https?:\/\/(.*)/", "$1", get_home_url());
215 }
216
217 public function getAdditionalDomains($siteId, $siteSecret) {
218 if (null !== $nitro = $this->getSdk($siteId, $siteSecret)) {
219 $config = $nitro->getConfig();
220 if (!property_exists($config->AdditionalDomains, 'Domains')) {
221 $nitro->fetchConfig();
222 }
223 return $config->AdditionalDomains->Domains;
224 }
225
226 return [];
227 }
228
229 public function isConnected() {
230 return !empty($this->getSiteId()) && !empty($this->getSiteSecret());
231 }
232
233 public function updateCurrentBlogConfig($siteId, $siteSecret, $blogId, $enableCompression = null) {
234 if ($enableCompression === null) {
235 $enableCompression = (get_option('nitropack-enableCompression') == 1);
236 }
237
238 $webhookToken = get_option('nitropack-webhookToken');
239 $hosting = nitropack_detect_hosting();
240
241 $home_url = get_home_url();
242 $admin_url = admin_url();
243 $alwaysBuffer = defined("NITROPACK_ALWAYS_BUFFER") ? NITROPACK_ALWAYS_BUFFER : true;
244 $configKey = self::getConfigKey();
245 $staticConfig = $this->Config->get();
246 $staticConfig[$configKey] = array(
247 "siteId" => $siteId,
248 "siteSecret" => $siteSecret,
249 "blogId" => $blogId,
250 "compression" => $enableCompression,
251 "webhookToken" => $webhookToken,
252 "home_url" => $home_url,
253 "admin_url" => $admin_url,
254 "hosting" => $hosting,
255 "alwaysBuffer" => $alwaysBuffer,
256 "isEzoicActive" => \NitroPack\Integration\Plugin\Ezoic::isActive(),
257 "isApoActive" => \NitroPack\Integration\Plugin\Cloudflare::isApoActive(),
258 "isNginxHelperActive" => \NitroPack\Integration\Plugin\NginxHelper::isActive(),
259 "isLateIntegrationInitRequired" => nitropack_is_late_integration_init_required(),
260 "isDlmActive" => \NitroPack\Integration\Plugin\DownloadManager::isActive(),
261 "isWoocommerceCacheHandlerActive" => \NitroPack\Integration\Plugin\WoocommerceCacheHandler::isActive(),
262 "isWoocommerceActive" => \NitroPack\Integration\Plugin\Woocommerce::isActive(),
263 "isAeliaCurrencySwitcherActive" => \NitroPack\Integration\Plugin\AeliaCurrencySwitcher::isActive(),
264 "isGeoTargetingWPActive" => \NitroPack\Integration\Plugin\GeoTargetingWP::isActive(),
265 "dlm_downloading_url" => \NitroPack\Integration\Plugin\DownloadManager::isActive() ? \NitroPack\Integration\Plugin\DownloadManager::downloadingUrl() : NULL,
266 "dlm_download_endpoint" => \NitroPack\Integration\Plugin\DownloadManager::isActive() ? \NitroPack\Integration\Plugin\DownloadManager::downloadEndpoint() : NULL,
267 "pluginVersion" => NITROPACK_VERSION,
268 "options_cache" => [],
269 "additional_domains" => $this->getAdditionalDomains($siteId, $siteSecret),
270 );
271 foreach (self::$optionsToCache as $opt) {
272 if (is_array($opt)) {
273 foreach($opt as $option => $suboption) {
274 if (empty($staticConfig[$configKey]["options_cache"][$option])) {
275 $staticConfig[$configKey]["options_cache"][$option] = [];
276 }
277 $optionValue = get_option($option);
278 if (!empty($optionValue)) {
279 $staticConfig[$configKey]["options_cache"][$option][$suboption] = $optionValue[$suboption];
280 } else {
281 $staticConfig[$configKey]["options_cache"][$option][$suboption] = null;
282 }
283 }
284 } else {
285 $staticConfig[$configKey]["options_cache"][$opt] = get_option($opt);
286 }
287 }
288 $configSetResult = $this->Config->set($staticConfig);
289
290 if (\NitroPack\Integration\Plugin\AeliaCurrencySwitcher::isActive()) {
291 try {
292 \NitroPack\Integration\Plugin\AeliaCurrencySwitcher::configureVariationCookies();
293 } catch (\Exception $e) {
294 // TODO: Log this error
295 }
296 }
297 if (\NitroPack\Integration\Plugin\GeoTargetingWP::isActive()) {
298 try {
299 \NitroPack\Integration\Plugin\GeoTargetingWP::configureVariationCookies();
300 } catch (\Exception $e) {
301 // TODO: Log this error
302 }
303 }
304
305 return $configSetResult;
306 }
307
308 public function unsetCurrentBlogConfig() {
309 $configKey = self::getConfigKey();
310 $staticConfig = $this->Config->get();
311 if (!empty($staticConfig[$configKey])) {
312 unset($staticConfig[$configKey]);
313 return $this->Config->set($staticConfig);
314 }
315
316 return true;
317 }
318
319 public function resetSdkInstances() {
320 $this->sdkObjects = [];
321 }
322
323 public function getSdk($siteId = null, $siteSecret = null, $urlOverride = NULL, $forwardExceptions = false) {
324 $siteConfig = $this->getSiteConfig();
325
326 $siteId = $siteId ?: (!empty($siteConfig) ? $siteConfig['siteId'] : NULL);
327 $siteSecret = $siteSecret ?: (!empty($siteConfig) ? $siteConfig['siteSecret'] : NULL);
328
329 if ($siteId && $siteSecret) {
330 try {
331 $userAgent = NULL; // It will be automatically detected by the SDK
332 $dataDir = nitropack_trailingslashit(NITROPACK_DATA_DIR) . $siteId; // dir without a trailing slash, because this is how the SDK expects it
333 $cacheKey = "{$siteId}:{$siteSecret}:{$dataDir}";
334
335 if ($urlOverride) {
336 $cacheKey .= ":{$urlOverride}";
337 }
338
339 if (!empty($this->sdkObjects[$cacheKey])) {
340 $nitro = $this->sdkObjects[$cacheKey];
341 } else {
342 if (!defined("NP_COOKIE_FILTER")) {
343 \NitroPack\SDK\NitroPack::addCookieFilter("nitropack_filter_non_original_cookies");
344 define("NP_COOKIE_FILTER", true);
345 do_action('np_set_cookie_filter');
346 }
347 if (!defined("NP_STORAGE_CONFIGURED")) {
348 if (defined("NITROPACK_USE_REDIS") && NITROPACK_USE_REDIS) {
349 \NitroPack\SDK\Filesystem::setStorageDriver(new \NitroPack\SDK\StorageDriver\Redis(
350 NITROPACK_REDIS_HOST,
351 NITROPACK_REDIS_PORT,
352 NITROPACK_REDIS_PASS,
353 NITROPACK_REDIS_DB
354 ));
355 }
356 define("NP_STORAGE_CONFIGURED", true);
357 }
358
359 if (!defined('NP_GEOLOCATION_PREFIX_DEFINED')) {
360 do_action('set_nitropack_geo_cache_prefix');
361 define('NP_GEOLOCATION_PREFIX_DEFINED', true);
362 }
363
364 if (defined("NITROPACK_CUSTOM_CACHE_PREFIX") && !defined('NP_CUSTOM_CACHE_PREFIX_SET')) {
365 \NitroPack\SDK\NitroPack::addCustomCachePrefix(NITROPACK_CUSTOM_CACHE_PREFIX);
366 define('NP_CUSTOM_CACHE_PREFIX_SET', true);
367 }
368
369 $nitro = new \NitroPack\SDK\NitroPack($siteId, $siteSecret, $userAgent, $urlOverride, $dataDir);
370 $this->sdkObjects[$cacheKey] = $nitro;
371 }
372 } catch (\Exception $e) {
373 if ($forwardExceptions) {
374 throw $e;
375 }
376 return NULL;
377 }
378
379 return $nitro;
380 }
381
382 return NULL;
383 }
384
385 public function dataDirExists() {
386 return defined("NITROPACK_DATA_DIR") && is_dir(NITROPACK_DATA_DIR); // TODO: Convert this to use the Filesystem abstraction for better Redis support
387 }
388
389 public function initDataDir() {
390 return $this->dataDirExists() || @mkdir(NITROPACK_DATA_DIR, 0755, true); // TODO: Convert this to use the Filesystem abstraction for better Redis support
391 }
392
393 public function pluginDataDirExists() {
394 return defined("NITROPACK_PLUGIN_DATA_DIR") && is_dir(NITROPACK_PLUGIN_DATA_DIR); // TODO: Convert this to use the Filesystem abstraction for better Redis support
395 }
396
397 public function initPluginDataDir() {
398 return $this->pluginDataDirExists() || @mkdir(NITROPACK_PLUGIN_DATA_DIR, 0755, true); // TODO: Convert this to use the Filesystem abstraction for better Redis support
399 }
400
401 public function setDisabledReason($reason) {
402 $this->disabledReason = $reason;
403 nitropack_header("X-Nitro-Disabled-Reason: $reason");
404 }
405
406 public function getDisabledReason() {
407 return $this->disabledReason;
408 }
409
410 public function setPageType($type) {
411 $this->pageType = $type;
412 }
413
414 public function getPageType() {
415 return $this->pageType;
416 }
417
418 /**
419 * Get current url
420 *
421 * @return string The current url
422 */
423 public function getCurrentUrl() {
424
425 if ( defined('NITROPACK_HOST') ) {
426
427 return NITROPACK_HOST;
428 }
429
430 if (! empty( $_SERVER['HTTP_X_FORWARDED_HOST'] )) {
431 $host = $_SERVER['HTTP_X_FORWARDED_HOST'];
432 } else {
433 $host = !empty($_SERVER["HTTP_HOST"]) ? $_SERVER["HTTP_HOST"] : "";
434 }
435
436 $uri = !empty($_SERVER["REQUEST_URI"]) ? $_SERVER["REQUEST_URI"] : "";
437 $currentUrl = $host . $uri;
438
439 if (empty($currentUrl) || (defined( 'WP_CLI' ) && WP_CLI && trim($currentUrl) == "localhost")) {
440
441 if (function_exists('get_site_url')) {
442 $host = apply_filters('nitropack_current_host', get_site_url());
443 } elseif (function_exists('get_option')) {
444 $host = apply_filters('nitropack_current_host', get_option('siteurl'));
445 }
446
447 if ($host != '') {
448 $site_url = parse_url($host);
449 if (is_array($site_url) && isset($site_url["host"]) && !empty($site_url["host"])) {
450 $currentUrl = $site_url["host"];
451 }
452 }
453 }
454
455 if (stripos($currentUrl, "www.") === 0) {
456 $currentUrl = substr($currentUrl, 4);
457 }
458
459 return $currentUrl;
460 }
461 }
462