PluginProbe
BerqWP – All-In-One Optimization for Core Web Vitals, Cache, CDN, Images, CSS & JavaScript / 4.0.16
BerqWP – All-In-One Optimization for Core Web Vitals, Cache, CDN, Images, CSS & JavaScript v4.0.16
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 / cache / class-berqcache.php

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

954 lines 33.0 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 use BerqWP\BerqWP;
6
7 if (!class_exists('berqCache')) {
8 class berqCache
9 {
10 public static $instance = null;
11
12 function __construct()
13 {
14
15 $this->process_migration();
16
17 add_filter('berqwp_ignored_urls_params', [$this, 'ingore_tracking_params']);
18
19 add_action('template_redirect', [$this, 'queue_page'], 11);
20
21 if (!isset($_GET['bwp_preload'])) {
22 add_action('wp', [$this, 'html_cache'], 2);
23 }
24
25 // Clear page cache on update
26 add_action('save_post', [$this, 'clear_cache_on_post_update'], 10, 3);
27
28 // // Automatic cache warmup
29 // // add_action('init', [$this, 'warmup_home']);
30 // add_action('berqwp_flush_all_cache', [$this, 'warmup_home']);
31 // add_action('warmup_cache_quickly', 'warmup_cache_by_url');
32 // add_action('bwp_warmup_sitemap', [$this, 'warmup_sitemap']);
33 // add_action('berqwp_flush_all_cache', [$this, 'request_warmup_cache']);
34 // add_action('berqwp_cache_warmup', [$this, 'request_warmup_cache']);
35
36 // Delete cache files when the mode changes
37 add_action('berqwp_before_update_optimization_mode', [$this, 'delete_cache_files']);
38
39 // Reverse proxy cache support
40 add_action('berqwp_stored_page_cache', [$this, 'flush_reverse_proxy_cache']);
41 add_action('berqwp_flush_all_cache', ['berqReverseProxyCache', 'flush_all']);
42 add_action('berqwp_flush_page_cache', [$this, 'flush_reverse_proxy_cache']);
43
44 // Clear cache warmup lock after storing the cache
45 add_action('berqwp_stored_page_cache', 'bwp_clear_warmup_lock');
46
47 add_action('init', [$this, 'bypass_cache']);
48
49 add_action('init', [$this, 'bypass_cache']);
50
51 // Flush cache when there's a new comment
52 add_action('wp_set_comment_status', [$this, 'handle_new_comment'], 10, 2);
53
54 // Store cache without any need for the rest api
55 add_action('init', 'bwp_webhook');
56
57 // Handle request new cache request
58 add_action('init', 'bwp_handle_request_cache');
59
60 // Flush cache when theme changes
61 add_action('switch_theme', [$this, 'delete_cache_files']);
62
63 // Flush critical css when theme changes
64 add_action('switch_theme', [$this, 'purge_critical_css_cache']);
65
66 // Flush critical css when custimizer additional css is updated
67 add_action('customize_save_css', [$this, 'purge_critical_css_cache']);
68
69 // Request cache when a post is published
70 // clear_cache_on_post_update and handle_post_status_update almost do the same thing
71 // add_action( 'transition_post_status', [$this, 'handle_post_status_update'], 10, 3 );
72
73 add_action('send_headers', [$this, 'brust_cache_for_loggedin']);
74
75 // Purge home page when new post is published
76 add_action('transition_post_status', [$this, 'purge_home'], 10, 3);
77
78 // flush cloudflare edge cache
79 add_action('berqwp_stored_page_cache', [$this, 'flush_cf_page']);
80 add_action('berqwp_flush_page_cache', [$this, 'flush_cf_page']);
81 add_action('berqwp_flush_all_cache', 'bwp_cf_flush_all');
82 add_action('berqwp_update_sandbox_mode', 'bwp_cf_flush_all');
83 add_action('berqwp_deactivate_plugin', 'bwp_cf_delete_rules');
84 add_action('berqwp_activate_plugin', [$this, 'check_cf_rules']);
85
86 // Apache htaccess cache rules (skip on LiteSpeed — remove any existing rules)
87 add_action('berqwp_activate_plugin', 'bwp_write_htaccess_rules');
88 add_action('berqwp_flush_all_cache', 'bwp_write_htaccess_rules');
89 add_action('berqwp_deactivate_plugin', 'bwp_remove_htaccess_rules');
90 if (bwp_is_openlitespeed_server()) {
91 add_action('berqwp_activate_plugin', 'bwp_remove_htaccess_rules');
92 }
93 add_action('berqwp_update_sandbox_mode', 'bwp_sync_htaccess_on_sandbox_change');
94
95 // Clear queue list on cloud
96 add_action('berqwp_deactivate_plugin', 'berqwp_clear_cache_queue');
97
98 // Edit post type list custom links
99 $bwp_post_types = get_option('berqwp_optimize_post_types');
100
101 if (is_admin() && !empty($bwp_post_types)) {
102 foreach ($bwp_post_types as $post_type) {
103 add_filter("{$post_type}_row_actions", [$this, 'post_type_action_links'], 10, 2);
104 }
105 }
106
107 // detect when theme/plugin is installed or updated
108 add_action( 'upgrader_process_complete', [$this, 'process_updates'], 10, 2 );
109 }
110
111 static function getInstance() {
112
113 if (self::$instance === null) {
114 $instance = new berqCache();
115 self::$instance = $instance;
116 return $instance;
117 }
118
119 return self::$instance;
120 }
121
122 function process_updates( WP_Upgrader $upgrader, array $hook_extra ) {
123
124 if (!berqwp_can_use_cloud()) {
125 return;
126 }
127
128 $berqwp = new BerqWP(berqwp_get_license_key(), null, null);
129 $parsed_url = wp_parse_url(home_url());
130 $domain = $parsed_url['host'];
131
132 global $berq_log;
133 $berq_log->info("Processing updates");
134
135 // mark cdn assets stale
136 $berqwp->cdn_stale_assets($domain);
137
138 // flush all critical css cache
139 $berqwp->purge_critilclcss($domain);
140
141 }
142
143 function process_migration() {
144 $raw_home = get_option('home');
145
146 if (defined('WP_HOME')) {
147 $raw_home = WP_HOME;
148 }
149
150 // detect migration when home changes
151 if (get_option('berqwp_raw_home', $raw_home) !== $raw_home) {
152 global $berq_log;
153 $berq_log->info('Raw home url change detected, flushing all cache');
154
155 if (get_option('berqwp_raw_home', $raw_home) !== null) {
156 $berq_log->info('Home url change detected, flushing all cache');
157 }
158
159 // regenerate site id
160 $berqconfigs = berqConfigs::getInstance();
161 $blog_id = get_current_blog_id();
162 $network_id = function_exists('get_current_network_id') ? get_current_network_id() : 1;
163 $siteurl = get_option('siteurl');
164 $site_id = md5("berqwp|$network_id|$blog_id|$siteurl");
165
166 $berqconfigs->update_configs(['site_id' => $site_id, 'secret' => '']);
167
168
169 // Flush critical css
170 $parsed_url = wp_parse_url(home_url());
171 $domain = $parsed_url['host'];
172 $berqwp = new BerqWP(berqwp_get_license_key(), null, null);
173 $berqwp->purge_critilclcss($domain);
174
175 // Flush page cache
176 $this->delete_cache_files();
177
178 update_option('berqwp_raw_home', $raw_home);
179 delete_transient('berq_lic_response_cache');
180 delete_transient('berqwp_lic_response_cache');
181 }
182 }
183
184 function post_type_action_links($actions, $post)
185 {
186
187 $page_url = get_permalink($post->ID);
188 $url = wp_nonce_url(admin_url('admin-post.php?action=berq_purge_page&uri=' . urlencode($page_url)), 'berq_purge_page_action');
189
190 $actions['berqwp_flush_cache'] = '<a href="' . esc_url($url) . '">Flush Cache</a>';
191
192 $url = wp_nonce_url(admin_url('admin-post.php?action=berq_request_cache&uri=' . urlencode($page_url)), 'berq_request_cache_action');
193
194 $actions['berqwp_force_cache'] = '<a href="' . esc_url($url) . '">Force Cache</a>';
195
196 return $actions;
197 }
198
199 function check_cf_rules()
200 {
201 if (!empty(get_option('berqwp_cf_creden'))) {
202 $email = get_option('berqwp_cf_creden')['email'];
203 $apitoken = get_option('berqwp_cf_creden')['apitoken'];
204 $zoneid = get_option('berqwp_cf_creden')['zoneid'];
205 $berqCloudflareAPIHandler = new berqCloudflareAPIHandler($email, $apitoken, $zoneid);
206
207 if ($berqCloudflareAPIHandler->verify_credentials()) {
208 $berqCloudflareAPIHandler->add_rule();
209 $berqCloudflareAPIHandler->purge_all_cache();
210 return;
211 }
212
213 delete_option('berqwp_cf_creden');
214 }
215 }
216
217 function flush_author_cache($post_id)
218 {
219 // Bail out on autosaves and revisions
220 if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE)
221 return;
222 if (wp_is_post_revision($post_id))
223 return;
224
225 $post = get_post($post_id);
226 if (!$post)
227 return;
228
229 global $berq_log;
230
231 // Get current author ID
232 $current_author_id = $post->post_author;
233
234 // Get original author ID before any potential changes
235 $original_post = wp_get_post_revision($post_id);
236 $original_author_id = $original_post ? $original_post->post_author : $current_author_id;
237
238 // Collect all author IDs that need flushing
239 $author_ids = array_unique([$current_author_id, $original_author_id]);
240
241 foreach ($author_ids as $author_id) {
242 // Skip invalid author IDs
243 if (!$author_id || !get_userdata($author_id))
244 continue;
245
246 // Get author archive URL
247 $author_link = get_author_posts_url($author_id);
248 if (!is_wp_error($author_link) && !empty($author_link)) {
249 $berq_log->info("Purging author cache: $author_link");
250 self::purge_page($author_link);
251
252 // Handle translations for multilingual author archives
253 $translation_urls = apply_filters('berqwp_page_translation_urls', [], $author_link);
254 if (!empty($translation_urls)) {
255 foreach ($translation_urls as $url) {
256 $berq_log->info("Purging author translation cache: $url");
257 self::purge_page($url);
258 }
259 }
260 }
261 }
262 }
263
264 function flush_post_taxonomy_cache($post_id)
265 {
266 // Bail out on autosaves and revisions.
267 if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
268 return;
269 }
270 if (wp_is_post_revision($post_id)) {
271 return;
272 }
273
274 $post = get_post($post_id);
275 if (!$post) {
276 return;
277 }
278
279 global $berq_log;
280
281 // Get all taxonomies registered for this post type.
282 $taxonomies = get_object_taxonomies($post->post_type);
283 if (!empty($taxonomies)) {
284 // Clear the object term cache for the post.
285 clean_object_term_cache($post_id, $taxonomies);
286
287 // Loop through each taxonomy.
288 foreach ($taxonomies as $taxonomy) {
289
290 if (!in_array($taxonomy, get_option('berqwp_optimize_taxonomies'))) {
291 continue;
292 }
293
294 // Get all terms for this post in the current taxonomy.
295 $terms = get_the_terms($post_id, $taxonomy);
296 if (empty($terms) || is_wp_error($terms)) {
297 continue;
298 }
299
300 foreach ($terms as $term) {
301 // Clear the term cache for the original term.
302 clean_object_term_cache($term->term_id, $taxonomy);
303
304 // Collect terms to purge: original term and its ancestors (if hierarchical)
305 $terms_to_purge = array($term);
306
307 // Check if taxonomy is hierarchical to process ancestors
308 if (is_taxonomy_hierarchical($taxonomy)) {
309 $ancestor_ids = get_ancestors($term->term_id, $taxonomy, 'taxonomy');
310 foreach ($ancestor_ids as $ancestor_id) {
311 $ancestor_term = get_term($ancestor_id, $taxonomy);
312 if ($ancestor_term && !is_wp_error($ancestor_term)) {
313 $terms_to_purge[] = $ancestor_term;
314 }
315 }
316 }
317
318 // Process each term (original and ancestors)
319 foreach ($terms_to_purge as $term_to_purge) {
320 $term_link = get_term_link($term_to_purge);
321 if (is_wp_error($term_link)) {
322 continue;
323 }
324
325 $berq_log->info("Purging cache for term $term_link");
326 self::purge_page($term_link);
327
328 // Handle translations
329 $translation_urls = apply_filters('berqwp_page_translation_urls', array(), $term_link);
330 if (!empty($translation_urls)) {
331 foreach ($translation_urls as $url) {
332 $berq_log->info("Purging taxonomy translation for $url");
333 self::purge_page($url);
334 }
335 }
336 }
337 }
338 }
339 }
340 }
341
342 function purge_critical_css_cache()
343 {
344 $parsed_url = wp_parse_url(home_url());
345 $domain = $parsed_url['host'];
346 $berqwp = new BerqWP(berqwp_get_license_key(), null, null);
347 $berqwp->purge_critilclcss($domain);
348 }
349
350 function flush_cf_page($slug = '')
351 {
352 if (empty($slug)) {
353 $slug = '/';
354 }
355 $url = home_url($slug);
356 bwp_cf_flush_page($url);
357 }
358
359 function purge_home($new_status, $old_status, $post)
360 {
361
362 $can_flush_cache = apply_filters('berqwp_can_flush_home_cache_on_post_update', true);
363
364 if (!$can_flush_cache) {
365 return;
366 }
367
368 if ($new_status == 'auto-draft') {
369 return;
370 }
371
372 if ($new_status == 'trash') {
373 return;
374 }
375
376 if ($new_status == 'publish' && $old_status == 'publish') {
377 return;
378 }
379
380 // if ($old_status == 'new' && $new_status == 'draft') {
381 // return;
382 // }
383
384 // if statement skips when scheduled post publishes
385 // with admin wp cron request
386 // if (!is_admin()) {
387 // $berq_log->info('Trasition post status admin' . ' ' . $new_status);
388 // return;
389 // }
390
391 $post_types = apply_filters('berqwp_purge_home_post_types', ['post']);
392
393 if (in_array($post->post_type, $post_types)) {
394 global $berq_log;
395 $berq_log->info('Purging homepage. Triggered by post type: ' . $post->post_type . ' ' . $old_status . ' ' . $new_status);
396 $home_url = home_url('/');
397 self::purge_page($home_url);
398 warmup_cache_by_url($home_url, true);
399 }
400
401 $blog_page_id = get_option('page_for_posts');
402
403 if ($blog_page_id) {
404
405 $blog_url = get_permalink($blog_page_id);
406
407 global $berq_log;
408 $berq_log->info('Purging blog page: ' . $blog_url);
409
410 self::purge_page($blog_url);
411 warmup_cache_by_url($blog_url);
412 }
413 }
414
415 function brust_cache_for_loggedin()
416 {
417 if (is_user_logged_in()) {
418 // Add Vary: Cookie header to differentiate cached versions for logged-in users
419 header('Vary: Cookie');
420 header("Cache-Control: no-cache, no-store, must-revalidate");
421 header("Pragma: no-cache");
422 header("Expires: 0");
423 }
424 }
425
426 function handle_post_status_update($new_status, $old_status, $post)
427 {
428 // Get the post types that should be optimized from BerqWP settings
429 $post_types = get_option('berqwp_optimize_post_types');
430
431 // Get the published post URL
432 $post_url = get_permalink($post);
433
434 // Only proceed if the post is being published (from any status to 'publish')
435 if ('publish' === $new_status && 'publish' !== $old_status) {
436
437 // Check if the post type is in the list of types to be optimized
438 if (in_array($post->post_type, $post_types)) {
439
440 // We need path with query parameters
441 $parsed_url = parse_url($post_url);
442 $path = isset($parsed_url['path']) ? $parsed_url['path'] : '';
443 $query = isset($parsed_url['query']) ? '?' . $parsed_url['query'] : '';
444 $path_with_query = $path . $query;
445
446 if (berqwp_is_slug_excludable($path_with_query)) {
447 return;
448 }
449
450 global $berq_log;
451 $berq_log->info("Post status updated $post_url");
452
453 if (bwp_can_optimize_page_url($post_url)) {
454 warmup_cache_by_url($post_url);
455 }
456
457 self::purge_page($post_url, true);
458
459 $this->flush_post_taxonomy_cache($post->ID);
460 $this->flush_author_cache($post->ID);
461 }
462 }
463 }
464
465 public static function delete_page_cache_files($page_url)
466 {
467 $cache_dir = bwp_get_cache_dir() . bwp_build_cache_path($page_url);
468
469 if (is_dir($cache_dir)) {
470 berqwp_unlink_recursive($cache_dir);
471 }
472
473 }
474
475 public static function purge_page($page_url, $flush_criticalcss = false)
476 {
477
478 if (!berqwp_can_use_cloud()) {
479 $flush_criticalcss = false;
480 }
481
482 $page_url = strtolower($page_url);
483
484 // $page_path = bwp_intersect_str(home_url(), $page_path);
485 $slug = bwp_url_into_path($page_url);
486
487 self::delete_page_cache_files($page_url);
488
489 do_action('berqwp_flush_page_cache', $slug);
490
491 if ($flush_criticalcss) {
492 $berqwp = new BerqWP(berqwp_get_license_key(), null, null);
493 $berqwp->purge_criticlecss_url($page_url);
494 }
495
496 bwp_cf_flush_page(home_url($slug));
497 }
498
499 function handle_new_comment($comment_id, $comment_status)
500 {
501 if ($comment_status === 'approve') {
502 $comment = get_comment($comment_id);
503 $post_id = $comment->comment_post_ID;
504 $post_url = get_permalink($post_id);
505
506 self::purge_page($post_url);
507
508 global $berq_log;
509 $berq_log->info("New comment added, deleting cache for $post_url");
510 }
511 }
512
513 function bypass_cache()
514 {
515 if (
516 isset($_GET['nocache'])
517 || isset($_GET['bwp_preload'])
518 // || isset($_GET['creating_cache'])
519 || berqDetectCrawler::is_crawler() ||
520 (get_option('berqwp_enable_sandbox') == 1 && !isset($_GET['berqwp']) && !is_admin() && !isset($_POST))
521 ) {
522
523 add_filter('berqwp_bypass_cache', function () {
524 return true;
525 });
526
527 // if (berqReverseProxyCache::is_reverse_proxy_cache_enabled()) {
528 berqReverseProxyCache::bypass();
529 // }
530
531 }
532 }
533
534 function flush_reverse_proxy_cache($slug = '/.*')
535 {
536
537 if (empty($slug)) {
538 $slug = '/';
539 }
540
541 // if ($slug == '/') {
542 // $slug = '';
543 // }
544
545 $page_url = home_url($slug);
546 $host = !empty($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : '';
547 berqReverseProxyCache::purge_cache($page_url);
548 }
549
550 function ingore_tracking_params($tracking_params)
551 {
552 $tracking_params = array_merge($tracking_params, ignoreParams::$query_params);
553 return $tracking_params;
554 }
555
556 function clear_cache_on_post_update($post_id, $post, $update)
557 {
558
559 if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
560 return;
561 }
562
563 // if (!$update) {
564 // return;
565 // }
566
567 $can_flush_cache = apply_filters('berqwp_can_flush_cache_on_post_update', true);
568
569 if (!$can_flush_cache) {
570 return;
571 }
572
573 // If this is just a revision, don't run the function.
574 if (wp_is_post_revision($post_id)) {
575 return;
576 }
577
578 if (!is_admin()) {
579 return;
580 }
581
582 $post_type = get_post_type($post_id);
583 $post_url = get_permalink($post_id);
584
585 // We need path with query parameters
586 $parsed_url = parse_url($post_url);
587 $path = isset($parsed_url['path']) ? $parsed_url['path'] : '';
588 $query = isset($parsed_url['query']) ? '?' . $parsed_url['query'] : '';
589 $path_with_query = $path . $query;
590
591 if (berqwp_is_slug_excludable($path_with_query)) {
592 return;
593 }
594
595 // Potentially cachable post types
596 $cachable_post_type_names = get_post_types(array(
597 'public' => true,
598 ), 'names');
599 unset($cachable_post_type_names['attachment']);
600
601 if (!in_array($post_type, $cachable_post_type_names)) {
602 return;
603 }
604
605 global $berq_log;
606 $berq_log->info("Post updated [Post type - $post_type]: $post_url $post->post_status");
607
608 self::purge_page($post_url, true);
609
610 if (bwp_can_optimize_page_url($post_url)) {
611 warmup_cache_by_url($post_url);
612 }
613
614 $translation_urls = apply_filters('berqwp_page_translation_urls', [], $post_url);
615
616 if (!empty($translation_urls)) {
617 foreach ($translation_urls as $url) {
618
619 $berq_log->info("Purging translation for $post_url");
620 self::purge_page($url, true);
621 }
622 }
623
624 $this->flush_post_taxonomy_cache($post_id);
625 $this->flush_author_cache($post_id);
626 }
627
628 function flush_cdn()
629 {
630 $parsed_url = wp_parse_url(home_url());
631 $domain = $parsed_url['host'];
632
633 $args = [
634 'timeout' => 30,
635 'sslverify' => false,
636 'body' => ['flush_cdn' => $domain, 'license_key' => berqwp_get_license_key()]
637 ];
638
639 wp_remote_post('https://boost.berqwp.com/photon/', $args);
640
641 // Flush cache
642 $this->delete_cache_files();
643
644 // clear local static files
645
646 $dir = optifer_cache . '/static/';
647
648 if (! is_dir($dir)) {
649 return;
650 }
651
652 $files = glob(rtrim($dir, '/') . '/*');
653
654 foreach ($files as $file) {
655 if (is_file($file)) {
656 unlink($file);
657 }
658 }
659
660 update_option('berqwp_uploaded_assets', [], false);
661
662 do_action('berqwp_purge_cdn');
663 }
664
665 function delete_cache_files($flush_all_sites = false)
666 {
667 global $berq_log;
668 $berq_log->info("Flushing all cache.");
669
670 // Define the cache directory
671 $cache_directory = bwp_get_cache_dir();
672
673 if (is_multisite() && $flush_all_sites) {
674 $cache_directory = optifer_cache . '/html/';
675 }
676
677 // Delete all cache files within the directory
678 berqwp_unlink_recursive($cache_directory);
679
680 // Delete external CSS cache
681 $external_cache_dir = optifer_cache . 'external/';
682 if (is_dir($external_cache_dir)) {
683 berqwp_unlink_recursive($external_cache_dir);
684 }
685
686 delete_transient('berqwp_warmup_running');
687 delete_transient('cache_warmup_in_progress');
688 delete_transient('berqwp_doing_cache_warmup');
689
690 // Remove require cache warning
691 update_option('bwp_require_flush_cache', 0);
692
693 do_action('berqwp_flush_all_cache');
694 }
695
696 static function should_cache() {
697 // Check if the current user is logged in and only allow GET requests
698 if (is_user_logged_in() || $_SERVER['REQUEST_METHOD'] !== 'GET') {
699 return false;
700 }
701
702 if (isset($_GET['creating_cache'])) {
703 return false;
704 }
705
706 if (is_admin() || is_preview() || is_404() || is_search()) {
707 return false;
708 }
709
710 if (defined('DOING_CRON') && DOING_CRON) {
711 return false;
712 }
713
714 if (defined('DOING_AJAX') && DOING_AJAX) {
715 return false;
716 }
717
718 if (defined('REST_REQUEST') && REST_REQUEST) {
719 return false;
720 }
721
722 if (php_sapi_name() === 'cli' || defined('WP_CLI')) {
723 return false;
724 }
725
726 if (!bwp_is_webpage()) {
727 return false;
728 }
729
730 if (!bwp_pass_cookie_requirement()) {
731 return false;
732 }
733
734 $berqconfigs = berqConfigs::getInstance();
735 $configs = $berqconfigs->get_configs();
736
737 if (empty($configs['optimization_method'])) {
738 return false;
739 }
740
741 if (berqwp_can_use_cloud()) {
742
743 if (empty(berqwp_get_license_key())) {
744 return false;
745 }
746
747 // if (!bwp_pass_account_requirement()) {
748 // return false;
749 // }
750
751 }
752
753
754 $bypass_cache = apply_filters('berqwp_bypass_cache', false);
755
756 if ($bypass_cache) {
757 return false;
758 }
759
760 return true;
761 }
762
763 static function get_page_url() {
764 $page_url = bwp_get_request_url();
765
766 // For sitemaps
767 if (strpos($page_url, '.xml') !== false || strpos($page_url, '.xsl') !== false) {
768 return;
769 }
770
771 // Return if page is excluded from cache
772 $current_page_url = bwp_get_request_url();
773
774 if (strpos($current_page_url, '?') !== false) {
775 $current_page_url = explode('?', $current_page_url)[0];
776 }
777
778 if (berqwp_is_page_url_excluded($current_page_url)) {
779 return;
780 }
781
782 // Remove ignored params from the slug
783 // $slug = berqwp_remove_ignore_params($slug_uri);
784 $page_url = berqwp_remove_ignore_params($page_url);
785
786 if (get_option('berqwp_enable_sandbox') == 1 && isset($_GET['berqwp'])) {
787 $page_url = explode('?berqwp', $page_url)[0];
788 } elseif (get_option('berqwp_enable_sandbox') == 1 && !isset($_GET['creating_cache'])) {
789 return false;
790 }
791
792 if (berqwp_is_slug_excludable($page_url)) {
793 return false;
794 }
795
796 return $page_url;
797 }
798
799 static function queue_page($page_url = null) {
800
801
802 if (empty($page_url)) {
803
804 if (!self::should_cache()) {
805 return;
806 }
807
808 $page_url = self::get_page_url();
809 }
810
811 if (empty($page_url)) {
812 return false;
813 }
814
815 // Disable cache for unknown query parameters
816 if (strpos($page_url, '?') !== false) {
817 return false;
818 }
819
820 if (!berqwp_can_use_cloud()) {
821 return false;
822 }
823
824 // berqHeartbeat::add_queue($page_url);
825 warmup_cache_by_url($page_url);
826 }
827
828 function html_cache()
829 {
830
831 // Bypass cache for Photon
832 if (!empty($_COOKIE['berqwpnocache'])) {
833 header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0', true);
834 header('CDN-Cache-Control: no-store', true); // Cloudflare
835 header('Surrogate-Control: no-store', true); // Varnish
836 header('X-Accel-Expires: 0', true); // Nginx FastCGI
837
838 return;
839 }
840
841 if (!self::should_cache()) {
842 return;
843 }
844
845 $page_url = self::get_page_url();
846
847 if (empty($page_url)) {
848 return;
849 }
850
851 // Disable cache for unknown query parameters
852 if (strpos($page_url, '?') !== false) {
853 return;
854 }
855
856 if (is_singular()) {
857 $post_type = get_post_type();
858
859 if (empty($post_type) || !in_array($post_type, get_option('berqwp_optimize_post_types'))) {
860 return;
861 }
862 } elseif (is_archive()) {
863 $queried_object = get_queried_object();
864
865 if ($queried_object instanceof WP_Term && !empty($queried_object->taxonomy)) {
866 $current_taxonomy = $queried_object->taxonomy;
867
868 if (!in_array($current_taxonomy, get_option('berqwp_optimize_taxonomies'))) {
869 return;
870 }
871 }
872 }
873
874
875 $status_code = http_response_code();
876
877 if ($status_code !== 200) {
878 return;
879 }
880
881 $berqconfigs = berqConfigs::getInstance();
882 $configs = $berqconfigs->get_configs();
883 $cache_key = md5($page_url);
884 $cache_directory = bwp_get_cache_dir();
885
886 $cache_file = $cache_directory . bwp_build_cache_path($page_url) . '/index.html.gz';
887 $cache_max_life = file_exists($cache_file) ? @filemtime($cache_file) + $configs['cache_lifespan'] : null;
888
889 if (file_exists($cache_file) && $cache_max_life > time()) {
890 header_remove('Content-Encoding');
891
892 $lastModified = filemtime($cache_file);
893 $etag = md5_file($cache_file);
894 header('ETag: ' . $etag);
895 header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $lastModified) . ' GMT');
896 header('X-File-Size: ' . filesize($cache_file), true);
897 header('Content-Type: text/html; charset=utf-8');
898 header("X-served: WP Hook");
899 header('Vary: Cookie');
900
901 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)) {
902 // The client's cache is still valid based on Last-Modified, respond with a 304 Not Modified
903 header('HTTP/1.1 304 Not Modified');
904 // header('Expires: ' . gmdate('D, d M Y H:i:s') . ' GMT');
905 header("Expires: 0");
906 header('Cache-Control: no-cache, must-revalidate');
907 exit();
908 }
909
910 header('Cache-Control: public, max-age=0, s-maxage=3600, must-revalidate', true);
911 header('Vary: Accept-Encoding, Cookie');
912 header('Content-Encoding: gzip', true);
913 header('Content-Length: ' . filesize($cache_file), true);
914 readfile($cache_file);
915 exit();
916 }
917
918 header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
919 header('CDN-Cache-Control: no-store'); // Cloudflare
920 header('Surrogate-Control: no-store'); // Varnish
921 header('X-Accel-Expires: 0'); // Nginx FastCGI
922
923 self::purge_page($page_url);
924
925 if (!berqwp_can_use_cloud()) {
926 try {
927
928 $berqPageOptimizer = new berqPageOptimizer();
929 $berqPageOptimizer->set_slug(bwp_url_into_path($page_url));
930 $berqPageOptimizer->set_page($page_url);
931 $berqPageOptimizer->start_cache();
932 unset($berqPageOptimizer);
933
934 } catch (Exception $e) {
935 global $berq_log;
936 $berq_log->error($e->getMessage());
937 return;
938 } catch (Throwable $e) {
939 global $berq_log;
940 $berq_log->error($e->getMessage());
941 return;
942 }
943
944 }
945
946 return;
947 }
948
949 }
950
951 // $cache = new berqCache();
952 $cache = berqCache::getInstance();
953 }
954