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

959 lines 33.1 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_file = bwp_get_cache_dir() . bwp_build_cache_path($page_url) . '/index.html.gz';
468
469 if (file_exists($cache_file)) {
470 unlink($cache_file);
471 }
472 }
473
474 public static function purge_page($page_url, $flush_criticalcss = false)
475 {
476
477 if (!berqwp_can_use_cloud()) {
478 $flush_criticalcss = false;
479 }
480
481 $page_url = strtolower($page_url);
482
483 // $page_path = bwp_intersect_str(home_url(), $page_path);
484 $slug = bwp_url_into_path($page_url);
485
486 self::delete_page_cache_files($page_url);
487
488 do_action('berqwp_flush_page_cache', $slug);
489
490 if ($flush_criticalcss) {
491 $berqwp = new BerqWP(berqwp_get_license_key(), null, null);
492 $berqwp->purge_criticlecss_url($page_url);
493 }
494
495 bwp_cf_flush_page(home_url($slug));
496 }
497
498 function handle_new_comment($comment_id, $comment_status)
499 {
500 if ($comment_status === 'approve') {
501 $comment = get_comment($comment_id);
502 $post_id = $comment->comment_post_ID;
503 $post_url = get_permalink($post_id);
504
505 self::purge_page($post_url);
506
507 global $berq_log;
508 $berq_log->info("New comment added, deleting cache for $post_url");
509 }
510 }
511
512 function bypass_cache()
513 {
514 if (
515 isset($_GET['nocache'])
516 || isset($_GET['bwp_preload'])
517 // || isset($_GET['creating_cache'])
518 || berqDetectCrawler::is_crawler() ||
519 (get_option('berqwp_enable_sandbox') == 1 && !isset($_GET['berqwp']) && !is_admin() && !isset($_POST))
520 ) {
521
522 add_filter('berqwp_bypass_cache', function () {
523 return true;
524 });
525
526 // if (berqReverseProxyCache::is_reverse_proxy_cache_enabled()) {
527 berqReverseProxyCache::bypass();
528 // }
529
530 }
531 }
532
533 function flush_reverse_proxy_cache($slug = '/.*')
534 {
535
536 if (empty($slug)) {
537 $slug = '/';
538 }
539
540 // if ($slug == '/') {
541 // $slug = '';
542 // }
543
544 $page_url = home_url($slug);
545 $host = !empty($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : '';
546 berqReverseProxyCache::purge_cache($page_url);
547 }
548
549 function ingore_tracking_params($tracking_params)
550 {
551 $tracking_params = array_merge($tracking_params, ignoreParams::$query_params);
552 return $tracking_params;
553 }
554
555 function clear_cache_on_post_update($post_id, $post, $update)
556 {
557
558 if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
559 return;
560 }
561
562 // if (!$update) {
563 // return;
564 // }
565
566 $can_flush_cache = apply_filters('berqwp_can_flush_cache_on_post_update', true);
567
568 if (!$can_flush_cache) {
569 return;
570 }
571
572 // If this is just a revision, don't run the function.
573 if (wp_is_post_revision($post_id)) {
574 return;
575 }
576
577 if (!is_admin()) {
578 return;
579 }
580
581 $post_type = get_post_type($post_id);
582 $post_url = get_permalink($post_id);
583
584 // We need path with query parameters
585 $parsed_url = parse_url($post_url);
586 $path = isset($parsed_url['path']) ? $parsed_url['path'] : '';
587 $query = isset($parsed_url['query']) ? '?' . $parsed_url['query'] : '';
588 $path_with_query = $path . $query;
589
590 if (berqwp_is_slug_excludable($path_with_query)) {
591 return;
592 }
593
594 // Potentially cachable post types
595 $cachable_post_type_names = get_post_types(array(
596 'public' => true,
597 ), 'names');
598 unset($cachable_post_type_names['attachment']);
599
600 if (!in_array($post_type, $cachable_post_type_names)) {
601 return;
602 }
603
604 global $berq_log;
605 $berq_log->info("Post updated [Post type - $post_type]: $post_url $post->post_status");
606
607 self::purge_page($post_url, true);
608
609 if (bwp_can_optimize_page_url($post_url)) {
610 warmup_cache_by_url($post_url);
611 }
612
613 $translation_urls = apply_filters('berqwp_page_translation_urls', [], $post_url);
614
615 if (!empty($translation_urls)) {
616 foreach ($translation_urls as $url) {
617
618 $berq_log->info("Purging translation for $post_url");
619 self::purge_page($url, true);
620 }
621 }
622
623 $this->flush_post_taxonomy_cache($post_id);
624 $this->flush_author_cache($post_id);
625 }
626
627 function flush_cdn()
628 {
629 $parsed_url = wp_parse_url(home_url());
630 $domain = $parsed_url['host'];
631
632 $args = [
633 'timeout' => 30,
634 'sslverify' => false,
635 'body' => ['flush_cdn' => $domain, 'license_key' => berqwp_get_license_key()]
636 ];
637
638 wp_remote_post('https://boost.berqwp.com/photon/', $args);
639
640 // Flush cache
641 $this->delete_cache_files();
642
643 // clear local static files
644
645 $dir = optifer_cache . '/static/';
646
647 if (! is_dir($dir)) {
648 return;
649 }
650
651 $files = glob(rtrim($dir, '/') . '/*');
652
653 foreach ($files as $file) {
654 if (is_file($file)) {
655 unlink($file);
656 }
657 }
658
659 update_option('berqwp_uploaded_assets', [], false);
660
661 do_action('berqwp_purge_cdn');
662 }
663
664 function delete_cache_files($flush_all_sites = false)
665 {
666 global $berq_log;
667 $berq_log->info("Flushing all cache.");
668
669 // Define the cache directory
670 $cache_directory = bwp_get_cache_dir();
671
672 if (is_multisite() && $flush_all_sites) {
673 $cache_directory = optifer_cache . '/html/';
674 }
675
676 // Delete all cache files within the directory
677 berqwp_unlink_recursive($cache_directory);
678
679 // Delete external CSS cache
680 $external_cache_dir = optifer_cache . 'external/';
681 if (is_dir($external_cache_dir)) {
682 berqwp_unlink_recursive($external_cache_dir);
683 }
684
685 delete_transient('berqwp_warmup_running');
686 delete_transient('cache_warmup_in_progress');
687 delete_transient('berqwp_doing_cache_warmup');
688
689 // Remove require cache warning
690 update_option('bwp_require_flush_cache', 0);
691
692 do_action('berqwp_flush_all_cache');
693 }
694
695 static function should_cache() {
696 // Check if the current user is logged in and only allow GET requests
697 if (is_user_logged_in() || $_SERVER['REQUEST_METHOD'] !== 'GET') {
698 return false;
699 }
700
701 if (isset($_GET['creating_cache'])) {
702 return false;
703 }
704
705 if (is_admin() || is_preview() || is_404() || is_search()) {
706 return false;
707 }
708
709 if (defined('DOING_CRON') && DOING_CRON) {
710 return false;
711 }
712
713 if (defined('DOING_AJAX') && DOING_AJAX) {
714 return false;
715 }
716
717 if (defined('REST_REQUEST') && REST_REQUEST) {
718 return false;
719 }
720
721 if (php_sapi_name() === 'cli' || defined('WP_CLI')) {
722 return false;
723 }
724
725 if (!bwp_is_webpage()) {
726 return false;
727 }
728
729 if (!bwp_pass_cookie_requirement()) {
730 return false;
731 }
732
733 $berqconfigs = berqConfigs::getInstance();
734 $configs = $berqconfigs->get_configs();
735
736 if (empty($configs['optimization_method'])) {
737 return false;
738 }
739
740 if (berqwp_can_use_cloud()) {
741
742 if (empty(berqwp_get_license_key())) {
743 return false;
744 }
745
746 // if (!bwp_pass_account_requirement()) {
747 // return false;
748 // }
749
750 }
751
752
753 $bypass_cache = apply_filters('berqwp_bypass_cache', false);
754
755 if ($bypass_cache) {
756 return false;
757 }
758
759 return true;
760 }
761
762 static function get_page_url() {
763 $page_url = bwp_get_request_url();
764
765 // For sitemaps
766 if (strpos($page_url, '.xml') !== false || strpos($page_url, '.xsl') !== false) {
767 return;
768 }
769
770 // Return if page is excluded from cache
771 $current_page_url = bwp_get_request_url();
772
773 if (strpos($current_page_url, '?') !== false) {
774 $current_page_url = explode('?', $current_page_url)[0];
775 }
776
777 if (berqwp_is_page_url_excluded($current_page_url)) {
778 return;
779 }
780
781 // Remove ignored params from the slug
782 // $slug = berqwp_remove_ignore_params($slug_uri);
783 $page_url = berqwp_remove_ignore_params($page_url);
784
785 if (get_option('berqwp_enable_sandbox') == 1 && isset($_GET['berqwp'])) {
786 $page_url = explode('?berqwp', $page_url)[0];
787 } elseif (get_option('berqwp_enable_sandbox') == 1 && !isset($_GET['creating_cache'])) {
788 return false;
789 }
790
791 if (berqwp_is_slug_excludable($page_url)) {
792 return false;
793 }
794
795 return $page_url;
796 }
797
798 static function queue_page($page_url = null) {
799
800
801 if (empty($page_url)) {
802
803 if (!self::should_cache()) {
804 return;
805 }
806
807 $page_url = self::get_page_url();
808 }
809
810 if (empty($page_url)) {
811 return false;
812 }
813
814 // Disable cache for unknown query parameters
815 if (strpos($page_url, '?') !== false) {
816 return false;
817 }
818
819 if (!berqwp_can_use_cloud()) {
820 return false;
821 }
822
823 $status_code = http_response_code();
824
825 if ($status_code !== 200) {
826 return false;
827 }
828
829 // berqHeartbeat::add_queue($page_url);
830 warmup_cache_by_url($page_url);
831 }
832
833 function html_cache()
834 {
835
836 // Bypass cache for Photon
837 if (!empty($_COOKIE['berqwpnocache'])) {
838 header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0', true);
839 header('CDN-Cache-Control: no-store', true); // Cloudflare
840 header('Surrogate-Control: no-store', true); // Varnish
841 header('X-Accel-Expires: 0', true); // Nginx FastCGI
842
843 return;
844 }
845
846 if (!self::should_cache()) {
847 return;
848 }
849
850 $page_url = self::get_page_url();
851
852 if (empty($page_url)) {
853 return;
854 }
855
856 // Disable cache for unknown query parameters
857 if (strpos($page_url, '?') !== false) {
858 return;
859 }
860
861 if (is_singular()) {
862 $post_type = get_post_type();
863
864 if (empty($post_type) || !in_array($post_type, get_option('berqwp_optimize_post_types'))) {
865 return;
866 }
867 } elseif (is_archive()) {
868 $queried_object = get_queried_object();
869
870 if ($queried_object instanceof WP_Term && !empty($queried_object->taxonomy)) {
871 $current_taxonomy = $queried_object->taxonomy;
872
873 if (!in_array($current_taxonomy, get_option('berqwp_optimize_taxonomies'))) {
874 return;
875 }
876 }
877 }
878
879
880 $status_code = http_response_code();
881
882 if ($status_code !== 200) {
883 return;
884 }
885
886 $berqconfigs = berqConfigs::getInstance();
887 $configs = $berqconfigs->get_configs();
888 $cache_key = md5($page_url);
889 $cache_directory = bwp_get_cache_dir();
890
891 $cache_file = $cache_directory . bwp_build_cache_path($page_url) . '/index.html.gz';
892 $cache_max_life = file_exists($cache_file) ? @filemtime($cache_file) + $configs['cache_lifespan'] : null;
893
894 if (file_exists($cache_file) && $cache_max_life > time()) {
895 header_remove('Content-Encoding');
896
897 $lastModified = filemtime($cache_file);
898 $etag = md5_file($cache_file);
899 header('ETag: ' . $etag);
900 header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $lastModified) . ' GMT');
901 header('X-File-Size: ' . filesize($cache_file), true);
902 header('Content-Type: text/html; charset=utf-8');
903 header("X-served: WP Hook");
904 header('Vary: Cookie');
905
906 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)) {
907 // The client's cache is still valid based on Last-Modified, respond with a 304 Not Modified
908 header('HTTP/1.1 304 Not Modified');
909 // header('Expires: ' . gmdate('D, d M Y H:i:s') . ' GMT');
910 header("Expires: 0");
911 header('Cache-Control: no-cache, must-revalidate');
912 exit();
913 }
914
915 header('Cache-Control: public, max-age=0, s-maxage=3600, must-revalidate', true);
916 header('Vary: Accept-Encoding, Cookie');
917 header('Content-Encoding: gzip', true);
918 header('Content-Length: ' . filesize($cache_file), true);
919 readfile($cache_file);
920 exit();
921 }
922
923 header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
924 header('CDN-Cache-Control: no-store'); // Cloudflare
925 header('Surrogate-Control: no-store'); // Varnish
926 header('X-Accel-Expires: 0'); // Nginx FastCGI
927
928 self::purge_page($page_url);
929
930 if (!berqwp_can_use_cloud()) {
931 try {
932
933 $berqPageOptimizer = new berqPageOptimizer();
934 $berqPageOptimizer->set_slug(bwp_url_into_path($page_url));
935 $berqPageOptimizer->set_page($page_url);
936 $berqPageOptimizer->start_cache();
937 unset($berqPageOptimizer);
938
939 } catch (Exception $e) {
940 global $berq_log;
941 $berq_log->error($e->getMessage());
942 return;
943 } catch (Throwable $e) {
944 global $berq_log;
945 $berq_log->error($e->getMessage());
946 return;
947 }
948
949 }
950
951 return;
952 }
953
954 }
955
956 // $cache = new berqCache();
957 $cache = berqCache::getInstance();
958 }
959