PluginProbe
RabbitLoader / 2.17.6
RabbitLoader v2.17.6
4.0.2 4.0.1 4.0 3.2.0 3.1.1 3.1.0 3.0.5 3.0.3 3.0.4 2.17.1 2.17.2 2.17.3 2.17.4 2.17.5 2.17.6 2.17.7 2.18.0 2.18.1 2.18.2 2.18.3 2.18.4 2.18.5 2.18.6 2.18.7 2.18.8 All 129 releases
rabbit-loader / inc / core / core.php

core.php in RabbitLoader 2.17.6, at inc/core/core.php

780 lines 30.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 class RabbitLoader_21_Core {
4
5 private static $rl_wp_options = [];
6 private static $user_options = [];
7
8 /**
9 * max time a cache can live
10 */
11 const ORPHANED_LONG_AGE_SEC = 30*24*3600;
12
13 private static function addKeys(&$args, &$rabbitloader_field_domain){
14 if(empty($args)){
15 $args = [];
16 }
17
18 if(empty($args['headers'])){
19 $args['headers'] = [];
20 }
21
22 if(RabbitLoader_21_Util_Core::isDev()){
23 $args['sslverify'] = false;
24 }
25 $args['timeout'] = 30;
26
27 $api_token = RabbitLoader_21_Core::getWpOptVal('api_token');
28 if(!empty($api_token)){
29 $args['headers'] += [
30 'AUTHORIZATION'=>'Bearer '.$api_token
31 ];
32 $rabbitloader_field_domain = RabbitLoader_21_Core::getWpOptVal('domain');
33 }else{
34
35 $rabbitloader_field_apikey = get_option('rabbitloader_field_apikey');
36 $rabbitloader_field_apisecret = get_option('rabbitloader_field_apisecret');
37 $rabbitloader_field_domain = get_option('rabbitloader_field_domain');
38
39 if(empty($rabbitloader_field_apikey) || empty($rabbitloader_field_apisecret)){
40 return false;
41 }
42
43 $args['headers'] += [
44 'APIKEY'=>$rabbitloader_field_apikey,
45 'APISECRET'=>$rabbitloader_field_apisecret
46 ];
47 }
48
49 return true;
50 }
51
52 //@deprecated
53 public static function update_auth_keys($key, $secret, $domain, $comments){
54 update_option('rabbitloader_field_apikey', $key, false);
55 update_option('rabbitloader_field_apisecret', $secret, false);
56 update_option('rabbitloader_field_domain', $domain, false);
57 update_option('rabbitloader_field_update_time', time(), false);
58 if(!empty($comments)){
59 update_option('rabbitloader_field_disconnect_reason', $comments, false);
60 }
61 }
62
63 public static function update_api_tokens($api_token, $push_key, $domain, $did, $comments){
64 RabbitLoader_21_Core::getWpOption($rl_wp_options);
65 $rl_wp_options['api_token'] = $api_token;
66 $rl_wp_options['push_key'] = empty($push_key) ? '' : wp_hash_password($push_key);
67 $rl_wp_options['domain'] = $domain;
68 $rl_wp_options['did'] = $did;
69 $rl_wp_options['comments'] = $comments;
70 $rl_wp_options['token_update_ts'] = time();
71 RabbitLoader_21_Core::updateWpOption($rl_wp_options);
72 }
73
74 public static function getRLDomain(){
75 return RabbitLoader_21_Util_Core::isDev() ? 'https://rabbitloader.local/' : 'https://rabbitloader.com/';
76 }
77
78 private static function isTemporaryError($apiMessage){
79 $temp_errors = ['timed out', 'Could not resolve host', 'error setting certificate', 'Connection reset', 'OpenSSL', 'getaddrinfo() thread', 'SSL connection timeout', 'Unknown SSL', 'SSL_ERROR_SYSCALL', 'Failed connect to', 'cURL error 77'];
80 $found = false;
81 forEach($temp_errors as $msg){
82 if(stripos($apiMessage, $msg)!==false){
83 $found = true;
84 break;
85 }
86 }
87 return $found;
88 }
89
90 public static function &callGETAPI($endpoint, &$apiError, &$apiMessage){
91 $http = [];
92 $apiError = true;
93 if(!RabbitLoader_21_Core::addKeys($args, $rabbitloader_field_domain)){
94 $apiError = 'Keys could not be added';
95 return $http;
96 }
97 $url = RabbitLoader_21_Core::getRLDomain().'api/v1/';
98 if(strpos($endpoint, '?')){
99 $endpoint.='&';
100 }else{
101 $endpoint.='?';
102 }
103
104 $endpoint.='domain='.$rabbitloader_field_domain.'&plugin_cms=wp&plugin_v='.RABBITLOADER_PLUG_VERSION.'&cms_v='.get_bloginfo( 'version' );
105
106 $args['method'] = 'GET';
107
108 try{
109 $http = wp_remote_get( $url.$endpoint, $args);
110
111 if(is_wp_error($http)){
112 $apiError = true;
113 $apiMessage = $http->get_error_message();
114 if(empty($apiMessage)){$apiMessage='';}
115 if(self::isTemporaryError($apiMessage)){
116 //chill, it happens
117 }else{
118 RabbitLoader_21_Core::on_exception($http);
119 }
120 $http = [];
121 }
122
123 if(!empty($http['response']['code']) && in_array($http['response']['code'], [200, 401])){
124 $http['body'] = json_decode($http['body'], true);
125 if(!empty($http['body']['message'])){
126 $message = $http['body']['message'];
127 if(!strcmp($message, 'AUTH_REQUIRED') || !strcmp($message, 'INVALID_DOMAIN')){
128 RabbitLoader_21_Core::update_auth_keys('', '', '', "$message when $endpoint was called");
129 RabbitLoader_21_Core::update_api_tokens('', '', '', '', "$message when $endpoint was called");
130 }
131 }
132 $apiError = empty($http['body']['result']);
133 $apiMessage = empty($http['body']['message']) ? '' : $http['body']['message'];
134 }
135
136 }catch(Throwable $e){
137 RabbitLoader_21_Core::on_exception($e);
138 $apiError = true;
139 $apiMessage = $e->getMessage();
140 }
141 return $http;
142 }
143
144 public static function &callPostApi($endpoint, $body, &$apiError, &$apiMessage){
145 $http = [];
146 $apiError = true;
147
148 if(!RabbitLoader_21_Core::addKeys($args, $rabbitloader_field_domain)){
149 $apiError = 'Keys could not be added';
150 return $http;
151 }
152 $url = RabbitLoader_21_Core::getRLDomain().'api/v1/';
153
154 $body['domain'] = $rabbitloader_field_domain;
155 $body['plugin_cms'] = 'wp';
156 $body['plugin_v'] = RABBITLOADER_PLUG_VERSION;
157 $body['cms_v'] = get_bloginfo( 'version' );
158
159 $args['method'] = 'POST';
160 $args['body'] = $body;
161
162 try{
163 $http = wp_remote_post( $url.$endpoint, $args);
164
165 if(is_wp_error($http)){
166 $apiError = true;
167 $apiMessage = $http->get_error_message();
168 if(empty($apiMessage)){$apiMessage='';}
169 if(self::isTemporaryError($apiMessage)){
170 //chill, it happens
171 }else{
172 RabbitLoader_21_Core::on_exception($http->get_error_message().$url.$endpoint);
173 }
174 $http = [];
175 }
176
177 if(!empty($http['response']['code']) && in_array($http['response']['code'], [200, 401])){
178 $http['body'] = json_decode($http['body'], true);
179 if(!empty($http['body']['message'])){
180 $message = $http['body']['message'];
181 if(!strcmp($message, 'AUTH_REQUIRED') || !strcmp($message, 'INVALID_DOMAIN')){
182 RabbitLoader_21_Core::update_auth_keys('', '', '', "$message when $endpoint was called");
183 RabbitLoader_21_Core::update_api_tokens('', '', '', '', "$message when $endpoint was called");
184 }
185 }
186 $apiError = empty($http['body']['result']);
187 $apiMessage = empty($http['body']['message']) ? '' : $http['body']['message'];
188 }
189 }catch(Throwable $e){
190 RabbitLoader_21_Core::on_exception($e);
191 $apiError = true;
192 $apiMessage = $e->getMessage();
193 }
194 return $http;
195 }
196
197 public static function get_cache_file_path($request_url, &$file){
198 $file = RabbitLoader_21_Util_WP::get_cache_dir('long').DIRECTORY_SEPARATOR.md5($request_url);
199 }
200
201 public static function cache_exists_for_url($request_url, $post_mdfd_ts){
202 RabbitLoader_21_Core::get_cache_file_path($request_url, $cache_file);
203 return RabbitLoader_21_Core::cache_exists_for_hash($cache_file, $post_mdfd_ts);
204 }
205 public static function cache_exists_for_hash($cache_file, $post_mdfd_ts){
206 $fn = $cache_file.'_c';
207 $fe = file_exists($fn);
208 if($post_mdfd_ts && $post_mdfd_ts>631152000){
209 $mt = filemtime($fn);
210 if($mt && $mt<$post_mdfd_ts){
211 //post is modified after cache was generated
212 $fe = false;
213 }
214 }
215 return $fe;
216 }
217
218 public static function getWpUserOption(&$user_options){
219 if(!empty(self::$user_options)){
220 $user_options = self::$user_options;
221 return;
222 }
223 if(function_exists('get_option')){
224 $user_options = get_option('rabbit_loader_user_options');
225 }else{
226 RabbitLoader_21_Core::get_log_file('rl_user_options', $rl_user_options);
227 if(file_exists($rl_user_options)){
228 $user_options = json_decode(file_get_contents($rl_user_options), true);
229 }
230 }
231 if(empty($user_options) || !is_array($user_options)){
232 $user_options = [];
233 }
234 $default_values = [
235 'purge_on_change'=>true,
236 'exclude_patterns' => '',
237 'ignore_params' => '',
238 'private_mode_val'=>false,
239 ];
240 foreach($default_values as $k=>$v){
241 if(!isset($user_options[$k])){
242 $user_options[$k] = $v;
243 }
244 }
245 self::$user_options = $user_options;
246 }
247 public static function updateUserOption(&$user_options){
248 self::$user_options = $user_options;
249 update_option('rabbit_loader_user_options', $user_options, true);
250 try{
251 RabbitLoader_21_Core::get_log_file('rl_user_options', $rl_user_options);
252 $rl_json = json_encode($user_options);
253 RabbitLoader_21_Util_Core::fpc($rl_user_options, $rl_json, WP_DEBUG);
254 }catch(\Throwable $e){
255 RabbitLoader_21_Core::on_exception($e);
256 }
257 }
258
259
260 public static function getWpOption(&$rl_wp_options){
261 if(!empty(self::$rl_wp_options)){
262 $rl_wp_options = self::$rl_wp_options;
263 return;
264 }
265 if(function_exists('get_option')){
266 $rl_wp_options = get_option('rabbit_loader_wp_options');
267 }else{
268 RabbitLoader_21_Core::get_log_file('rl_config', $rl_config);
269 if(file_exists($rl_config)){
270 $rl_wp_options = json_decode(file_get_contents($rl_config), true);
271 }
272 }
273 if(empty($rl_wp_options)){
274 $rl_wp_options = [];
275 }
276 self::$rl_wp_options = $rl_wp_options;
277 }
278 /**
279 * Get value of single config option
280 */
281 public static function getWpOptVal($key){
282 RabbitLoader_21_Core::getWpOption($rl_wp_options);
283 return isset($rl_wp_options[$key]) ? $rl_wp_options[$key] : '';
284 }
285
286 public static function updateWpOption(&$rl_wp_options){
287 self::$rl_wp_options = $rl_wp_options;
288 update_option('rabbit_loader_wp_options', $rl_wp_options, true);
289 try{
290 RabbitLoader_21_Core::get_log_file('rl_config', $rl_config);
291 $rl_json = json_encode($rl_wp_options);
292 RabbitLoader_21_Util_Core::fpc($rl_config, $rl_json, WP_DEBUG);
293 }catch(\Throwable $e){
294 RabbitLoader_21_Core::on_exception($e);
295 }
296 }
297
298 public static function clean_orphaned_cached_files($orphanedFreqSec){
299 if(empty($orphanedFreqSec)){
300 $orphanedFreqSec = 300;
301 }
302
303 if(!function_exists('get_option') || !function_exists('update_option')){
304 //may not be available if all WP files are not loaded
305 return;
306 }
307
308 RabbitLoader_21_Core::getWpOption($rl_wp_options);
309 if(empty($rl_wp_options)){
310 $rl_wp_options = [
311 'last_orphaned_cleanup'=>0,
312 'rl_optimizer_engine_version'=>''
313 ];
314 }
315
316 //version migrations start
317 $user_options = [];
318 RabbitLoader_21_Core::getWpUserOption($user_options);
319 if(!empty($rl_wp_options['exclude_patterns']) && empty($user_options['exclude_patterns'])){
320 //introduced@2.14.0
321 $user_options['exclude_patterns'] = $rl_wp_options['exclude_patterns'];
322 unset($rl_wp_options['exclude_patterns']);
323 RabbitLoader_21_Core::updateUserOption($user_options);
324 }
325 if(!empty($rl_wp_options['ignore_params']) && empty($user_options['ignore_params'])){
326 //introduced@2.14.0
327 $user_options['ignore_params'] = $rl_wp_options['ignore_params'];
328 unset($rl_wp_options['ignore_params']);
329 RabbitLoader_21_Core::updateUserOption($user_options);
330 }
331 //version migrations end
332
333 $prevRunSecAgo = PHP_INT_MAX;
334 if(!empty($rl_wp_options['last_orphaned_cleanup'])){
335 $prevRunSecAgo = time() - $rl_wp_options['last_orphaned_cleanup'];
336 if($prevRunSecAgo < $orphanedFreqSec){
337 #we have recently cleaned it within self::orphanedFreqSec seconds
338 return;
339 }
340 }
341 $rl_wp_options['last_orphaned_cleanup'] = time();
342 RabbitLoader_21_Core::updateWpOption($rl_wp_options);
343
344 $orphanedCleanTime = time() - RabbitLoader_21_Core::ORPHANED_LONG_AGE_SEC;
345 $files = glob(RabbitLoader_21_Util_WP::get_cache_dir('long').'/*'); // get all file names
346 $maxLimit = 500;//so we will not make the shutdown slow
347 foreach($files as $file){ // iterate files
348 if(is_file($file) && filemtime($file)<$orphanedCleanTime) {
349 @unlink($file); // delete file
350 --$maxLimit;
351 }
352 if(!$maxLimit){break;}
353 }
354
355 $anyPendingLog = false;
356 $logs_to_send = [
357 'cache_missed'=>2500,
358 'error_log'=>5000
359 ];
360 $post_data = [];
361 foreach($logs_to_send as $fn=>$length){
362 RabbitLoader_21_Core::get_log_file($fn, $fp);
363 if(file_exists($fp)){
364 try{
365 $post_data[$fn] = file_get_contents($fp, false, null, 0, $length);
366 if(!empty($post_data[$fn])){
367 $anyPendingLog = true;
368 }
369 @unlink($fp);
370 }catch(\Throwable $e){
371 $data = '';
372 RabbitLoader_21_Util_Core::fpc($fp, $data, false);
373 }
374 }
375 }
376
377 $hbeat_success_ts = empty($rl_wp_options['hbeat_success_ts'])?0:$rl_wp_options['hbeat_success_ts'];
378 $hbeat_success_diff = time()-$hbeat_success_ts;
379
380 if(!$anyPendingLog && $hbeat_success_diff <30*60){
381 return;
382 }
383
384 $post_data['cdn_loop'] = empty($_SERVER['HTTP_CDN_LOOP']) ? '': $_SERVER['HTTP_CDN_LOOP'];
385 if(empty($post_data['cdn_loop']) && !empty($_SERVER['HTTP_INCAP_CLIENT_IP'])){
386 $post_data['cdn_loop'] = 'incap';
387 }
388 $post_data['server_addr'] = empty($_SERVER['SERVER_ADDR']) ? '': $_SERVER['SERVER_ADDR'];
389 if(empty($post_data['server_addr']) && !empty($_SERVER['LOCAL_ADDR'])){
390 $post_data['server_addr'] = $_SERVER['LOCAL_ADDR'];
391 }
392
393 $post_data['rl_plugin_instance'] = empty($rl_wp_options['rl_plugin_instance']) ? '': $rl_wp_options['rl_plugin_instance'];
394 $post_data['rl_plugin_site_url'] = site_url();
395 if(empty($post_data['rl_plugin_site_url'])){
396 $post_data['rl_plugin_site_url'] = home_url();
397 }
398 $post_data['admin_ajax'] = admin_url( 'admin-ajax.php' );
399 $http = RabbitLoader_21_Core::callPostApi('domain/heartbeat', $post_data, $apiError, $apiMessage);
400
401 if(!$apiError && !empty($http['body']['data'])){
402 $apiResponse = $http['body']['data'];
403
404 $rl_wp_options['rabbitloader_field_apikey'] = get_option('rabbitloader_field_apikey');
405
406 if(!empty($apiResponse['rl_plugin_instance'])){
407 $rl_wp_options['rl_plugin_instance'] = $apiResponse['rl_plugin_instance'];
408 }
409
410 if(!empty($apiResponse['api_token'])){
411 $rl_wp_options['api_token'] = $apiResponse['api_token'];
412 $rl_wp_options['did'] = $apiResponse['did'];
413 $rl_wp_options['push_key'] = wp_hash_password($apiResponse['push_key']);
414 }
415
416 if(!empty($apiResponse['rl_optimizer_engine_version'])){
417 $server_version = $apiResponse['rl_optimizer_engine_version'];
418 if(empty($rl_wp_options['rl_optimizer_engine_version']) || $server_version != $rl_wp_options['rl_optimizer_engine_version']){
419 #we have update optimizer engine, and cache generated here was from previous engine. This can lead to performance issues.
420 RabbitLoader_21_Core::cleanAllCachedFiles('long');
421 }
422 $rl_wp_options['rl_optimizer_engine_version'] = $server_version;
423 }
424
425 if(!empty($apiResponse['rl_hb_messages'])){
426 $rl_wp_options['rl_hb_messages'] = $apiResponse['rl_hb_messages'];
427 }else{
428 $rl_wp_options['rl_hb_messages'] = [];
429 }
430
431 if(!empty($apiResponse['rl_latest_plugin_v'])){
432 $rl_wp_options['rl_latest_plugin_v'] = $apiResponse['rl_latest_plugin_v'];
433 }
434
435 if(empty($rl_wp_options['rl_varnish'])){
436 $rl_wp_options['rl_varnish'] = self::check_varnish(2) ? 1 : -1;
437 }
438 $rl_wp_options['hbeat_success_ts'] = time();
439 }
440 RabbitLoader_21_Core::updateWpOption($rl_wp_options);
441 }
442
443 public static function cleanAllCachedFiles($cache_type){
444 $deleted_count = 0;
445 $files = glob(RabbitLoader_21_Util_WP::get_cache_dir($cache_type).'/*'); // get all file names
446 foreach($files as $file){
447 if(is_file($file)) {
448 if(@unlink($file)){
449 ++$deleted_count;
450 }
451 }
452 }
453 return $deleted_count;
454 }
455
456 public static function purge_all(&$purge_count, $purge_source, &$tp_purge_count){
457 try{
458 //RL purges
459 $purge_count = 0;
460 $purge_count += RabbitLoader_21_Core::cleanAllCachedFiles('long');
461 RabbitLoader_21_Core::callPostApi('purge/request', ['purge_source'=>$purge_source], $apiError, $apiMessage);
462
463 //other common platforms purges
464 RabbitLoader_21_TP::purge_all($tp_purge_count);
465
466 }catch(Throwable $e){
467 RabbitLoader_21_Core::on_exception($e);
468 }
469 }
470
471 public static function purge_url_cache_local($url, &$local_purge_count, &$tp_purge_count){
472 if(empty($url)){
473 return;
474 }
475 $local_purge_count = 0;
476 try{
477 RabbitLoader_21_Core::get_cache_file_path($url, $cache_file);
478 if(is_file($cache_file.'_c')) {
479 if(@unlink($cache_file.'_c')){
480 ++$local_purge_count;
481 } // delete file
482 }
483 RabbitLoader_21_TP::purge_url($url, $tp_purge_count);
484 }catch(\Throwable $e){
485 RabbitLoader_21_Core::on_exception($e);
486 }
487 }
488
489 /**
490 * @param string $fn file name
491 * @param string $fp file path
492 */
493 public static function get_log_file($fn, &$fp){
494 $fp = RabbitLoader_21_Util_WP::get_cache_dir().DIRECTORY_SEPARATOR.$fn.".log";
495 }
496
497 public static function on_exception($exception, $limit = 8){
498 try{
499 $msg = "\n".date("c")." ";
500
501 if(function_exists('is_wp_error') && is_wp_error($exception)){
502 $msg .= $exception->get_error_message();
503 }else if($exception instanceof Exception || $exception instanceof Throwable) {
504 $msg .= $exception->getMessage();
505 }else{
506 $msg .= $exception;
507 }
508 if($limit>8){$limit=8;}
509 $msg .= @print_r(debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT, $limit),true);
510 $msg .= @print_r($_SERVER,true);
511
512 RabbitLoader_21_Util_Core::fac('error_log', $msg, WP_DEBUG);
513 if(RabbitLoader_21_Util_Core::isDev()){
514 echo $msg;
515 error_log($msg);
516 }
517 }catch(Throwable $e){
518 if(WP_DEBUG){
519 echo $e->getMessage();
520 }
521 }
522 }
523
524 public static function sendJsonResponse(&$response){
525 header("Content-Type: application/json");
526 header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0, s-max-age=0");
527 header("Cache-Control: post-check=0, pre-check=0", false);
528 header("Pragma: no-cache");
529 $encoded_str = json_encode($response, JSON_INVALID_UTF8_IGNORE);
530 if($encoded_str===false){
531 echo '{"time":"1", "failed":"1"}';
532 }else{
533 echo $encoded_str;
534 }
535 exit;
536 }
537
538 public static function sendHeader(string $header, bool $replace=true){
539 if(!headers_sent()){
540 header($header, $replace);
541 }
542 /*else{
543 $is_wp_cron_script = !empty($_SERVER['SCRIPT_NAME']) && stripos($_SERVER['SCRIPT_NAME'], '/wp-cron.php')!==false;
544 $is_wp_cron_self = !empty($_SERVER['PHP_SELF']) && stripos($_SERVER['PHP_SELF'], '/wp-cron.php') !==false;
545 $is_admin_ajax_self = !empty($_SERVER['PHP_SELF']) && stripos($_SERVER['PHP_SELF'], '/admin-ajax.php') !==false;
546 $is_admin_update_self = !empty($_SERVER['PHP_SELF']) && stripos($_SERVER['PHP_SELF'], '/update.php') !==false;
547 $is_wp_shell = !empty($_SERVER['SHELL']);
548 if($is_wp_cron_script || $is_wp_cron_self || $is_wp_shell || $is_admin_ajax_self || $is_admin_update_self){
549 //wp-cron will usually send the Cache-Control and Expires headers in advance, we need not to worry logging error in this case
550 return;
551 }
552
553 RabbitLoader_21_Core::on_exception('Trying to send header when it is already sent. Header=> '.$header.'. Headers already sent=>'.print_r(headers_list(), true));
554 }*/
555 }
556
557 private static function check_varnish($attempts){
558 $httpcode = 0;
559 try{
560 $url_id = home_url().'/';
561 $url_parts = parse_url($url_id);
562 $port = (empty($url_parts['scheme']) || $url_parts['scheme']=='https') ? '443' : '80';
563 $ch = curl_init($url_id);
564 curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PURGE");
565 curl_setopt($ch, CURLOPT_RESOLVE, array($url_parts['host'].":$port:127.0.0.1"));
566 curl_setopt($ch, CURLOPT_TIMEOUT, 30);
567 curl_exec($ch);
568 //$curl_error = curl_error($ch);
569 $httpcode = intval(curl_getinfo($ch, CURLINFO_HTTP_CODE));
570 curl_close($ch);
571 }catch(Throwable $e){
572
573 }
574 if($httpcode==200){
575 return true;
576 }else if($attempts>0){
577 $attempts--;
578 if($attempts==0){return false;}
579 return self::check_varnish($attempts);
580 }
581 }
582
583 public static function get_common_cache_urls(&$urls_to_purge){
584 if(empty($urls_to_purge)){
585 $urls_to_purge = [];
586 }
587
588 $urls_to_purge[] = get_home_url(); //always purge home page if any other page is modified
589 $urls_to_purge[] = get_home_url()."/"; //always purge home page if any other page is modified
590 $urls_to_purge[] = home_url('/'); //always purge home page if any other page is modified
591 $urls_to_purge[] = site_url('/'); //always purge home page if any other page is modified
592
593 //clean pagination urls
594 try{
595 if(!empty(get_option('page_for_posts'))){
596 $page_for_posts = get_permalink(get_option('page_for_posts'));
597 if(is_string($page_for_posts) && !empty($page_for_posts) && get_option('show_on_front') == 'page'){
598 $urls_to_purge[] = $page_for_posts;
599 }
600 }
601
602 $posts_per_page = get_option('posts_per_page');
603 $published_posts = RabbitLoader_21_Core::get_published_count();
604 $page_number_max = min(3, ceil($published_posts / $posts_per_page));
605 for($pn=1; $pn<$page_number_max; $pn++){
606 $urls_to_purge[] = home_url(sprintf('/page/%s/', $pn));
607 }
608 }catch(Throwable $e){
609 RabbitLoader_21_Core::on_exception($e);
610 }
611 }
612
613 public static function run_warmup($queued_offset, &$responses){
614 try{
615 RabbitLoader_21_Core::push_recent_posts($queued_offset, $queued_count, $published_count);
616 $responses['queued_offset'] = $queued_offset;
617 $responses['queued_count'] = $queued_count;
618 $responses['published_count'] = $published_count;
619 // Checking Hosting Name
620 $hosting_name = RabbitLoader_21_Core::checkHostingName();
621 if(!empty($hosting_name)){
622 $responses['hosting_name'] = $hosting_name;
623 }
624 RabbitLoader_21_Core::clean_orphaned_cached_files(1);
625 }catch(Throwable $e){
626 $responses['exception'] = true;
627 RabbitLoader_21_Core::on_exception($e);
628 }
629 }
630
631 public static function get_published_count(){
632 //$published_count = wp_count_posts()->publish + wp_count_posts('page')->publish;
633 $published_count = 0;
634 $post_types = get_post_types(['public' => true], 'names', 'and');
635 foreach ( $post_types as $post_type ) {
636 $published_count += wp_count_posts($post_type)->publish;
637 }
638 return $published_count + 1;//1 for home page
639 }
640
641 public static function push_recent_posts(&$offset=0, &$queued_count=0, &$published_count=0){
642 $permalinks = '';
643 $posts_per_page = 250;
644 $queued_count = 0;
645 $latest_modified_ts = 0;
646
647 //published posts
648 $published_count = RabbitLoader_21_Core::get_published_count();
649
650 $offset = intval($offset);
651 if($offset>$published_count){
652 $offset = 0;
653 }
654
655 $permalink_structure = get_option( 'permalink_structure' );
656 $append_slash = substr($permalink_structure, -1) == "/" ? true : false;
657 $args = array(
658 'post_status' => 'publish',
659 'post_type' => 'any',
660 'orderby' => 'post_date',
661 'order' => 'DESC',
662 'fields' => 'ids', // Only get post IDs
663 'posts_per_page' => $posts_per_page,
664 'offset'=>intval($offset),
665 'no_found_rows'=>false
666 );
667
668 try{
669 $posts = get_posts($args);
670 if(!empty($posts)){
671 foreach($posts as $post_id){
672 $the_post = get_post( $post_id );
673 $permalink = get_permalink($the_post);
674 if(empty($permalink)){
675 continue;
676 }
677 if($append_slash){
678 $permalink = trailingslashit($permalink);
679 }else{
680 $permalink = $permalink.$append_slash;
681 }
682
683 $modified_ts = strtotime(get_the_modified_date($the_post));
684 if($modified_ts > $latest_modified_ts){
685 $latest_modified_ts = $modified_ts;
686 }
687 if(!self::cache_exists_for_url($permalink, $modified_ts)){
688 $permalinks.=$permalink."\n";
689 ++$queued_count;
690 }
691 }
692 }else{
693 $offset = 0;
694 }
695 }catch(Throwable $e){
696 $responses['exception'] = true;
697 RabbitLoader_21_Core::on_exception($e);
698 }
699
700 //common URLs
701 try{
702 RabbitLoader_21_Core::get_common_cache_urls($urls_to_purge);
703 if(!empty($urls_to_purge)){
704 foreach($urls_to_purge as $url){
705 if(!self::cache_exists_for_url($url, $latest_modified_ts)){
706 $permalinks.=$url."\n";
707 ++$queued_count;
708 }
709 }
710 }
711 }catch(\Throwable $e){
712 RabbitLoader_21_Core::on_exception($e);
713 }
714
715 if(empty($permalinks)){
716 return;
717 }else{
718 RabbitLoader_21_Util_Core::fac('cache_missed', $permalinks, WP_DEBUG);
719 }
720 }
721
722 public static function run_diagnosis(&$responses){
723 $constants = get_defined_constants(true);
724 $constants = empty($constants['user']) ? [] : $constants['user'];
725 //remove known sensitive info
726 $sensitive_constants = ['DB_HOST', 'DB_NAME', 'DB_USER', 'DB_PASSWORD', 'AUTH_KEY', 'SECURE_AUTH_KEY', 'LOGGED_IN_KEY', 'NONCE_KEY', 'AUTH_SALT', 'SECURE_AUTH_SALT', 'LOGGED_IN_SALT', 'NONCE_SALT', 'COOKIEHASH', 'USER_COOKIE', 'PASS_COOKIE', 'AUTH_COOKIE', 'SECURE_AUTH_COOKIE', 'LOGGED_IN_COOKIE', 'RECOVERY_MODE_COOKIE'];
727 foreach($sensitive_constants as $const_name){
728 unset($constants[$const_name]);
729 }
730 $responses['server'] = $_SERVER;
731 $responses['constants'] = $constants;
732 $responses['classes'] = get_declared_classes();
733
734 try{
735 global $wpdb;
736 $responses['options'] = $wpdb->get_results("select option_id, option_name from $wpdb->options");
737 }catch(Throwable $e){
738 RabbitLoader_21_Core::on_exception($e);
739 }
740 }
741
742 private static function &checkHostingName(){
743 $hosting_name = 'NA';
744 if(!empty($_SERVER['cw_allowed_ip'])){
745 $hosting_name = $_SERVER['cw_allowed_ip'];
746 }
747 else if ( class_exists('WpeCommon') && method_exists( 'WpeCommon', 'purge_memcached' )) {
748 $hosting_name = 'wpengine';
749 }
750 else if(defined("KINSTAMU_VERSION")){
751 $hosting_name = 'Kinsta';
752 }
753 else if(defined("FLYWHEEL_PLUGIN_DIR")){
754 $hosting_name = 'flywheel';
755 }
756 else if(preg_match("/^dp-.+/", gethostname())){
757 $hosting_name = 'dreamhost';
758 }
759 else if(defined("CLOSTE_APP_ID")){
760 $hosting_name = 'closte';
761 }
762 else if(function_exists( 'sg_cachepress_purge_cache')) {
763 $hosting_name = 'siteground';
764 }
765 else if(class_exists('LiteSpeed_Cache_API') && method_exists('LiteSpeed_Cache_API', 'purge_all')) {
766 $hosting_name = 'litespeed';
767 }
768 else if(class_exists('PagelyCachePurge') && method_exists('PagelyCachePurge','purgeAll')) {
769 $hosting_name = 'pagely';
770 }
771 else if(class_exists('comet_cache') && method_exists('comet_cache', 'clear')) {
772 $hosting_name = 'comet';
773 }
774 else if(defined('IS_PRESSABLE')) {
775 $hosting_name = 'pressable';
776 }
777 return $hosting_name;
778 }
779 }
780 ?>