PluginProbe
RabbitLoader / 2.18.2
RabbitLoader v2.18.2
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.18.2, at inc/core/core.php

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