PluginProbe
BerqWP – All-In-One Optimization for Core Web Vitals, Cache, CDN, Images, CSS & JavaScript / 4.0.27
BerqWP – All-In-One Optimization for Core Web Vitals, Cache, CDN, Images, CSS & JavaScript v4.0.27
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-berqwp.php

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

1,626 lines 53.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 as BerqWPCloud;
6 use BerqWP\RateLimiter;
7
8 if (!class_exists('berqWP')) {
9 class berqWP
10 {
11
12 public $is_key_verified = false;
13 public $key_response = false;
14 public static $instance = null;
15
16 public $conflicting_plugins = [
17 'autoptimize/autoptimize.php', // Autoptimize
18 'wp-super-cache/wp-cache.php', // WP Super Cache
19 'w3-total-cache/w3-total-cache.php', // W3 Total Cache
20 'wp-fastest-cache/wpFastestCache.php', // WP Fastest Cache
21 'litespeed-cache/litespeed-cache.php', // LiteSpeed Cache
22 'cache-enabler/cache-enabler.php', // Cache Enabler
23 'hummingbird-performance/wp-hummingbird.php', // Hummingbird – Speed up, Cache, Optimize Your CSS and JS
24 'sg-cachepress/sg-cachepress.php', // SiteGround Optimizer (for those hosted on SiteGround)
25 'wp-rocket/wp-rocket.php', // WP Rocket
26 'breeze/breeze.php', // Breeze (Cloudways)
27 'comet-cache/comet-cache.php', // Comet Cache
28 'hyper-cache/plugin.php', // Hyper Cache
29 'simple-cache/simple-cache.php', // Simple Cache
30 'wp-optimize/wp-optimize.php', // WP-Optimize
31 'swift-performance-lite/performance.php', // Swift Performance Lite
32 'nitropack/nitropack.php', // NitroPack
33 'nitropack/main.php', // NitroPack
34 'jetpack-boost/jetpack-boost.php', // Jetpack Boost
35 'tenweb-speed-optimizer/tenweb_speed_optimizer.php', // 10Web Booster
36 'speed-booster-pack/speed-booster-pack.php', // Speed booster pack
37 'wp-speed-of-light/wp-speed-of-light.php', // WP speed of light
38 'speedycache/speedycache.php', // Speedy cache
39 'powered-cache/powered-cache.php', // Powered cache
40 'clearfy/clearfy.php', // Clearfy
41 'rabbit-loader/rabbit-loader.php',
42 'psn-pagespeed-ninja/pagespeedninja.php',
43 'jch-optimize/jch-optimize.php',
44 'cache-enabler/cache-enabler.php',
45 'core-web-vitals-pagespeed-booster/core-web-vitals-pagespeed-booster.php',
46 'surge/surge.php',
47 'speedien/speedien.php',
48 'wpspeed/wpspeed.php',
49 'debloat/debloat.php',
50 'perfmatters/perfmatters.php',
51 'phastpress/phastpress.php',
52 'wp-meteor/wp-meteor.php',
53 ];
54
55 function __construct()
56 {
57
58 add_action('init', [$this, 'initialize']);
59
60 // Save settings
61 add_action('admin_init', [$this, 'save_settings']);
62
63 // Sitemap for cache warmup
64 // add_action('wp', 'bwp_get_sitemap');
65 add_action('wp_loaded', 'bwp_get_sitemap', 999);
66
67 // BerqWP display logs
68 add_action('init', 'bwp_display_logs');
69
70 require_once optifer_PATH . '/api/register_apis.php';
71
72 add_action('admin_menu', [$this, 'register_menu']);
73 // add_action('init', [$this, 'berq_post_types'], 20);
74 add_action('berqwp_notices', [$this, 'notices']);
75
76 add_filter('plugin_action_links_searchpro/berqwp.php', [$this, 'plugin_settings_links']);
77
78 // add_action('wp_ajax_berqwp_fetch_remote_html', [$this, 'fetch_remote_html']);
79
80 add_action('wp_ajax_berqwp_refresh_cache_stats', [$this, 'refresh_cache_stats']);
81
82 add_action('wp_ajax_berqwp_get_optimized_pages', [$this, 'berqwp_get_optimized_pages']);
83 add_action('wp_ajax_berqwp_recently_optimized_pages', [$this, 'ajax_recently_optimized_pages']);
84
85 add_action('admin_enqueue_scripts', [$this, 'admin_scripts']);
86
87 // add_filter( 'action_scheduler_queue_runner_concurrent_batches', [$this, 'ashp_increase_concurrent_batches'] );
88
89 // add_filter('action_scheduler_retention_period', function ($period) {
90 // return DAY_IN_SECONDS;
91 // });
92
93 // add_filter('action_scheduler_default_cleaner_statuses', function ($statuses) {
94 // $statuses[] = 'failed';
95 // return $statuses;
96 // });
97
98 // add_filter('action_scheduler_cleanup_batch_size', function ($batch_size) {
99 // return 100;
100 // });
101
102 // Refresh license key
103 add_action('admin_post_bwp_refresh_license', [$this, 'handle_refresh_license_action']);
104
105 add_action('admin_post_switch_optimization_method_local', [$this, 'switch_optimization_method']);
106 add_action('admin_post_switch_optimization_method_cloud', [$this, 'switch_optimization_method']);
107
108 add_action('in_admin_header', [$this, 'remove_admin_notices']);
109
110 // Increase nonce life
111 add_filter('nonce_life', [$this, 'increase_nonce_life']);
112
113 // Page compression test
114 add_action('wp_ajax_berqwp_enable_page_compression', [$this, 'enable_page_compression']);
115 add_action('template_redirect', [$this, 'page_compression_test']);
116
117 // Run daily maintenance tasks
118 // add_action('init', [$this, 'schedule_daily_maintenance']);
119 // add_action('berqwp_daily_maintenance_hook', [$this, 'daily_maintenance']);
120
121 // Revoke License
122 add_action('init', [$this, 'revoke_license']);
123
124 // Create dropin plugin file
125 add_action('init', 'berqwp_setup_dropin');
126
127 // Update settings via API
128 add_action('init', 'bwp_update_configs_webhook');
129
130 // Active-status check from optimization server
131 add_action('init', 'bwp_check_status_webhook');
132
133 // Sync addons from cloud
134 add_action('init', [$this, 'sync_addons']);
135
136 // Multisite support
137 if (function_exists('is_multisite') && is_multisite()) {
138 add_action('network_admin_menu', [$this, 'register_network_menu']);
139 add_action('network_admin_edit_berqwp_network_save', [$this, 'save_network_settings']);
140 add_action('wp_initialize_site', [$this, 'on_new_site_created'], 10, 1);
141 add_action('wp_delete_site', [$this, 'regenerate_blog_map']);
142 add_action('berqwp_activate_plugin', [$this, 'regenerate_blog_map']);
143 }
144 }
145
146 static function getInstance() {
147
148 if (self::$instance === null) {
149 $instance = new berqWP();
150 self::$instance = $instance;
151 return $instance;
152 }
153
154 return self::$instance;
155 }
156
157 function switch_optimization_method() {
158 // Check if the user has the necessary nonce and the action matches
159 if (isset($_GET['action']) && $_GET['action'] === 'switch_optimization_method_local' && wp_verify_nonce(sanitize_text_field(wp_unslash($_GET['_wpnonce'] ?? '')), 'switch_optimization_method_local_action')) {
160
161
162 $berqconfigs = berqConfigs::getInstance();
163 $berqconfigs->update_configs(['optimization_method' => 'local']);
164
165 $redirect_url = wp_get_referer();
166
167 // Redirect back to the referring page after clearing the cache
168 wp_safe_redirect($redirect_url);
169 exit;
170 }
171
172 if (isset($_GET['action']) && $_GET['action'] === 'switch_optimization_method_cloud' && wp_verify_nonce(sanitize_text_field(wp_unslash($_GET['_wpnonce'] ?? '')), 'switch_optimization_method_cloud_action')) {
173
174 $berqconfigs = berqConfigs::getInstance();
175 $configs = $berqconfigs->get_configs();
176
177 if (empty($configs['secret'])) {
178 $berqconfigs->update_configs(['optimization_method' => '']);
179 } else {
180 $berqconfigs->update_configs(['optimization_method' => 'cloud']);
181 }
182
183
184 $redirect_url = wp_get_referer();
185
186 // Redirect back to the referring page after clearing the cache
187 wp_safe_redirect($redirect_url);
188 exit;
189 }
190 }
191
192 function sync_addons()
193 {
194 $license_key = berqwp_get_license_key();
195 if (get_option('berqwp_sync_addons') && !empty($this->key_response->product_ref) && $this->key_response->product_ref == 'AppSumo Deal' && !empty($license_key)) {
196 berqwp_sync_addons($license_key, home_url());
197 delete_option('berqwp_sync_addons');
198 }
199 }
200
201 function revoke_license()
202 {
203 if (isset($_GET['berqwp_revoke_license']) && !empty($_POST['key_hash'])) {
204 $hash = sanitize_text_field($_POST['key_hash']);
205
206 if ($hash == md5(berqwp_get_license_key())) {
207 berqwp_delete_license_key();
208 echo json_encode(['success' => true]);
209 exit;
210 }
211 }
212 }
213
214 function daily_maintenance()
215 {
216
217 // Perform connection test
218 bwp_check_connection(true);
219
220 $log_file = optifer_cache . 'berqwp.log';
221 if (file_exists($log_file)) {
222 @unlink($log_file);
223 }
224
225 $log_dir = optifer_cache . 'logs/';
226
227 // Check if directory exists
228 if (is_dir($log_dir)) {
229 // Get all files in the directory
230 $files = glob($log_dir . '*');
231
232 // Check if there are more than 10 files
233 if (count($files) > 10) {
234 // Sort files by modified time, newest first
235 usort($files, function ($a, $b) {
236 return filemtime($b) - filemtime($a);
237 });
238
239 // Get files beyond the first 10
240 $files_to_delete = array_slice($files, 10);
241
242 // Delete the extra files
243 foreach ($files_to_delete as $file) {
244 if (is_file($file)) {
245 @unlink($file);
246 }
247 }
248 }
249 }
250 }
251
252 function schedule_daily_maintenance()
253 {
254 if (!as_next_scheduled_action('berqwp_daily_maintenance_hook')) {
255 as_schedule_recurring_action(time(), DAY_IN_SECONDS, 'berqwp_daily_maintenance_hook');
256 }
257 }
258
259 function page_compression_test()
260 {
261 if (isset($_GET['berqwp_compression_test'])) {
262 $test_file_path = optifer_cache . 'gzip-compression-test.gz';
263 $accept_encoding = $_SERVER['HTTP_ACCEPT_ENCODING'] ?? '';
264 $supports_gzip = strpos($accept_encoding, 'gzip') !== false;
265
266 // if ($supports_gzip) {
267 header('Content-Type: text/html; charset=utf-8');
268 // header_remove('Content-Encoding');
269 // header('Content-Encoding: gzip');
270 // readgzfile($test_file_path);
271
272 header('Vary: Accept-Encoding');
273 header('Content-Encoding: gzip', true);
274 header('Content-Length: ' . filesize($test_file_path), true);
275 readfile($test_file_path);
276 // }
277 // header('Content-Type: text/html');
278 // header('Content-Encoding: gzip');
279 // readfile($test_file_path);
280 exit;
281 }
282 }
283
284 function enable_page_compression()
285 {
286
287 check_ajax_referer('wp_rest', 'nonce');
288
289 $url = home_url('/?berqwp_compression_test=' . time());
290 $berqconfigs = berqConfigs::getInstance();
291 $testfile = optifer_cache . 'gzip-compression-test.gz';
292 $html = gzencode('Hello World!');
293 @file_put_contents($testfile, $html);
294
295 sleep(5);
296
297 $response = wp_remote_get($url);
298
299 if (!empty($response) && !is_wp_error($response)) {
300 $html = wp_remote_retrieve_body($response);
301
302 if ($html == 'Hello World!') {
303 $berqconfigs->update_configs(['page_compression' => true]);
304 wp_send_json_success('Compression test passed.');
305 }
306 }
307
308 $berqconfigs->update_configs(['page_compression' => false]);
309 wp_send_json_error('Compression test failed.');
310
311 die(); // Always exit in AJAX functions
312 }
313
314 function increase_nonce_life($default_life)
315 {
316
317 // if (!is_user_logged_in() && bwp_pass_account_requirement()) {
318 if (!is_user_logged_in()) {
319 return 30 * DAY_IN_SECONDS;
320 }
321
322 return $default_life;
323 }
324
325 function remove_admin_notices()
326 {
327
328 if (current_user_can('manage_options')) {
329 $screen = get_current_screen();
330 if ($screen->id === 'toplevel_page_berqwp') {
331 remove_all_actions('user_admin_notices');
332 remove_all_actions('admin_notices');
333 remove_all_actions('all_admin_notices');
334 } else {
335 add_action('admin_notices', function () {
336 do_action('berqwp_notices');
337 }, 10);
338 }
339 }
340 }
341
342 function admin_scripts()
343 {
344
345 // settings page specific assets
346 if ( isset($_GET['page']) && $_GET['page'] == 'berqwp' ) {
347
348 wp_enqueue_style(
349 'bwp-google-fonts',
350 "https://fonts.googleapis.com/css2?family=Lato:wght@400;700&display=swap",
351 [],
352 BERQWP_VERSION
353 );
354
355 wp_enqueue_style(
356 'bwp-jquery-datatable',
357 optifer_URL . '/admin/css/dataTables.dataTables.min.css',
358 [],
359 BERQWP_VERSION
360 );
361
362 wp_enqueue_style(
363 'bwp-settings-style',
364 optifer_URL . '/admin/css/style.css',
365 [],
366 BERQWP_VERSION
367 );
368
369 }
370
371 wp_enqueue_style(
372 'bwp-global-styles', // Handle for the style
373 optifer_URL . 'admin/css/global.css', // URL to the CSS file
374 [], // Dependencies (array of handles)
375 BERQWP_VERSION // Version number
376 );
377 }
378
379 function handle_refresh_license_action()
380 {
381 // Check if the user has the necessary nonce and the action matches
382 if (isset($_GET['action']) && $_GET['action'] === 'bwp_refresh_license' && wp_verify_nonce(sanitize_text_field(wp_unslash($_GET['_wpnonce'] ?? '')), 'bwp_refresh_license_action')) {
383
384 // $transient_key = 'berq_lic_response_cache';
385 // $expire_transient_key = 'berq_lic_cache_expire';
386
387 // berqwp_delete_network_option($transient_key);
388 // berqwp_delete_network_option($expire_transient_key);
389
390 berqwp_delete_network_option('berqwp_license_cache');
391
392 // clear cache from cloud
393 bwp_request_purge_license_key_cache();
394
395 global $berqNotifications;
396 $berqNotifications->success('License key successfully refreshed.');
397
398 $redirect_url = add_query_arg('berq_refresh_license', '', wp_get_referer());
399
400 // Redirect back to the referring page after clearing the cache
401 wp_safe_redirect($redirect_url);
402 exit;
403 }
404 }
405
406 function berqwp_get_optimized_pages()
407 {
408 check_ajax_referer('berqwp_get_optimized_pages_nonce', 'nonce');
409 if (!current_user_can('manage_options')) {
410 wp_send_json_error('Unauthorized', 403);
411 return;
412 }
413
414 if (!isset($_POST['start']) || !isset($_POST['length'])) {
415 wp_send_json_error('Invalid parameters');
416 return;
417 }
418
419 $start = intval($_POST['start']); // Offset for the query
420 $length = intval($_POST['length']); // Number of records to fetch per request
421 $search = isset($_POST['search']) ? sanitize_text_field($_POST['search']) : ''; // Search term if present
422
423 $post_types = get_option('berqwp_optimize_post_types');
424 $optimized_pages = [];
425
426 // Build the query arguments
427 $args = array(
428 'post_type' => $post_types,
429 'posts_per_page' => $length, // Limit the number of posts per request
430 'offset' => $start, // Set the offset for pagination
431 'post_status' => array('publish'), // Only published pages
432 );
433
434 // Add search filtering, if applicable
435 if (!empty($search)) {
436 $args['s'] = $search; // Add the search parameter to the query
437 }
438
439 if ($start === 0 && empty($search)) {
440 $url = bwp_admin_home_url('/');
441
442 if (strpos($url, bwp_admin_home_url()) === false) {
443 $url = str_replace(home_url(), bwp_admin_home_url(), $url);
444 }
445
446 $slug = bwp_url_into_path($url);
447
448 $cache_directory = bwp_get_cache_dir();
449 $cache_key = md5($url);
450 // $cache_key = md5($slug);
451 $cache_file = $cache_directory . $cache_key . '.gz';
452
453 if (is_file($cache_file)) {
454 $status = '<span class="bwp-cache-tag completed">Completed</span>';
455
456 // if (bwp_is_partial_cache($url) === true) {
457 // $status = '<span class="bwp-cache-tag part-completed">Partial cache</span>';
458 // }
459 } else {
460 $status = '<span class="bwp-cache-tag">Pending</span>';
461 }
462
463 $parsed_url = parse_url($url);
464 $decoded_path = isset($parsed_url['path']) ? urldecode($parsed_url['path']) : '';
465 $decoded_query = isset($parsed_url['query']) ? urldecode($parsed_url['query']) : '';
466
467 $decoded_url = $parsed_url['scheme'] . '://' . $parsed_url['host'];
468 if (isset($parsed_url['port'])) {
469 $decoded_url .= ':' . $parsed_url['port'];
470 }
471 $decoded_url .= $decoded_path;
472 if ($decoded_query) {
473 $decoded_url .= '?' . $decoded_query;
474 }
475 if (isset($parsed_url['fragment'])) {
476 $decoded_url .= '#' . $parsed_url['fragment'];
477 }
478
479 $page_arr = [
480 'url' => $decoded_url,
481 'status' => $status,
482 'last_modified' => file_exists($cache_file) ? date('Y-m-d H:i:s', filemtime($cache_file)) : ''
483 ];
484
485 array_push($optimized_pages, $page_arr);
486 }
487
488 $query = new WP_Query($args);
489 $total_posts = $query->found_posts; // Get the total number of records
490
491 $valid_posts_query = new WP_Query([
492 'post_type' => $post_types,
493 'posts_per_page' => -1,
494 'fields' => 'ids',
495 'post_status' => ['publish'],
496 ]);
497 $valid_posts = array_filter($valid_posts_query->posts, function ($post_id) {
498 $url = get_permalink($post_id);
499 return bwp_can_optimize_page_url($url);
500 });
501 $total_posts = count($valid_posts);
502
503 if ($query->have_posts()) {
504 while ($query->have_posts()) {
505 $query->the_post();
506
507 $url = get_permalink();
508
509 if (strpos($url, bwp_admin_home_url()) === false) {
510 $url = str_replace(home_url(), bwp_admin_home_url(), $url);
511 }
512
513 if (bwp_admin_home_url('/') == $url) {
514 continue;
515 }
516
517 $slug = bwp_url_into_path($url);
518
519 if (!bwp_can_optimize_page_url($url)) {
520 continue;
521 }
522
523 $cache_directory = bwp_get_cache_dir();
524 $cache_key = md5($url);
525 // $cache_key = md5($slug);
526 $cache_file = $cache_directory . $cache_key . '.gz';
527
528 if (is_file($cache_file)) {
529 $status = '<span class="bwp-cache-tag completed">Completed</span>';
530
531 // if (bwp_is_partial_cache($url) === true) {
532 // $status = '<span class="bwp-cache-tag part-completed">Partial cache</span>';
533 // }
534 } else {
535 $status = '<span class="bwp-cache-tag">Pending</span>';
536 }
537
538 $parsed_url = parse_url($url);
539 $decoded_path = isset($parsed_url['path']) ? urldecode($parsed_url['path']) : '';
540 $decoded_query = isset($parsed_url['query']) ? urldecode($parsed_url['query']) : '';
541
542 $decoded_url = $parsed_url['scheme'] . '://' . $parsed_url['host'];
543 if (isset($parsed_url['port'])) {
544 $decoded_url .= ':' . $parsed_url['port'];
545 }
546 $decoded_url .= $decoded_path;
547 if ($decoded_query) {
548 $decoded_url .= '?' . $decoded_query;
549 }
550 if (isset($parsed_url['fragment'])) {
551 $decoded_url .= '#' . $parsed_url['fragment'];
552 }
553
554 $page_arr = [
555 'url' => $decoded_url,
556 'status' => $status,
557 'last_modified' => file_exists($cache_file) ? date('Y-m-d H:i:s', filemtime($cache_file)) : ''
558 ];
559
560 array_push($optimized_pages, $page_arr);
561 }
562 }
563
564 wp_reset_postdata();
565
566 // Send the response with the optimized pages and total entries
567 wp_send_json_success([
568 'optimized_pages' => $optimized_pages,
569 'total_entries' => $total_posts, // Total number of posts (unfiltered)
570 'records_filtered' => $total_posts // Adjust if filtered by search
571 ]);
572 }
573
574
575
576 function ajax_recently_optimized_pages()
577 {
578 check_ajax_referer('wp_rest', 'nonce');
579
580 $search = isset($_POST['search']) ? sanitize_text_field($_POST['search']) : '';
581 $start = max(0, intval($_POST['start'] ?? 0));
582 $length = max(1, intval($_POST['length'] ?? 10));
583
584 $log = json_decode(get_option('berqwp_recently_optimized', '[]'), true);
585 if (!is_array($log)) $log = [];
586
587 if (!empty($search)) {
588 $s = strtolower(rtrim($search, '/'));
589 $home = strtolower(rtrim(home_url(), '/'));
590 // Strip the site root from the search term so we compare paths only.
591 // e.g. "http://plugin-berqwp.local/" → "", "/about" → "/about"
592 $s_path = ltrim(str_starts_with($s, $home) ? substr($s, strlen($home)) : $s, '/');
593
594 $log = array_values(array_filter($log, function ($e) use ($s, $home, $s_path) {
595 $url = strtolower(rtrim($e['url'], '/'));
596 $url_path = ltrim(str_starts_with($url, $home) ? substr($url, strlen($home)) : $url, '/');
597 // Exact path match (covers homepage: both empty)
598 if ($url_path === $s_path) return true;
599 // Path starts with the search path (only if search is non-empty to avoid matching everything)
600 if ($s_path !== '' && str_starts_with($url_path, $s_path)) return true;
601 // Full URL substring fallback
602 return $s_path === '' ? $url === $home : stripos($url_path, $s_path) !== false;
603 }));
604
605 // Sort: exact path match first, prefix match second, substring last
606 usort($log, function ($a, $b) use ($home, $s_path) {
607 $pa = ltrim(str_starts_with(strtolower(rtrim($a['url'], '/')), $home)
608 ? substr(strtolower(rtrim($a['url'], '/')), strlen($home)) : strtolower(rtrim($a['url'], '/')), '/');
609 $pb = ltrim(str_starts_with(strtolower(rtrim($b['url'], '/')), $home)
610 ? substr(strtolower(rtrim($b['url'], '/')), strlen($home)) : strtolower(rtrim($b['url'], '/')), '/');
611 $ra = $pa === $s_path ? 0 : (str_starts_with($pa, $s_path) ? 1 : 2);
612 $rb = $pb === $s_path ? 0 : (str_starts_with($pb, $s_path) ? 1 : 2);
613 return $ra <=> $rb;
614 });
615 }
616
617 $total = count($log);
618 $page_log = array_slice($log, $start, $length);
619
620 wp_send_json_success([
621 'data' => $page_log,
622 'total' => $total,
623 'records_filtered' => $total,
624 ]);
625 }
626
627 function ashp_increase_concurrent_batches($concurrent_batches)
628 {
629 return $concurrent_batches * 2;
630 }
631
632 function refresh_cache_stats()
633 {
634
635 check_ajax_referer('wp_rest', 'nonce');
636
637 $post_types = get_option('berqwp_optimize_post_types');
638 $args = array(
639 'post_type' => $post_types,
640 'posts_per_page' => -1,
641 'fields' => 'ids',
642 'post_status' => 'publish'
643 );
644 $query = new WP_Query($args);
645 $pages_to_exclude = get_option('berq_exclude_urls', []);
646 $total_pages = (int) $query->found_posts - count($pages_to_exclude);
647 $optimized_pages = bwp_cached_pages_count();
648
649 if (get_option('show_on_front') !== 'page') {
650 $total_pages++;
651 }
652
653 if (empty($total_pages) || $total_pages <= 0) {
654 $cached_percentage = 0;
655 } else {
656 $cached_percentage = round(($optimized_pages / $total_pages) * 100, 2);
657 }
658 if ($cached_percentage > 100) {
659 $cached_percentage = 100;
660 }
661
662 if ($cached_percentage < 0) {
663 $cached_percentage = 0;
664 }
665
666 $server_queue = get_option('berqwp_server_queue', []);
667
668 wp_send_json_success(['cache_count' => $optimized_pages, 'cache_percentage' => $cached_percentage, 'total' => $total_pages, 'server_queue' => count($server_queue)]);
669
670 die(); // Always exit in AJAX functions
671 }
672
673 function fetch_remote_html()
674 {
675
676 check_ajax_referer('wp_rest', 'nonce');
677
678 $url = get_option('berqwp_enable_sandbox') ? bwp_admin_home_url('/?berqwp') : bwp_admin_home_url('/');
679
680 $response = wp_remote_get($url);
681 // $response = bwp_wp_remote_get($url);
682
683 if (is_array($response) && !is_wp_error($response)) {
684 $html = wp_remote_retrieve_body($response);
685 echo $html;
686 } else {
687 echo 'Error fetching HTML.';
688 }
689
690 die(); // Always exit in AJAX functions
691 }
692
693 function activate_license_from_multi_site()
694 {
695 if (berq_is_localhost()) {
696 return;
697 }
698
699 $berqwp_license_key_from_parent = constant('BERQWP_LICENSE_KEY');
700
701 if (!empty($berqwp_license_key_from_parent) && empty(berqwp_get_license_key())) {
702 $key = sanitize_text_field($berqwp_license_key_from_parent);
703 $key_response = $this->verify_license_key($key, 'slm_activate');
704
705
706 if (!empty($key_response) && $key_response->result == 'success') {
707 berqwp_update_license_key($key);
708
709 if (is_admin()) {
710 ?>
711 <div class="notice notice-success is-dismissible">
712 <?php esc_html_e('The BerqWP license has been activated for your parent multisite.', 'searchpro'); ?>
713 </div>
714 <?php
715 }
716 } elseif ($key_response->result == 'error') {
717 $error = $key_response->message;
718
719 if (is_admin()) {
720 ?>
721 <div class="notice notice-error is-dismissible">
722 <?php echo esc_html($error); ?>
723 </div>
724 <?php
725
726 }
727 }
728 }
729 }
730
731 function handle_upgrade() {
732
733 $berqconfigs = berqConfigs::getInstance();
734 $configs = $berqconfigs->get_configs();
735 $site_id = $configs['site_id'];
736 $license_key = berqwp_get_license_key();
737 global $berq_log;
738
739 if (!empty($configs['optimization_method']) && $configs['optimization_method'] == 'cloud' && empty($license_key)) {
740
741 $berqconfigs->update_configs([
742 'secret' => '',
743 'optimization_method' => 'local'
744 ]);
745 return;
746 }
747
748 $license_check_only = false;
749
750 if ( !empty($configs['secret']) && !empty($configs['optimization_method']) && $configs['optimization_method'] == 'cloud' && !empty($license_key) && empty(berqwp_get_network_option('berqwp_license_cache')) ) {
751 $license_check_only = true;
752 }
753
754 // user first time upgrades to v4
755 $first_upgrade = empty($configs['optimization_method']) && !empty($license_key);
756 $missing_secret = empty($configs['secret']) && !empty($configs['optimization_method']) && $configs['optimization_method'] == 'cloud' && !empty($license_key);
757
758 if ($first_upgrade || $missing_secret || !empty($license_check_only)) {
759
760 // $berq_log->info("Authenticating secret");
761
762 // $lic_response = wp_remote_post(BerqWPCloud::$endpoint."authenticate", [
763 // 'timeout' => 30,
764 // 'body' => $request_body
765 // ]);
766
767 // if (is_wp_error($lic_response)) {
768 // $berq_log->info("Couldn't reach BerqWP server.");
769 // return;
770 // }
771
772 // $lic_body = wp_remote_retrieve_body($lic_response);
773 // $lic_json = json_decode($lic_body);
774
775 // if (empty($lic_json)) {
776 // $berq_log->info("Authenticate secret invalid response");
777 // return;
778 // }
779
780 $lic_json = $this->authenticate_license($license_key, $license_check_only);
781
782 if (!empty($lic_json->lic) && $lic_json->lic->result == 'success' && ($lic_json->lic->message == 'License key activated' || $lic_json->lic->status == 'active')) {
783
784 if (!empty($lic_json->secret)) {
785 $berqconfigs->update_configs([
786 'secret' => $lic_json->secret,
787 'optimization_method' => 'cloud'
788 ]);
789 }
790
791 berqwp_update_network_option('berqwp_license_cache', $lic_json->lic);
792
793 $berq_log->info("Authentication success.");
794
795 // Fresh installation
796 if (get_option('berqwp_can_use_fluid_images') === false) {
797
798 if ($lic_json->lic->product_ref !== 'AppSumo Deal') {
799 update_option('berqwp_can_use_fluid_images', 1);
800 } else {
801 update_option('berqwp_can_use_fluid_images', 0);
802 update_option('berqwp_sync_addons', true);
803 }
804 }
805
806 } else {
807
808 $berq_log->info("Authentication failed.");
809 berqwp_remove_license_key();
810
811 $berqconfigs->update_configs([
812 'secret' => '',
813 'optimization_method' => 'local'
814 ]);
815
816 berqwp_delete_network_option('berqwp_license_cache');
817 }
818
819 }
820
821 if (!empty(berqwp_get_network_option('berqwp_license_cache'))) {
822 $this->is_key_verified = true;
823 $this->key_response = berqwp_get_network_option('berqwp_license_cache');
824 }
825
826 }
827
828 function initialize()
829 {
830
831 if (defined('DOING_CRON') && DOING_CRON) {
832 return;
833 }
834
835 if (defined('DOING_AJAX') && DOING_AJAX) {
836 return;
837 }
838
839 // Set default settings
840 require_once optifer_PATH . '/inc/initialize.php';
841
842 $this->handle_upgrade();
843
844 if (berqwp_can_use_cloud()) {
845 $license_key = berqwp_get_license_key();
846 $lic_json = $this->authenticate_license($license_key, true);
847
848 if (!empty($lic_json->lic) && $lic_json->lic->result == 'success' && ($lic_json->lic->message == 'License key activated' || $lic_json->lic->status == 'active')) {
849 berqwp_update_network_option('berqwp_license_cache', $lic_json->lic);
850 }
851 }
852
853 // Activate the license from parent site
854 // if (defined('BERQWP_LICENSE_KEY')) {
855 // $this->activate_license_from_multi_site();
856 // }
857
858 if (is_admin()) {
859 $this->berq_post_types();
860 }
861
862 // if (is_admin() && isset($_GET['bwp_get_ip'])) {
863 // $ip = file_get_contents('https://api.ipify.org');
864 // echo 'Server Public IP Address: ' . $ip;
865 // exit;
866 // }
867
868 // if (is_admin() && !empty(berqwp_get_license_key())) {
869 // $license_key = berqwp_get_license_key();
870
871 // global $berq_log;
872 // // $berq_log->info("License key check from initialize function.");
873
874 // $key_response = $this->verify_license_key($license_key);
875
876 // if (!empty($key_response) && $key_response->result == 'success' && $key_response->status == 'active') {
877 // $this->is_key_verified = true;
878 // $this->key_response = $key_response;
879
880 // // Fresh installation
881 // if (get_option('berqwp_can_use_fluid_images') === false) {
882
883 // if ($key_response->product_ref !== 'AppSumo Deal') {
884 // update_option('berqwp_can_use_fluid_images', 1);
885 // } else {
886 // update_option('berqwp_can_use_fluid_images', 0);
887 // update_option('berqwp_sync_addons', true);
888 // }
889 // }
890
891 // } else {
892 // $this->is_key_verified = false;
893
894 // if (!empty($key_response) && $key_response->result == 'error') {
895 // berqwp_delete_license_key();
896 // }
897 // }
898 // }
899
900 // redirect to berqwp admin page
901 if (get_transient('berqwp_redirect')) {
902 delete_transient('berqwp_redirect');
903 // Set the URL to redirect to after activation
904 $redirect_url = admin_url('admin.php?page=berqwp');
905
906 // Redirect after activation
907 wp_redirect($redirect_url);
908
909 // Make sure to exit after the redirect
910 exit;
911 }
912
913 // Deactivate conflicting plugins
914 if (is_admin() && isset($_POST['berqwp_plugins_deactivate']) && wp_verify_nonce($_POST['berqwp_plugins_deactivate'], 'berqwp_plugins_deactivate')) {
915 foreach ($this->conflicting_plugins as $plugin) {
916 // Deactivate each conflicting plugin
917 if (is_plugin_active($plugin)) {
918 deactivate_plugins($plugin);
919 }
920 }
921 header('location: ' . esc_url(admin_url('admin.php') . add_query_arg(['page' => 'berqwp', 'tab_id' => sanitize_text_field(wp_unslash($_GET['tab_id'] ?? ''))])));
922 exit;
923 }
924 }
925
926 function save_settings()
927 {
928 require_once optifer_PATH . '/admin/save-settings.php';
929 }
930
931 function notices()
932 {
933
934 $plugin_name = defined('BERQWP_PLUGIN_NAME') ? BERQWP_PLUGIN_NAME : 'BerqWP';
935
936 if (isset($_GET['berqwp_page_compression_enabled'])) {
937 bwp_notice('success', 'Page Compression Enabled', "<p>Page compression has been successfully enabled on your website.</p>");
938 }
939
940 if (isset($_GET['dismiss_feedback'])) {
941 set_transient('bwp_hide_feedback_notice', true, DAY_IN_SECONDS * 14);
942 }
943
944 if (isset($_GET['bwp_quit_feedback'])) {
945 update_option('bwp_quit_feedback', true);
946 }
947
948
949 if (!empty($this->key_response) && $this->key_response->result == 'success' && $this->key_response->status == 'expired') {
950 ?>
951 <div class="notice notice-error">
952 <p><strong>Error:</strong> <?php echo $plugin_name; ?> license key has expired. Please renew your subscription.</p>
953 </div>
954 <?php
955 }
956
957 // Check connection
958 // $check_rest = bwp_check_connection(false, !empty($_GET['bwp_connection_test']) === true);
959 // if ($check_rest['status'] == 'error') {
960 // bwp_notice('error', 'Website Unreachable: Connection Blocked', "<p>$plugin_name server is unable to access this website, please whitelist our server IP address. <a href='https://berqwp.com/help-center/get-started-with-berqwp/' target='_blank'>Find our server IP address here.</a></p>", [
961 // [
962 // 'href' => esc_attr(add_query_arg(['bwp_connection_test' => true], get_admin_url())),
963 // 'text' => 'Check again',
964 // 'classes' => '',
965 // ]
966 // ]);
967 // }
968
969 // Check Permissions
970 $cache_directory = WP_CONTENT_DIR . '/cache/berqwp/';
971 $wp_config_file = defined('BERQWP_WP_CONFIG') ? BERQWP_WP_CONFIG : ABSPATH . 'wp-config.php';
972
973 if (!is_writable($cache_directory)) {
974 bwp_notice('error', 'Cache directory is not writable', "<p>The $plugin_name cache directory at /wp-content/cache/berqwp/ is not writable. Please update the directory permissions to allow the plugin to store cached files.</p>", []);
975 }
976
977 if (!defined('WP_CACHE') && !is_writable($wp_config_file)) {
978 bwp_notice('warning', 'wp-config.php is not writable', "<p>The wp-config.php file is not writable. $plugin_name needs to write configuration settings to this file. Please adjust the file permissions or manually add the WP_CACHE constant and set it to true.</p>", []);
979 }
980
981 if (defined('BERQWP_ADVANCED_CACHE_PATH')) {
982 $adv_cache_path = BERQWP_ADVANCED_CACHE_PATH;
983 } else {
984 $adv_cache_path = WP_CONTENT_DIR . '/advanced-cache.php';
985 }
986
987 // if (file_exists($adv_cache_path) && !is_writable($adv_cache_path)) {
988 // bwp_notice('warning', 'advanced-cache.php is not writable', "<p>$plugin_name can't write to wp-content/advanced-cache.php — please check file permissions or re-save settings to regenerate it.</p>", []);
989 // }
990
991 if (!get_transient('bwp_hide_feedback_notice') && !get_option('bwp_quit_feedback') && bwp_show_account()) {
992 bwp_notice('info bwp_feedback', 'Loving BerqWP\'s performance?', '<p>Show some love and help us grow 👉 - <a href="https://wordpress.org/support/plugin/searchpro/reviews/#new-post" target="_blank">Rate BerqWP Plugin</a>. Your insights shape our journey.</p>', [
993 [
994 'href' => 'https://wordpress.org/support/plugin/searchpro/reviews/#new-post',
995 'text' => '❤️ You deserve it',
996 'classes' => '',
997 'target' => '_blank',
998 ],
999 [
1000 'href' => get_admin_url() . 'admin.php?page=berqwp&bwp_quit_feedback',
1001 'text' => '👍 Already did',
1002 'classes' => '',
1003 'target' => '',
1004 ],
1005 [
1006 'href' => get_admin_url() . 'admin.php?page=berqwp&dismiss_feedback',
1007 'text' => 'Not Now',
1008 'classes' => '',
1009 'target' => '',
1010 ]
1011 ]);
1012
1013 // $notice = '<div class="bwp-notice bwp_feedback">';
1014 // $notice .= '<p>';
1015 // $notice .= __('🎉 <b>Loving BerqWP\'s performance? 🚀</b> Show some love and help us grow 👉 - <a href="https://wordpress.org/support/plugin/searchpro/reviews/#new-post" target="_blank">Rate BerqWP Plugin</a>. Your insights shape our journey.', 'searchpro');
1016 // $notice .= '<a href="'.get_admin_url().'admin.php?page=berqwp&dismiss_feedback" style="display: table;margin-left: 50px;color: #969595;display: table;">Dismiss</a>';
1017 // $notice .= '</p>';
1018 // $notice .= '</div>';
1019 // echo wp_kses_post($notice);
1020 }
1021
1022 // purge single page notice
1023 if (get_transient('berq_purge_page_notice')) {
1024 $flushed_page = esc_url(get_transient('berq_purge_page_notice'));
1025 delete_transient('berq_purge_page_notice');
1026 bwp_notice('success', '', "<p>Page cache has been flushed for $flushed_page.</p>", []);
1027 }
1028
1029 // purge all cache notice
1030 if (get_transient('berq_cache_cleared_notice')) {
1031 delete_transient('berq_cache_cleared_notice');
1032 bwp_notice('success', '', '<p>The cache has been cleared. Our automatic cache warm-up system will generate the cache. Alternatively, you can
1033 visit any page to create its cache immediately.</p>', []);
1034 }
1035
1036 // purge cdn cache notice
1037 if (get_transient('berq_purge_cdn_notice')) {
1038 delete_transient('berq_purge_cdn_notice');
1039 bwp_notice('success', '', '<p>The CDN and page cache have been flushed.</p>', []);
1040 }
1041
1042 // purge critical css cache notice
1043 if (get_transient('berq_purge_criticalcss_notice')) {
1044 delete_transient('berq_purge_criticalcss_notice');
1045 bwp_notice('success', '', '<p>Critical CSS cache has been flushed from the cloud.</p>', []);
1046 }
1047
1048 // cache warmup notice
1049 if (get_transient('berq_cache_warmup_notice')) {
1050 delete_transient('berq_cache_warmup_notice');
1051 bwp_notice('success', 'Cache Warmup Queued', '<p>The cache warmup has been added to the queue. Your website pages will be optimized in the background and ready soon.</p>', []);
1052 }
1053
1054 // force page cache notice
1055 if (get_transient('berq_force_cache_notice')) {
1056 $forced_page = esc_url(get_transient('berq_force_cache_notice'));
1057 delete_transient('berq_force_cache_notice');
1058 bwp_notice('success', '', "<p>The cache for page ($forced_page) has been queued with high priority and will be generated soon.</p>", []);
1059 }
1060
1061 if (get_option('bwp_require_flush_cache', false)) {
1062 bwp_notice('warning', 'Cache Flush Required', '<p>To apply the changes, please flush the cache.</p>', [
1063 [
1064 'href' => esc_attr(wp_nonce_url(admin_url('admin-post.php?action=clear_cache'), 'clear_cache_action')),
1065 'text' => 'Flush cache',
1066 'classes' => '',
1067 ]
1068 ]);
1069 }
1070
1071 if (berq_is_localhost() && berqwp_can_use_cloud()) {
1072 bwp_notice('warning', 'Localhost environment detected:', "<p>$plugin_name requires a live, publicly accessible website to function.</p>", []);
1073 }
1074
1075 $plugins_to_deactivate = '';
1076
1077 foreach ($this->conflicting_plugins as $plugin) {
1078 if (is_plugin_active($plugin)) {
1079 $plugins_to_deactivate .= '<li><b>' . basename(dirname($plugin)) . '</b></li>';
1080 }
1081 }
1082
1083 if (!empty($plugins_to_deactivate)) {
1084 echo "<style>.berqwp-plugin-conflict ul {
1085 list-style: disc;
1086 margin-left: 20px;
1087 }.berqwp-plugin-conflict form {
1088 padding: 10px;
1089 }
1090 .berqwp-plugin-conflict {
1091 display: grid;
1092 grid-template-columns: auto min-content;
1093 }</style>";
1094 echo '<div class="bwp-notice notice notice-error berqwp-plugin-conflict">';
1095 echo wp_kses_post(__('<p><strong>BerqWP Plugin Conflict:</strong> The following plugins have a same nature as BerqWP plugin. Having multiple plugins of the same type can cause unexpected results.</p>', 'searchpro'));
1096 ?>
1097 <form action="<?php echo esc_url(admin_url('admin.php') . add_query_arg(['page' => 'berqwp', 'tab_id' => sanitize_text_field(wp_unslash($_GET['tab_id'] ?? ''))])); ?>" method="post">
1098
1099 <?php
1100 $my_nonce = wp_create_nonce('berqwp_plugins_deactivate');
1101 echo '<input type="hidden" name="berqwp_plugins_deactivate" value="' . esc_attr($my_nonce) . '" />';
1102 ?>
1103
1104 <input type="submit" class="button-secondary alignright" value="Deactivate Conflicting Plugins">
1105 </form>
1106 <?php
1107 echo wp_kses_post("<ul>$plugins_to_deactivate</ul>");
1108 echo '</div>';
1109 }
1110 }
1111
1112 function berq_post_types()
1113 {
1114 // Get post type names
1115 $post_type_names = get_post_types(['public' => true, 'exclude_from_search' => false], 'names');
1116 unset($post_type_names['attachment']);
1117
1118 // var_dump($post_type_names);
1119
1120 // Modify which post types to optimize
1121 $post_type_names = apply_filters('berqwp_post_types', $post_type_names);
1122
1123 // Save the names in a WordPress option
1124 update_option('berqwp_post_type_names', $post_type_names);
1125 }
1126
1127 function plugin_settings_links($links)
1128 {
1129 $mylinks = array(
1130 '<a target="_blank" href="https://berqwp.com/help-center/">' . __('Help Center', 'searchpro') . '</a>',
1131 '<a href="' . admin_url('admin.php?page=berqwp') . '">' . __('Settings', 'searchpro') . '</a>',
1132 );
1133
1134 return array_merge($links, $mylinks);
1135 }
1136
1137 function authenticate_license($license_key, $check_only = false) {
1138
1139 $berqconfigs = berqConfigs::getInstance();
1140 $berqwp_configs = $berqconfigs->get_configs();
1141 $site_id = $berqwp_configs['site_id'];
1142
1143 if (empty($site_id)) {
1144 $blog_id = get_current_blog_id();
1145 $network_id = function_exists('get_current_network_id') ? get_current_network_id() : 1;
1146 $siteurl = get_option('siteurl');
1147 $site_id = md5("berqwp|$network_id|$blog_id|$siteurl");
1148
1149 $berqconfigs->update_configs(['site_id' => $site_id]);
1150 }
1151
1152 global $berq_log;
1153 $transient_key = 'berqwp_lic_response_cache'; // Set a unique key for the transient
1154 $expire_transient_key = 'berqwp_lic_cache_expire'; // Set a unique key for the transient
1155
1156 if (!$check_only) {
1157 berqwp_delete_network_option($transient_key);
1158 }
1159
1160 // Check if the response is already cached
1161 $lic_json = berqwp_get_network_option($transient_key);
1162 $cache_expire_time = (int) berqwp_get_network_option($expire_transient_key);
1163
1164 if (false === $lic_json || $cache_expire_time < time()) {
1165
1166 $berq_log->info("Authenticating license key");
1167
1168 $body = [
1169 'license_key' => $license_key,
1170 'site_id' => $site_id,
1171 'site_url' => home_url(),
1172 ];
1173
1174 if ($check_only) {
1175 $body['check'] = true;
1176 }
1177
1178 $lic_response = wp_remote_post(BerqWPCloud::$endpoint."authenticate", [
1179 'timeout' => 30,
1180 'body' => $body
1181 ]);
1182
1183 if (is_wp_error($lic_response)) {
1184 $berq_log->info("Couldn't reach BerqWP server.");
1185 return;
1186 }
1187
1188 $lic_body = wp_remote_retrieve_body($lic_response);
1189 $lic_json = json_decode($lic_body);
1190
1191 if (!empty($lic_json)) {
1192 berqwp_update_network_option($transient_key, $lic_json);
1193 berqwp_update_network_option($expire_transient_key, time() + DAY_IN_SECONDS);
1194 }
1195
1196 }
1197
1198
1199 return $lic_json;
1200
1201 }
1202
1203 function verify_license_key($license_key, $action = 'slm_check')
1204 {
1205 if ($action !== 'slm_deactivate') {
1206 return;
1207 }
1208
1209 // Action
1210 // slm_activate
1211 // slm_deactivate
1212 // slm_check
1213
1214 if (empty($license_key)) {
1215 return;
1216 }
1217
1218 if (defined('BERQWP_DOING_LICENSE_CHECK')) {
1219 // sleep(1);
1220 return;
1221 }
1222
1223 /**
1224 * Replaced transients with options
1225 */
1226
1227 global $berq_log;
1228 $transient_key = 'berq_lic_response_cache'; // Set a unique key for the transient
1229 $expire_transient_key = 'berq_lic_cache_expire'; // Set a unique key for the transient
1230
1231 if ($action !== 'slm_check') {
1232 // delete_transient( $transient_key );
1233 berqwp_delete_network_option($transient_key);
1234 }
1235
1236 // Check if the response is already cached
1237 // $cached_response = get_transient($transient_key);
1238 $cached_response = berqwp_get_network_option($transient_key);
1239 $cache_expire_time = (int) berqwp_get_network_option($expire_transient_key);
1240
1241
1242 if (false === $cached_response || $cache_expire_time < time()) {
1243 // If not cached, perform the API request
1244
1245 $rateLimiter = new RateLimiter(5, 60, optifer_cache . 'ratelimit/');
1246 $clientIdentifier = gethostname();
1247 if (function_exists('is_multisite') && is_multisite()) {
1248 $clientIdentifier .= '-site-' . get_current_blog_id();
1249 }
1250
1251 if ($rateLimiter->isRateLimited($clientIdentifier)) {
1252 return false;
1253 }
1254
1255 define('BERQWP_DOING_LICENSE_CHECK', true);
1256
1257 $berq_log->info('Checking the license key.');
1258
1259 $parsed_url = parse_url(home_url());
1260 $domain = $parsed_url['host'];
1261
1262 $api_params = array(
1263 'registered_domain' => $domain,
1264 'slm_action' => $action,
1265 'secret_key' => BERQ_SECRET,
1266 'license_key' => $license_key,
1267 'version' => BERQWP_VERSION,
1268 't' => '',
1269 );
1270
1271 $endpoint_url = esc_url(add_query_arg($api_params, BERQ_SERVER));
1272
1273 $args = array(
1274 'method' => 'POST', // Only POST works for unknown reason
1275 'timeout' => 20,
1276 'redirection' => 5,
1277 'blocking' => true,
1278 'headers' => array(
1279 'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
1280 'Accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
1281 'Accept-Encoding' => 'gzip, deflate, br',
1282 'Accept-Language' => 'en-US,en;q=0.9',
1283 'Connection' => 'keep-alive',
1284 'Referer' => 'https://berqwp.com/', // Adjust based on actual referer
1285 ),
1286 'cookies' => array(),
1287 'sslverify' => false, // Disable SSL verification (for debugging purposes)
1288 );
1289
1290 // $request = wp_remote_request( $endpoint_url, $args );
1291
1292
1293 $berq_log->info('Making request 1');
1294
1295 $query_string = http_build_query($api_params);
1296 // $client = new HttpClient(BERQ_SERVER);
1297 // $client->setUserAgent('BerqWP');
1298 // $client->post('?' . $query_string, $api_params);
1299 // $client->setTimeout(30);
1300
1301 $client = new \BerqWP_Deps\GuzzleHttp\Client([
1302 'timeout' => 60,
1303 'http_errors' => false,
1304 'verify' => false,
1305 ]);
1306
1307 $response = $client->post(BERQ_SERVER . '?' . $query_string, [
1308 'form_params' => $api_params,
1309 ]);
1310 $statusCode = $response->getStatusCode();
1311 $response = $response->getBody()->getContents();
1312
1313 // var_dump($client->getContent(), $client->getError(), $api_params);
1314
1315 // $berq_log->info(print_r($client->getContent(), true).'---'.$client->ok());
1316
1317 if ($statusCode >= 200 && $statusCode < 300) {
1318 // $response = $client->getContent();
1319 $JSON = json_decode($response);
1320
1321 if ($action == 'slm_activate' && isset($JSON->error_code) && $JSON->message !== 'Invalid license key') {
1322 sleep(1);
1323 $api_params = array(
1324 'registered_domain' => $domain,
1325 'slm_action' => 'slm_check',
1326 'secret_key' => BERQ_SECRET,
1327 'license_key' => $license_key,
1328 't' => '',
1329 );
1330
1331 $berq_log->info('Making request 2');
1332
1333 $query_string = http_build_query($api_params);
1334 // $client = new HttpClient(BERQ_SERVER);
1335 // $client->setUserAgent('BerqWP');
1336 // $client->post('?' . $query_string, $api_params);
1337
1338
1339 // if ($client->ok()) {
1340 // $response = $client->getContent();
1341 // }
1342
1343 $response = $client->post(BERQ_SERVER . '?' . $query_string, [
1344 'form_params' => $api_params,
1345 ]);
1346
1347 $response = $response->getBody()->getContents();
1348 }
1349 }
1350
1351 if ($action !== 'slm_check') {
1352 $api_params = array(
1353 'registered_domain' => $domain,
1354 'slm_action' => 'slm_check',
1355 'secret_key' => BERQ_SECRET,
1356 'license_key' => $license_key,
1357 'version' => BERQWP_VERSION,
1358 't' => '',
1359 );
1360
1361 $berq_log->info('Making request 3');
1362
1363 $query_string = http_build_query($api_params);
1364 // $client = new HttpClient(BERQ_SERVER);
1365 // $client->setUserAgent('BerqWP');
1366 // $client->post('?' . $query_string, $api_params);
1367
1368
1369 // if ($client->ok()) {
1370 // $response = $client->getContent();
1371 // }
1372
1373 $response = $client->post(BERQ_SERVER . '?' . $query_string, [
1374 'form_params' => $api_params,
1375 ]);
1376
1377 $response = $response->getBody()->getContents();
1378 }
1379
1380 if (empty($response)) {
1381 return;
1382 }
1383
1384 $cached_response = json_decode($response);
1385
1386
1387 if ($action == 'slm_check' && !empty($cached_response) && !empty($cached_response->result)) {
1388 $domain_found = false;
1389
1390 foreach ($cached_response->registered_domains as $reg_domain) {
1391 $domain_name = str_replace('www.', '', $domain);
1392 $domain_name_www = 'www.' . $domain;
1393
1394 if ($reg_domain->registered_domain == $domain_name || $reg_domain->registered_domain == $domain_name_www || $reg_domain->registered_domain == $domain) {
1395 $domain_found = true;
1396 break;
1397 }
1398 }
1399
1400 if ($domain_found) {
1401 // Cache the response for 24 hours
1402 // set_transient($transient_key, $cached_response, 24 * HOUR_IN_SECONDS);
1403 berqwp_update_network_option($transient_key, $cached_response);
1404 berqwp_update_network_option($expire_transient_key, time() + MONTH_IN_SECONDS);
1405 } else {
1406
1407 berqwp_delete_network_option($transient_key);
1408 berqwp_delete_network_option($expire_transient_key);
1409 berqwp_delete_license_key();
1410
1411 return false;
1412 }
1413 }
1414
1415 // if ($action == 'slm_check' && !empty($cached_response) && $cached_response->result == 'success' && $cached_response->status == 'active') {
1416 // // Cache the response for 24 hours
1417 // set_transient($transient_key, $cached_response, 24 * HOUR_IN_SECONDS);
1418 // }
1419
1420 // if ($action == 'slm_check' && !empty($cached_response) && $cached_response->result == 'error') {
1421 // // Key verification failed, cache the response for 14 hours
1422 // // preventing unnecessary verification requests
1423 // set_transient($transient_key, $cached_response, 14 * HOUR_IN_SECONDS);
1424 // }
1425
1426 } else {
1427 // $berq_log->info('Delivering license key object from the transient cache.');
1428 }
1429
1430 // Return the cached response
1431 return $cached_response;
1432 }
1433
1434 // Disable emoji functionality
1435 function disable_emoji()
1436 {
1437 // Remove emoji-related actions and filters
1438 remove_action('wp_head', 'print_emoji_detection_script', 7);
1439 remove_action('admin_print_scripts', 'print_emoji_detection_script');
1440 remove_action('wp_print_styles', 'print_emoji_styles');
1441 remove_action('admin_print_styles', 'print_emoji_styles');
1442 remove_filter('the_content_feed', 'wp_staticize_emoji');
1443 remove_filter('comment_text_rss', 'wp_staticize_emoji');
1444 remove_filter('wp_mail', 'wp_staticize_emoji_for_email');
1445
1446 // Remove emoji-related TinyMCE plugins
1447 add_filter('tiny_mce_plugins', [$this, 'disable_emoji_tinymce']);
1448 }
1449
1450 // Filter function to disable emoji-related TinyMCE plugins
1451 function disable_emoji_tinymce($plugins)
1452 {
1453 if (is_array($plugins)) {
1454 return array_diff($plugins, array('wpemoji'));
1455 } else {
1456 return array();
1457 }
1458 }
1459
1460 // function clear_cache(WP_REST_Request $request)
1461 // {
1462 // require_once optifer_PATH . 'api/clear_cache.php';
1463 // }
1464
1465 // function warmup_cache(WP_REST_Request $request)
1466 // {
1467 // require_once optifer_PATH . 'api/warmup_cache.php';
1468 // }
1469
1470 // function store_cache(WP_REST_Request $request)
1471 // {
1472 // require_once optifer_PATH . 'api/store_cache.php';
1473 // }
1474
1475 // function store_javascript_cache(WP_REST_Request $request)
1476 // {
1477 // require_once optifer_PATH . 'api/store_javascript_cache.php';
1478 // }
1479
1480 // ==========================================
1481 // Multisite Network Support
1482 // ==========================================
1483
1484 function register_network_menu()
1485 {
1486 $svg = '<svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
1487 <path fill-rule="evenodd" clip-rule="evenodd" d="M6.43896 0H17.561C21.1172 0 24 2.88287 24 6.43903V17.561C24 21.1171 21.1172 24 17.561 24H6.43896C2.88281 24 0 21.1171 0 17.561V6.43903C0 2.88287 2.88281 0 6.43896 0ZM15.7888 4.09753L8.59961 12.7534H12.3517L7.02441 20.4878L16.3903 11.0222L12.7814 10.3799L15.7888 4.09753Z" fill="#a7aaad"/>
1488 </svg>';
1489
1490 $plugin_name = defined('BERQWP_PLUGIN_NAME') ? BERQWP_PLUGIN_NAME : 'BerqWP';
1491
1492 add_menu_page(
1493 $plugin_name . ' Network',
1494 $plugin_name,
1495 'manage_network_options',
1496 'berqwp-network',
1497 [$this, 'network_admin_page'],
1498 'data:image/svg+xml;base64,' . base64_encode($svg),
1499 80
1500 );
1501 }
1502
1503 function network_admin_page()
1504 {
1505 require_once optifer_PATH . 'admin/network-admin-page.php';
1506 }
1507
1508 function save_network_settings()
1509 {
1510 check_admin_referer('berqwp_network_save');
1511
1512 if (!current_user_can('manage_network_options')) {
1513 wp_die('Unauthorized');
1514 }
1515
1516 // License activation
1517 if (!empty($_POST['berqwp_license_key'])) {
1518 $key = sanitize_text_field($_POST['berqwp_license_key']);
1519 // $key_response = $this->verify_license_key($key, 'slm_activate');
1520 $key_response = $this->authenticate_license($key);
1521 if (!empty($key_response->lic) && isset($key_response->lic->result) && $key_response->lic->result == 'success') {
1522 berqwp_update_license_key($key);
1523 }
1524 }
1525
1526 // License deactivation
1527 if (!empty($_POST['berq_deactivate_key'])) {
1528 $existing_key = berqwp_get_license_key();
1529 if (!empty($existing_key)) {
1530 $this->verify_license_key($existing_key, 'slm_deactivate');
1531 }
1532 berqwp_delete_license_key();
1533 berqwp_delete_network_option('berq_lic_response_cache');
1534 berqwp_delete_network_option('berq_lic_cache_expire');
1535 berqwp_delete_network_option('berqwp_lic_response_cache');
1536 berqwp_delete_network_option('berqwp_lic_cache_expire');
1537 }
1538
1539 // Flush all sites cache
1540 if (!empty($_POST['berqwp_flush_all_cache'])) {
1541 $cache_directory = WP_CONTENT_DIR . '/cache/berqwp/html/';
1542 if (is_dir($cache_directory)) {
1543 berqwp_unlink_recursive($cache_directory);
1544 }
1545 }
1546
1547 wp_safe_redirect(network_admin_url('admin.php?page=berqwp-network&updated=true'));
1548 exit;
1549 }
1550
1551 function regenerate_blog_map()
1552 {
1553 if (!function_exists('is_multisite') || !is_multisite()) {
1554 return;
1555 }
1556
1557 $sites = get_sites(['fields' => 'ids', 'number' => 0]);
1558 $map = [
1559 'subdomains' => [],
1560 'subdirs' => [],
1561 ];
1562
1563 $is_subdomain = defined('SUBDOMAIN_INSTALL') && SUBDOMAIN_INSTALL;
1564
1565 foreach ($sites as $site_id) {
1566 $site = get_site($site_id);
1567 if (!$site) continue;
1568
1569 if ($is_subdomain) {
1570 $map['subdomains'][strtolower($site->domain)] = (int) $site_id;
1571 } else {
1572 $path = rtrim($site->path, '/') . '/';
1573 if ($path !== '/') {
1574 $map['subdirs'][$path] = (int) $site_id;
1575 }
1576 }
1577 }
1578
1579 $map_file = WP_CONTENT_DIR . '/cache/berqwp/blog-map.json';
1580 $map_dir = dirname($map_file);
1581 if (!is_dir($map_dir)) {
1582 wp_mkdir_p($map_dir);
1583 }
1584 file_put_contents($map_file, json_encode($map, JSON_PRETTY_PRINT));
1585 }
1586
1587 function on_new_site_created($new_site)
1588 {
1589 if (function_exists('is_plugin_active_for_network') && is_plugin_active_for_network('searchpro/berqwp.php')) {
1590 switch_to_blog($new_site->blog_id);
1591 berqwp_activate_single_site();
1592 restore_current_blog();
1593 }
1594 $this->regenerate_blog_map();
1595 }
1596
1597 function register_menu()
1598 {
1599 $svg = '<svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
1600 <path fill-rule="evenodd" clip-rule="evenodd" d="M6.43896 0H17.561C21.1172 0 24 2.88287 24 6.43903V17.561C24 21.1171 21.1172 24 17.561 24H6.43896C2.88281 24 0 21.1171 0 17.561V6.43903C0 2.88287 2.88281 0 6.43896 0ZM15.7888 4.09753L8.59961 12.7534H12.3517L7.02441 20.4878L16.3903 11.0222L12.7814 10.3799L15.7888 4.09753Z" fill="#a7aaad"/>
1601 </svg>';
1602
1603 $plugin_name = defined('BERQWP_PLUGIN_NAME') ? BERQWP_PLUGIN_NAME : 'BerqWP';
1604
1605 add_menu_page($plugin_name, $plugin_name, 'manage_options', 'berqwp', [$this, 'admin_page'], 'data:image/svg+xml;base64,' . base64_encode($svg), 80);
1606 }
1607
1608 function admin_page()
1609 {
1610
1611 $berqconfigs = berqConfigs::getInstance();
1612 $configs = $berqconfigs->get_configs();
1613
1614 if (!empty($configs['optimization_method'])) {
1615 require_once optifer_PATH . 'admin/admin-page.php';
1616 } else {
1617 require_once optifer_PATH . 'admin/intro-page.php';
1618 }
1619 }
1620 }
1621
1622 berqWP::getInstance();
1623 // global $berqWP;
1624 // $berqWP = new berqWP();
1625 }
1626