PluginProbe
BerqWP – All-In-One Optimization for Core Web Vitals, Cache, CDN, Images, CSS & JavaScript / 1.9.5
BerqWP – All-In-One Optimization for Core Web Vitals, Cache, CDN, Images, CSS & JavaScript v1.9.5
4.1.16 4.1.15 4.1.14 4.1.13 4.1.12 4.1.11 4.1.10 4.0.30 4.0.29 4.0.28 4.0.27 4.0.26 4.0.24 4.0.25 4.0.23 4.0.22 4.0.21 4.0.19 4.0.18 4.0.17 4.0.16 1.9.3 1.9.4 1.9.5 1.9.6 All 170 releases
searchpro / inc / class-berqcache.php

class-berqcache.php in BerqWP – All-In-One Optimization for Core Web Vitals, Cache, CDN, Images, CSS & JavaScript 1.9.5, at inc/class-berqcache.php

945 lines 34.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if (!defined('ABSPATH'))
3 exit;
4
5 if (!class_exists('berqCache')) {
6 class berqCache
7 {
8 public $cache_file;
9 public $max_page_per_batch = 5;
10
11 function __construct()
12 {
13 $this->max_page_per_batch = apply_filters( 'berqwp_max_pages_per_batch', 5 );
14
15 add_filter( 'berqwp_ignored_urls_params', [$this, 'ingore_tracking_params'] );
16
17 // $this->cache_file = berqwp_current_page_cache_file();
18
19 // clear cache after migration
20 if (get_option('berqwp_site_url', home_url()) !== home_url()) {
21
22 if (get_option('berqwp_site_url', home_url()) !== null) {
23 global $berq_log;
24 $berq_log->info('Home url change detected, flushing all cache');
25 }
26
27 $this->delete_cache_files();
28 update_option('berqwp_site_url', home_url());
29 delete_transient( 'berq_lic_response_cache' );
30 }
31
32 global $berqwp_is_dropin;
33 if (empty($berqwp_is_dropin)) {
34 add_action('wp', [$this, 'html_cache'], 2);
35 }
36
37 // Add clear cache link to admin bar
38 add_action('admin_bar_menu', [$this, 'add_clear_cache_link_to_admin_bar'], 999);
39
40 // Flush cache
41 add_action('admin_post_clear_cache', [$this, 'handle_clear_cache_action']);
42
43 // Purge a page cache
44 add_action('admin_post_berq_purge_page', [$this, 'handle_berq_purge_page_action']);
45
46 // Request page cache
47 add_action('admin_post_berq_request_cache', [$this, 'handle_berq_request_cache_action']);
48
49 // Flush CDN cache
50 add_action('admin_post_berq_flush_cdn', [$this, 'handle_berq_flush_cdn_action']);
51
52 // Flush critical CSS cache
53 add_action('admin_post_berq_flush_criticalcss', [$this, 'handle_berq_flush_criticalcss_action']);
54
55 // Clear page cache on update
56 add_action('save_post', [$this, 'clear_cache_on_post_udpate'], 10, 3);
57
58 // Automatic cache warmup
59 add_action('init', [$this, 'warmup_queue']);
60 add_action('warmup_cache_by_slug', [$this, 'handle_warmup_cache_by_slug']);
61 add_action('warmup_cache_quickly', 'warmup_cache_by_slug');
62 add_action('admin_notices', [$this, 'cache_warmup_admin_notice']);
63
64
65 // add_action('wp_loaded', [$this, 'berqwp_warmup_cache_all_pages']);
66
67 add_action('berqwp_before_update_optimization_mode', [$this, 'delete_cache_files']);
68
69 // Reverse proxy cache support
70 add_action('berqwp_stored_page_cache', [$this, 'flush_reverse_proxy_cache']);
71 add_action('berqwp_flush_all_cache', [$this, 'flush_reverse_proxy_cache']);
72 add_action('berqwp_flush_page_cache', [$this, 'flush_reverse_proxy_cache']);
73
74 // Clear cache warmup lock after storing the cache
75 add_action('berqwp_stored_page_cache', 'bwp_clear_warmup_lock');
76
77 add_action('init', [$this, 'bypass_cache']);
78
79
80 }
81
82 function bypass_cache() {
83 if (isset($_GET['generating_critical_css'])
84 || isset($_GET['nocache'])
85 || isset($_GET['creating_cache']) || berqDetectCrawler::is_crawler() ||
86 (get_option('berqwp_enable_sandbox') == 1 && !isset($_GET['berqwp']) && !is_admin() && !isset($_POST))) {
87
88 add_filter( 'berqwp_bypass_cache', function () { return true; } );
89
90 // if (berqReverseProxyCache::is_reverse_proxy_cache_enabled()) {
91 berqReverseProxyCache::bypass();
92 // }
93
94 }
95 }
96
97 function flush_reverse_proxy_cache($slug = '/.*') {
98
99 if (empty($slug)) {
100 $slug = '/.*'; // Purge all cache
101 }
102
103 if ($slug == '/') {
104 $slug = '';
105 }
106
107 $page_url = home_url() . $slug;
108 berqReverseProxyCache::purge_cache($page_url);
109 }
110
111 function ingore_tracking_params($tracking_params) {
112 $tracking_params = array_merge($tracking_params, ignoreParams::$query_params);
113 return $tracking_params;
114 }
115
116 function berqwp_warmup_cache_all_pages()
117 {
118
119 if (isset($_GET['run_warmup'])) {
120
121 global $berq_log;
122 $berq_log->info('* * * * * * * * * * * * *');
123 $berq_log->info('* Manual Cache Warmup');
124 $berq_log->info('* * * * * * * * * * * * *');
125
126 // Get all published pages and posts
127 $args = array(
128 'post_type' => array('page'),
129 'post_status' => 'publish',
130 'posts_per_page' => -1, // Get all posts
131 );
132 $query = new WP_Query($args);
133
134 // API endpoint URL
135 $api_endpoint = 'https://boost.berqwp.com/photon/';
136
137 if (get_site_url() == 'http://berq-test.local') {
138 $api_endpoint = 'http://dev-berqwp.local/photon/';
139 }
140
141 $httpMulti = new bwp_multi_http();
142
143
144 // Loop through each post/page and warm up the cache
145 if ($query->have_posts()) {
146 while ($query->have_posts()) {
147 $query->the_post();
148 $url = trailingslashit(get_permalink()); // Get the permalink of the post/page
149
150 // $httpMulti->addRequest('GET', $url);
151 $slug = str_replace(home_url(), '', $url);
152 $post_data = berqwp_get_page_params($slug, true);
153
154 $httpMulti->addRequest('POST', $api_endpoint, $post_data);
155
156 $berq_log->info("Requesting cache for $slug");
157 }
158 }
159
160 $responses = $httpMulti->execute();
161 wp_reset_postdata();
162
163 }
164
165 }
166
167 function warmup_queue()
168 {
169 $wp_content_adv_cache = ABSPATH . 'wp-content/advanced-cache.php';
170 $bwp_adv_cache = optifer_PATH . 'advanced-cache.php';
171
172 if (
173 (!file_exists($wp_content_adv_cache) && get_option('berqwp_enable_sandbox') !== 1)
174 || (file_exists($wp_content_adv_cache) && md5_file($wp_content_adv_cache) !== md5_file($bwp_adv_cache))
175 ) {
176 // Specify the drop-in file path
177 $dropin_file = ABSPATH . 'wp-content/advanced-cache.php';
178
179 // Dynamically create the drop-in file
180 $dropin_content = file_get_contents(optifer_PATH . 'advanced-cache.php');
181
182 // Write the drop-in content to the file, replacing any existing file
183 file_put_contents($dropin_file, $dropin_content);
184
185 // Enable object cache in wp-config.php
186 berqwp_enable_object_cache(true);
187
188 if (function_exists('wp_cache_flush')) {
189 wp_cache_flush(); // Clear the entire object cache.
190 }
191 }
192
193 if (get_option('berqwp_enable_sandbox') == 1 && file_exists($wp_content_adv_cache)) {
194 unlink($wp_content_adv_cache);
195 }
196
197 if (false === as_has_scheduled_action('warmup_cache_by_slug')) {
198 $post_types = get_option('berqwp_optimize_post_types');
199
200 $args = array(
201 'post_type' => $post_types,
202 'posts_per_page' => -1,
203 'fields' => 'ids',
204 'post_status' => 'publish',
205 );
206
207 $query = new WP_Query($args);
208
209 // Calculate the total number of pages
210 $total_posts = count($query->posts);
211
212 $posts_per_batch = $this->max_page_per_batch;
213 $total_pages = ceil($total_posts / $posts_per_batch);
214
215
216 // Schedule the events
217 for ($page = 1; $page <= $total_pages; $page++) {
218 as_schedule_single_action(time() + (80 * $page), 'warmup_cache_by_slug', array($page));
219 }
220
221 wp_reset_postdata();
222 }
223
224 if (false === as_has_scheduled_action('warmup_cache_quickly') && (bwp_is_home_cached() === false || bwp_is_partial_cache('/')) && function_exists('as_enqueue_async_action')) {
225 as_enqueue_async_action('warmup_cache_quickly', ['/', true]);
226 }
227
228
229
230 }
231
232 function can_send_warmup_request()
233 {
234 $requests_sent = get_transient('berqwp_warmup_requests_count');
235
236 // If we haven't set the rate limiting transient yet, or if we're still below our rate, return true.
237 if (false === $requests_sent || $requests_sent < BERQWP_MAX_WARMUP_REQUESTS) {
238 return true;
239 }
240
241 return false;
242 }
243
244 function update_warmup_request_count()
245 {
246 $requests_sent = get_transient('berqwp_warmup_requests_count');
247
248 if (false === $requests_sent) {
249 // If this is the first request in our window, set the transient with a timeout.
250 set_transient('berqwp_warmup_requests_count', 1, BERQWP_WARMUP_RATE_LIMIT_WINDOW);
251 } else {
252 // Otherwise, just increment the counter.
253 set_transient('berqwp_warmup_requests_count', ++$requests_sent, BERQWP_WARMUP_RATE_LIMIT_WINDOW);
254 }
255 }
256
257
258
259 function handle_warmup_cache_by_slug($page)
260 {
261 global $berq_log;
262 $berq_log->info("handle_warmup_cache_by_slug triggered");
263
264 // error_log('-page-' . $page);
265 if ($this->can_send_warmup_request()) {
266 // error_log('page-' . $page);
267 $this->warmup_cache($page);
268 $this->update_warmup_request_count();
269 } else {
270 $berq_log->info("handle_warmup_cache_by_slug cache skipped");
271 // You've hit the rate limit.
272 $retry_after_seconds = 200; // Retry after 10 minutes. You can adjust this time as needed.
273 // as_schedule_single_action(time() + $retry_after_seconds, 'warmup_cache_by_slug', array($page));
274 }
275 }
276
277
278
279 function clear_cache_on_post_udpate($post_id, $post, $update)
280 {
281 // If this is just a revision, don't run the function.
282 if (wp_is_post_revision($post_id)) {
283 return;
284 }
285
286 $post_url = get_permalink($post_id);
287 $slug = str_replace(home_url(), '', $post_url);
288 $cache_key = md5($slug);
289 $cache_directory = optifer_cache . '/html/';
290 $cache_file = $cache_directory . $cache_key . '.html';
291
292 global $berq_log;
293 $berq_log->info("Post updated, deleting cache for $post_url");
294
295 if (file_exists($cache_file)) {
296 unlink($cache_file);
297 }
298
299 }
300
301 function flatten_array($array)
302 {
303 $result = array();
304 foreach ($array as $item) {
305 if (is_array($item)) {
306 $result = array_merge($result, $this->flatten_array($item));
307 } else {
308 $result[] = $item;
309 }
310 }
311 return $result;
312 }
313
314 function handle_berq_purge_page_action()
315 {
316 // Check if the user has the necessary nonce and the action matches
317 if (isset($_GET['action']) && $_GET['action'] === 'berq_purge_page' && wp_verify_nonce($_GET['_wpnonce'], 'berq_purge_page_action')) {
318
319 $slug = sanitize_text_field($_GET['uri']);
320 $cache_file = optifer_cache . '/html/' . md5($slug) . '.html';
321
322 if (is_file($cache_file)) {
323 unlink($cache_file);
324 }
325
326 $cache_file = optifer_cache . '/html/' . md5($slug) . '.gz';
327
328 if (is_file($cache_file)) {
329 unlink($cache_file);
330 }
331
332
333 if (function_exists('wp_cache_flush')) {
334 wp_cache_flush(); // Clear the entire object cache.
335 }
336
337 do_action('berqwp_flush_page_cache', $slug);
338
339 // Redirect back to the referring page after clearing the cache
340 wp_safe_redirect(wp_get_referer());
341 exit;
342 }
343 }
344
345 function handle_berq_request_cache_action()
346 {
347 // Check if the user has the necessary nonce and the action matches
348 if (isset($_GET['action']) && $_GET['action'] === 'berq_request_cache' && wp_verify_nonce($_GET['_wpnonce'], 'berq_request_cache_action')) {
349
350 $slug = sanitize_text_field($_GET['uri']);
351
352 as_enqueue_async_action('warmup_cache_quickly', [$slug, true]);
353
354 // Redirect back to the referring page after clearing the cache
355 wp_safe_redirect(wp_get_referer());
356 exit;
357 }
358 }
359
360 function handle_berq_flush_cdn_action()
361 {
362 // Check if the user has the necessary nonce and the action matches
363 if (isset($_GET['action']) && $_GET['action'] === 'berq_flush_cdn' && wp_verify_nonce($_GET['_wpnonce'], 'berq_flush_cdn_action')) {
364
365 $parsed_url = wp_parse_url(home_url());
366 $domain = $parsed_url['host'];
367
368 $args = [
369 'timeout' => 30,
370 'body' => ['flush_cdn' => $domain, 'license_key' => get_option('berqwp_license_key')]
371 ];
372
373 wp_remote_post( 'https://boost.berqwp.com/photon/', $args );
374
375 // Flush cache
376 $this->delete_cache_files();
377
378 do_action( 'berqwp_purge_cdn' );
379
380 set_transient('berq_purge_cdn_notice', 'true', 60);
381
382 // Redirect back to the referring page after clearing the cache
383 wp_safe_redirect(wp_get_referer());
384 exit;
385 }
386 }
387
388 function handle_berq_flush_criticalcss_action()
389 {
390 // Check if the user has the necessary nonce and the action matches
391 if (isset($_GET['action']) && $_GET['action'] === 'berq_flush_criticalcss' && wp_verify_nonce($_GET['_wpnonce'], 'berq_flush_criticalcss_action')) {
392
393 $parsed_url = wp_parse_url(home_url());
394 $domain = $parsed_url['host'];
395
396 $args = [
397 'timeout' => 30,
398 'body' => ['flush_criticalcss' => $domain, 'license_key' => get_option('berqwp_license_key')]
399 ];
400
401 wp_remote_post( 'https://boost.berqwp.com/photon/', $args );
402
403 do_action( 'berqwp_purge_criticalcss' );
404
405 set_transient('berq_purge_criticalcss_notice', 'true', 60);
406
407 // Redirect back to the referring page after clearing the cache
408 wp_safe_redirect(wp_get_referer());
409 exit;
410 }
411 }
412
413 function handle_clear_cache_action()
414 {
415 // Check if the user has the necessary nonce and the action matches
416 if (isset($_GET['action']) && $_GET['action'] === 'clear_cache' && wp_verify_nonce($_GET['_wpnonce'], 'clear_cache_action')) {
417 // Call your custom cache clearing function here
418 $this->delete_cache_files();
419
420 if (function_exists('wp_cache_flush')) {
421 wp_cache_flush(); // Clear the entire object cache.
422 }
423
424 set_transient('berq_cache_cleared_notice', 'true', 60);
425
426 $redirect_url = add_query_arg('berq_clear_cache', '', wp_get_referer());
427
428 // Redirect back to the referring page after clearing the cache
429 wp_safe_redirect($redirect_url);
430 exit;
431 }
432 }
433
434 function delete_cache_files()
435 {
436 global $berq_log;
437 $berq_log->info("Flushing all cache.");
438
439 // Define the cache directory
440 $cache_directory = optifer_cache . '/html/';
441
442 // Delete all cache files within the directory
443 berqwp_unlink_recursive($cache_directory);
444
445 delete_transient('berqwp_warmup_running');
446 delete_transient('cache_warmup_in_progress');
447 delete_transient('berqwp_doing_cache_warmup');
448
449 do_action('berqwp_flush_all_cache');
450 }
451
452 function add_clear_cache_link_to_admin_bar()
453 {
454 global $wp_admin_bar;
455
456 // Check if the user has the capability to clear the cache (adjust the capability as needed)
457 if (current_user_can('manage_options')) {
458 $wp_admin_bar->add_menu(
459 array(
460 'id' => 'berqWP',
461 'title' => 'BerqWP',
462 'href' => get_admin_url() . '/admin.php?page=berqwp',
463 )
464 );
465
466 // Add the sub-menu item
467 $wp_admin_bar->add_menu(
468 array(
469 'parent' => 'berqWP',
470 // ID of the parent menu item
471 'id' => 'flush-cache',
472 'title' => 'Flush cache',
473 'href' => wp_nonce_url(admin_url('admin-post.php?action=clear_cache'), 'clear_cache_action'),
474 'meta' => array(
475 'class' => 'clear-cache-link',
476 'title' => 'Clear BerqWP cache',
477 ),
478 )
479 );
480
481 $wp_admin_bar->add_menu(
482 array(
483 'parent' => 'berqWP',
484 // ID of the parent menu item
485 'id' => 'flush-cdn',
486 'title' => 'Flush CDN & page cache',
487 'href' => wp_nonce_url(admin_url('admin-post.php?action=berq_flush_cdn'), 'berq_flush_cdn_action'),
488 'meta' => array(
489 'class' => 'flush-cdn-cache',
490 'title' => 'Flush CDN & page cache',
491 ),
492 )
493 );
494
495 $wp_admin_bar->add_menu(
496 array(
497 'parent' => 'berqWP',
498 // ID of the parent menu item
499 'id' => 'flush-criticalcss',
500 'title' => 'Flush critical CSS cache',
501 'href' => wp_nonce_url(admin_url('admin-post.php?action=berq_flush_criticalcss'), 'berq_flush_criticalcss_action'),
502 'meta' => array(
503 'class' => 'flush-criticalcss',
504 'title' => 'Flush critical CSS cache',
505 ),
506 )
507 );
508
509 if (!is_admin()) {
510 // Add the sub-menu item
511 $wp_admin_bar->add_menu(
512 array(
513 'parent' => 'berqWP',
514 // ID of the parent menu item
515 'id' => 'purge-page',
516 'title' => 'Purge this page',
517 'href' => wp_nonce_url(admin_url('admin-post.php?action=berq_purge_page&uri=' . urlencode($_SERVER['REQUEST_URI'])), 'berq_purge_page_action'),
518 'meta' => array(
519 'class' => 'purge-page-link',
520 'title' => 'Clear this page cache',
521 ),
522 )
523 );
524
525 // Add the request cache
526 $wp_admin_bar->add_menu(
527 array(
528 'parent' => 'berqWP',
529 // ID of the parent menu item
530 'id' => 'request-page-cache',
531 'title' => 'Request cache',
532 'href' => wp_nonce_url(admin_url('admin-post.php?action=berq_request_cache&uri=' . urlencode($_SERVER['REQUEST_URI'])), 'berq_request_cache_action'),
533 'meta' => array(
534 'class' => 'request-page-cache-link',
535 'title' => 'Request cache for this page',
536 ),
537 )
538 );
539
540 }
541
542 }
543 }
544
545 static function is_cache_file_expired($cache_file) {
546 $cache_max_life = filemtime($cache_file) + (18 * 60 * 60);
547
548 // is still valide
549 if ($cache_max_life > time()) {
550 return false;
551 }
552
553 return true;
554 }
555
556
557 function html_cache()
558 {
559 // Check if the current user is logged in or if it's a POST request
560 if (is_user_logged_in() || $_SERVER['REQUEST_METHOD'] === 'POST') {
561 return;
562 }
563
564 if (is_admin()) {
565 return;
566 }
567
568 if (defined('DOING_CRON') && DOING_CRON) {
569 return;
570 }
571
572 if (defined('DOING_AJAX') && DOING_AJAX) {
573 return;
574 }
575
576 if (defined('REST_REQUEST') && REST_REQUEST) {
577 return;
578 }
579
580 if (php_sapi_name() === 'cli' || defined('WP_CLI')) {
581 return;
582 }
583
584 $bypass_cache = apply_filters( 'berqwp_bypass_cache', false );
585
586 if ($bypass_cache) {
587 return;
588 }
589
590 $slug_uri = $_SERVER['REQUEST_URI'];
591
592 // if wordpress is installed in a sub directory
593 if (berqwp_is_sub_dir_wp()) {
594 // Parse strings to extract paths
595 $path1 = explode('/', parse_url(home_url(), PHP_URL_PATH));
596 $path2 = explode('/', parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH));
597
598 // Find the common part of the paths
599 $commonPath = implode('/', array_intersect($path1, $path2));
600
601 // Subtract the common part from the first string
602 $slug_uri = str_replace($commonPath, '', $_SERVER['REQUEST_URI']);
603 }
604
605 // Return if page is excluded from cache
606 $pages_to_exclude = get_option('berq_exclude_urls', []);
607
608 if (in_array(home_url() . $slug_uri, $pages_to_exclude)) {
609 return;
610 }
611
612 // Remove ignored params from the slug
613 $slug = berqwp_remove_ignore_params($slug_uri);
614
615 if (isset($_GET['creating_cache'])) {
616 return;
617 }
618
619 if (get_option('berqwp_enable_sandbox') == 1 && isset($_GET['berqwp'])) {
620 $slug = explode('?berqwp', $slug_uri)[0];
621 } elseif (get_option('berqwp_enable_sandbox') == 1 && !isset($_GET['creating_cache'])) {
622 return;
623 }
624
625 if (is_singular()) {
626 $post_type = get_post_type();
627
628 if (empty($post_type) || !in_array($post_type, get_option('berqwp_optimize_post_types'))) {
629 return;
630 }
631 } elseif (is_archive()) {
632 $queried_object = get_queried_object();
633
634 if ($queried_object instanceof WP_Term && !empty($queried_object->taxonomy)) {
635 $current_taxonomy = $queried_object->taxonomy;
636
637 if (!in_array($current_taxonomy, get_option('berqwp_optimize_taxonomies'))) {
638 return;
639 }
640 }
641 }
642
643
644 // Attempt to retrieve the cached HTML from the cache directory
645 $cache_directory = optifer_cache . '/html/';
646
647 // Generate a unique cache key based on the current page URL
648 $cache_key = md5($slug);
649 $cache_file = $cache_directory . $cache_key . '.html';
650
651
652 $status_code = http_response_code();
653
654 if ($status_code !== 200) {
655 return;
656 }
657
658 if (berqwp_is_slug_excludable($slug)) {
659 return;
660 }
661
662 // Account requirement doesn't meet && not updating existing cache
663 if (!file_exists($cache_file) && bwp_pass_account_requirement() === false) {
664 return;
665 }
666
667 $berqPageOptimizer = new berqPageOptimizer();
668 $berqPageOptimizer->set_slug($slug);
669 $berqPageOptimizer->start_cache();
670 unset($berqPageOptimizer);
671
672
673 if (!isset($_GET['creating_cache'])) {
674 if (strpos($slug, '?creating_cache') === false) {
675 // $page_modified_time = berqwp_get_last_modified_timestamp();
676 $cache_life_span = time() - (18 * 60 * 60);
677
678 // Hook to modify cache lifespan
679 $cache_life_span = apply_filters('berqwp_cache_lifespan', $cache_life_span);
680
681 if (bwp_is_gzip_supported() && file_exists($cache_directory . $cache_key . '.gz')) {
682 $cache_file = $cache_directory . $cache_key . '.gz';
683 header('Content-Encoding: gzip');
684 header('Content-Type: text/html; charset=UTF-8');
685 }
686
687 if (
688 (!file_exists($cache_file) ||
689 (file_exists($cache_file) && $this->is_cache_file_expired($cache_file)) ) ||
690 (file_exists($cache_file) && bwp_is_partial_cache($slug) === true)
691 && bwp_can_warmup_cache($slug)
692 ) {
693
694 global $berq_log;
695 $startTime = microtime(true);
696
697 $args = array(
698 'blocking' => false,
699 'timeout' => 0.01,
700 'body' => array(
701 'slug' => $slug,
702 ),
703 );
704
705 wp_remote_post(get_site_url() . '/wp-json/optifer/v1/warmup-cache', $args);
706
707 // Get end time
708 $endTime = microtime(true);
709
710 // Calculate runtime in milliseconds
711 $runtime = ($endTime - $startTime) * 1000;
712
713 $berq_log->info("Requesting cache for $slug took $runtime ms from frontend.");
714
715 }
716
717 }
718 }
719
720 // If the cached HTML file exists, serve it and stop further execution
721 if (!isset($_GET['creating_cache']) && file_exists($cache_file)) {
722 $lastModified = filemtime($cache_file);
723 $etag = md5_file($cache_file);
724 header('ETag: ' . $etag);
725 header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $lastModified) . ' GMT');
726
727 // Check if the client has a cached copy and if it's still valid using Last-Modified
728 if ((isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) >= $lastModified) || (isset($_SERVER['HTTP_IF_NONE_MATCH']) && $_SERVER['HTTP_IF_NONE_MATCH'] === $etag)) {
729 // The client's cache is still valid based on Last-Modified, respond with a 304 Not Modified
730 header('HTTP/1.1 304 Not Modified');
731 header('Expires: ' . gmdate('D, d M Y H:i:s') . ' GMT');
732 header('Cache-Control: no-cache, must-revalidate');
733 exit();
734
735 } else {
736
737 header('Cache-Control: public, max-age=86400');
738
739 if (file_exists($cache_file)) {
740 readfile($cache_file);
741 exit();
742 }
743
744 }
745 }
746
747 if (berqReverseProxyCache::is_reverse_proxy_cache_enabled()) {
748 berqReverseProxyCache::handle_bypass();
749 }
750
751 return;
752
753 }
754
755 function warmup_cache($page)
756 {
757 global $berq_log;
758 $berq_log->info("* * * * * * * * *");
759 $berq_log->info("* Cache Warmup");
760 $berq_log->info("* * * * * * * * *");
761
762 $posts_per_batch = $this->max_page_per_batch;
763
764 // if (get_transient('berqwp_doing_cache_warmup')) {
765 // return;
766 // }
767
768 // set_transient('berqwp_doing_cache_warmup', true, 120);
769
770 // Set a transient to indicate that the cache warmup is in progress
771 set_transient('cache_warmup_in_progress', true, 120);
772
773 // warmup_cache_by_slug('/');
774
775 // $post_types = get_post_types(array('publicly_queryable' => true), 'names');
776 $post_types = get_option('berqwp_optimize_post_types');
777
778 // API endpoint URL
779 $api_endpoint = 'https://boost.berqwp.com/photon/';
780
781 if (get_site_url() == 'http://berq-test.local') {
782 $api_endpoint = 'http://dev-berqwp.local/photon/';
783 }
784
785 // Modify photon engine endpoint for testing purposes
786 $api_endpoint = apply_filters( 'berqwp_photon_endpoint', $api_endpoint );
787
788 // $post_types[] = 'product';
789 $args = array(
790 'post_type' => $post_types,
791 'posts_per_page' => $posts_per_batch,
792 'paged' => $page,
793 );
794
795 $check_rest = bwp_check_rest_api(true);
796 if ( $check_rest['status'] == 'error' ) {
797 global $berq_log;
798 $berq_log->error('Exiting cron cache warmup, rest api not working.');
799 return;
800 }
801
802 $query = new WP_Query($args);
803
804 $httpMulti = new bwp_multi_http();
805
806 $post_data = berqwp_get_page_params('/');
807 $httpMulti->addRequest('POST', $api_endpoint, $post_data);
808
809 // Loop through all posts and make a GET request
810 while ($query->have_posts()) {
811 $query->the_post();
812
813 // Get the post URL and make a GET request
814 $url = trailingslashit(get_permalink());
815 $slug = str_replace(home_url(), '', $url);
816 $post_data = berqwp_get_page_params($slug);
817
818 // Skip if page is excluded from cache
819 $pages_to_exclude = get_option('berq_exclude_urls', []);
820
821 // Attempt to retrieve the cached HTML from the cache directory
822 $cache_directory = optifer_cache . '/html/';
823
824 // Generate a unique cache key based on the current page URL
825 $cache_key = md5($slug);
826 $cache_file = $cache_directory . $cache_key . '.html';
827 $page_modified_time = berqwp_get_last_modified_timestamp();
828 $cache_life_span = time() - (18 * 60 * 60);
829
830 if (!file_exists($cache_file) && bwp_pass_account_requirement() === false) {
831 $berq_log->info("Exiting cache $slug");
832 continue;
833 }
834
835 if (in_array($url, $pages_to_exclude)) {
836
837 if (file_exists($cache_file)) {
838 unlink($cache_file);
839 }
840
841 continue;
842 }
843
844 if (berqwp_is_slug_excludable($slug)) {
845 continue;
846 }
847
848 // Hook to modify cache lifespan
849 $cache_life_span = apply_filters('berqwp_cache_lifespan', $cache_life_span);
850
851 if (
852 !file_exists($cache_file) ||
853 ($this->is_cache_file_expired($cache_file)) ||
854 (file_exists($cache_file) && bwp_is_partial_cache($slug) === true) ||
855 (file_exists($cache_file) && !empty($page_modified_time) && $page_modified_time > filemtime($cache_file))
856 ) {
857 $httpMulti->addRequest('POST', $api_endpoint, $post_data);
858
859 $berq_log->info("Requesting cache for $slug");
860
861 }
862
863
864 }
865
866 $responses = $httpMulti->execute();
867
868 wp_reset_postdata();
869
870 delete_transient('cache_warmup_in_progress');
871 delete_transient('berqwp_doing_cache_warmup');
872
873 }
874
875
876 function cache_warmup_admin_notice()
877 {
878
879
880 if (get_transient('cache_warmup_in_progress')) {
881 ?>
882 <div class="notice notice-info is-dismissible">
883 <p>
884 <?php
885 esc_html_e('Cache warmup is in progress... This process could take some time depending on the number of pages on your website.', 'searchpro');
886 ?>
887 </p>
888 </div>
889 <?php
890 }
891
892 if (!get_transient('cache_warmup_in_progress') && isset($_GET['berq_warmingup'])) {
893 ?>
894 <div class="notice notice-info is-dismissible">
895 <p>
896 <?php esc_html_e('BerqWP is starting cache warmup. Please wait.', 'searchpro'); ?>
897 </p>
898 </div>
899 <?php
900 }
901
902 if (get_transient('berq_cache_cleared_notice')) {
903 delete_transient('berq_cache_cleared_notice');
904 ?>
905 <div class="notice notice-success is-dismissible">
906 <p>
907 <strong><?php esc_html_e('Success: ', 'searchpro'); ?></strong>
908 <?php esc_html_e('The cache has been cleared. Our automatic cache warm-up system will generate the cache. Alternatively, you can
909 visit any page to create its cache immediately.', 'searchpro'); ?>
910 </p>
911 </div>
912 <?php
913 }
914
915 if (get_transient('berq_purge_cdn_notice')) {
916 delete_transient('berq_purge_cdn_notice');
917 ?>
918 <div class="notice notice-success is-dismissible">
919 <p>
920 <strong><?php esc_html_e('Success: ', 'searchpro'); ?></strong>
921 <?php esc_html_e('The CDN and page cache have been flushed.', 'searchpro'); ?>
922 </p>
923 </div>
924 <?php
925 }
926
927 if (get_transient('berq_purge_criticalcss_notice')) {
928 delete_transient('berq_purge_criticalcss_notice');
929 ?>
930 <div class="notice notice-success is-dismissible">
931 <p>
932 <strong><?php esc_html_e('Success: ', 'searchpro'); ?></strong>
933 <?php esc_html_e('Critical CSS cache has been flushed from the cloud.', 'searchpro'); ?>
934 </p>
935 </div>
936 <?php
937 }
938 }
939
940 }
941
942 $cache = new berqCache();
943
944 }
945