PluginProbe
BerqWP – All-In-One Optimization for Core Web Vitals, Cache, CDN, Images, CSS & JavaScript / 4.0.19
BerqWP – All-In-One Optimization for Core Web Vitals, Cache, CDN, Images, CSS & JavaScript v4.0.19
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.19, at inc/class-berqwp.php

1,620 lines 52.7 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($_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($_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($_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 if (!isset($_POST['start']) || !isset($_POST['length'])) {
409 wp_send_json_error('Invalid parameters');
410 return;
411 }
412
413 $start = intval($_POST['start']); // Offset for the query
414 $length = intval($_POST['length']); // Number of records to fetch per request
415 $search = isset($_POST['search']) ? sanitize_text_field($_POST['search']) : ''; // Search term if present
416
417 $post_types = get_option('berqwp_optimize_post_types');
418 $optimized_pages = [];
419
420 // Build the query arguments
421 $args = array(
422 'post_type' => $post_types,
423 'posts_per_page' => $length, // Limit the number of posts per request
424 'offset' => $start, // Set the offset for pagination
425 'post_status' => array('publish'), // Only published pages
426 );
427
428 // Add search filtering, if applicable
429 if (!empty($search)) {
430 $args['s'] = $search; // Add the search parameter to the query
431 }
432
433 if ($start === 0 && empty($search)) {
434 $url = bwp_admin_home_url('/');
435
436 if (strpos($url, bwp_admin_home_url()) === false) {
437 $url = str_replace(home_url(), bwp_admin_home_url(), $url);
438 }
439
440 $slug = bwp_url_into_path($url);
441
442 $cache_directory = bwp_get_cache_dir();
443 $cache_key = md5($url);
444 // $cache_key = md5($slug);
445 $cache_file = $cache_directory . $cache_key . '.gz';
446
447 if (is_file($cache_file)) {
448 $status = '<span class="bwp-cache-tag completed">Completed</span>';
449
450 // if (bwp_is_partial_cache($url) === true) {
451 // $status = '<span class="bwp-cache-tag part-completed">Partial cache</span>';
452 // }
453 } else {
454 $status = '<span class="bwp-cache-tag">Pending</span>';
455 }
456
457 $parsed_url = parse_url($url);
458 $decoded_path = isset($parsed_url['path']) ? urldecode($parsed_url['path']) : '';
459 $decoded_query = isset($parsed_url['query']) ? urldecode($parsed_url['query']) : '';
460
461 $decoded_url = $parsed_url['scheme'] . '://' . $parsed_url['host'];
462 if (isset($parsed_url['port'])) {
463 $decoded_url .= ':' . $parsed_url['port'];
464 }
465 $decoded_url .= $decoded_path;
466 if ($decoded_query) {
467 $decoded_url .= '?' . $decoded_query;
468 }
469 if (isset($parsed_url['fragment'])) {
470 $decoded_url .= '#' . $parsed_url['fragment'];
471 }
472
473 $page_arr = [
474 'url' => $decoded_url,
475 'status' => $status,
476 'last_modified' => file_exists($cache_file) ? date('Y-m-d H:i:s', filemtime($cache_file)) : ''
477 ];
478
479 array_push($optimized_pages, $page_arr);
480 }
481
482 $query = new WP_Query($args);
483 $total_posts = $query->found_posts; // Get the total number of records
484
485 $valid_posts_query = new WP_Query([
486 'post_type' => $post_types,
487 'posts_per_page' => -1,
488 'fields' => 'ids',
489 'post_status' => ['publish'],
490 ]);
491 $valid_posts = array_filter($valid_posts_query->posts, function ($post_id) {
492 $url = get_permalink($post_id);
493 return bwp_can_optimize_page_url($url);
494 });
495 $total_posts = count($valid_posts);
496
497 if ($query->have_posts()) {
498 while ($query->have_posts()) {
499 $query->the_post();
500
501 $url = get_permalink();
502
503 if (strpos($url, bwp_admin_home_url()) === false) {
504 $url = str_replace(home_url(), bwp_admin_home_url(), $url);
505 }
506
507 if (bwp_admin_home_url('/') == $url) {
508 continue;
509 }
510
511 $slug = bwp_url_into_path($url);
512
513 if (!bwp_can_optimize_page_url($url)) {
514 continue;
515 }
516
517 $cache_directory = bwp_get_cache_dir();
518 $cache_key = md5($url);
519 // $cache_key = md5($slug);
520 $cache_file = $cache_directory . $cache_key . '.gz';
521
522 if (is_file($cache_file)) {
523 $status = '<span class="bwp-cache-tag completed">Completed</span>';
524
525 // if (bwp_is_partial_cache($url) === true) {
526 // $status = '<span class="bwp-cache-tag part-completed">Partial cache</span>';
527 // }
528 } else {
529 $status = '<span class="bwp-cache-tag">Pending</span>';
530 }
531
532 $parsed_url = parse_url($url);
533 $decoded_path = isset($parsed_url['path']) ? urldecode($parsed_url['path']) : '';
534 $decoded_query = isset($parsed_url['query']) ? urldecode($parsed_url['query']) : '';
535
536 $decoded_url = $parsed_url['scheme'] . '://' . $parsed_url['host'];
537 if (isset($parsed_url['port'])) {
538 $decoded_url .= ':' . $parsed_url['port'];
539 }
540 $decoded_url .= $decoded_path;
541 if ($decoded_query) {
542 $decoded_url .= '?' . $decoded_query;
543 }
544 if (isset($parsed_url['fragment'])) {
545 $decoded_url .= '#' . $parsed_url['fragment'];
546 }
547
548 $page_arr = [
549 'url' => $decoded_url,
550 'status' => $status,
551 'last_modified' => file_exists($cache_file) ? date('Y-m-d H:i:s', filemtime($cache_file)) : ''
552 ];
553
554 array_push($optimized_pages, $page_arr);
555 }
556 }
557
558 wp_reset_postdata();
559
560 // Send the response with the optimized pages and total entries
561 wp_send_json_success([
562 'optimized_pages' => $optimized_pages,
563 'total_entries' => $total_posts, // Total number of posts (unfiltered)
564 'records_filtered' => $total_posts // Adjust if filtered by search
565 ]);
566 }
567
568
569
570 function ajax_recently_optimized_pages()
571 {
572 check_ajax_referer('wp_rest', 'nonce');
573
574 $search = isset($_POST['search']) ? sanitize_text_field($_POST['search']) : '';
575 $start = max(0, intval($_POST['start'] ?? 0));
576 $length = max(1, intval($_POST['length'] ?? 10));
577
578 $log = json_decode(get_option('berqwp_recently_optimized', '[]'), true);
579 if (!is_array($log)) $log = [];
580
581 if (!empty($search)) {
582 $s = strtolower(rtrim($search, '/'));
583 $home = strtolower(rtrim(home_url(), '/'));
584 // Strip the site root from the search term so we compare paths only.
585 // e.g. "http://plugin-berqwp.local/" → "", "/about" → "/about"
586 $s_path = ltrim(str_starts_with($s, $home) ? substr($s, strlen($home)) : $s, '/');
587
588 $log = array_values(array_filter($log, function ($e) use ($s, $home, $s_path) {
589 $url = strtolower(rtrim($e['url'], '/'));
590 $url_path = ltrim(str_starts_with($url, $home) ? substr($url, strlen($home)) : $url, '/');
591 // Exact path match (covers homepage: both empty)
592 if ($url_path === $s_path) return true;
593 // Path starts with the search path (only if search is non-empty to avoid matching everything)
594 if ($s_path !== '' && str_starts_with($url_path, $s_path)) return true;
595 // Full URL substring fallback
596 return $s_path === '' ? $url === $home : stripos($url_path, $s_path) !== false;
597 }));
598
599 // Sort: exact path match first, prefix match second, substring last
600 usort($log, function ($a, $b) use ($home, $s_path) {
601 $pa = ltrim(str_starts_with(strtolower(rtrim($a['url'], '/')), $home)
602 ? substr(strtolower(rtrim($a['url'], '/')), strlen($home)) : strtolower(rtrim($a['url'], '/')), '/');
603 $pb = ltrim(str_starts_with(strtolower(rtrim($b['url'], '/')), $home)
604 ? substr(strtolower(rtrim($b['url'], '/')), strlen($home)) : strtolower(rtrim($b['url'], '/')), '/');
605 $ra = $pa === $s_path ? 0 : (str_starts_with($pa, $s_path) ? 1 : 2);
606 $rb = $pb === $s_path ? 0 : (str_starts_with($pb, $s_path) ? 1 : 2);
607 return $ra <=> $rb;
608 });
609 }
610
611 $total = count($log);
612 $page_log = array_slice($log, $start, $length);
613
614 wp_send_json_success([
615 'data' => $page_log,
616 'total' => $total,
617 'records_filtered' => $total,
618 ]);
619 }
620
621 function ashp_increase_concurrent_batches($concurrent_batches)
622 {
623 return $concurrent_batches * 2;
624 }
625
626 function refresh_cache_stats()
627 {
628
629 check_ajax_referer('wp_rest', 'nonce');
630
631 $post_types = get_option('berqwp_optimize_post_types');
632 $args = array(
633 'post_type' => $post_types,
634 'posts_per_page' => -1,
635 'fields' => 'ids',
636 'post_status' => 'publish'
637 );
638 $query = new WP_Query($args);
639 $pages_to_exclude = get_option('berq_exclude_urls', []);
640 $total_pages = (int) $query->found_posts - count($pages_to_exclude);
641 $optimized_pages = bwp_cached_pages_count();
642
643 if (get_option('show_on_front') !== 'page') {
644 $total_pages++;
645 }
646
647 if (empty($total_pages) || $total_pages <= 0) {
648 $cached_percentage = 0;
649 } else {
650 $cached_percentage = round(($optimized_pages / $total_pages) * 100, 2);
651 }
652 if ($cached_percentage > 100) {
653 $cached_percentage = 100;
654 }
655
656 if ($cached_percentage < 0) {
657 $cached_percentage = 0;
658 }
659
660 $server_queue = get_option('berqwp_server_queue', []);
661
662 wp_send_json_success(['cache_count' => $optimized_pages, 'cache_percentage' => $cached_percentage, 'total' => $total_pages, 'server_queue' => count($server_queue)]);
663
664 die(); // Always exit in AJAX functions
665 }
666
667 function fetch_remote_html()
668 {
669
670 check_ajax_referer('wp_rest', 'nonce');
671
672 $url = get_option('berqwp_enable_sandbox') ? bwp_admin_home_url('/?berqwp') : bwp_admin_home_url('/');
673
674 $response = wp_remote_get($url);
675 // $response = bwp_wp_remote_get($url);
676
677 if (is_array($response) && !is_wp_error($response)) {
678 $html = wp_remote_retrieve_body($response);
679 echo $html;
680 } else {
681 echo 'Error fetching HTML.';
682 }
683
684 die(); // Always exit in AJAX functions
685 }
686
687 function activate_license_from_multi_site()
688 {
689 if (berq_is_localhost()) {
690 return;
691 }
692
693 $berqwp_license_key_from_parent = constant('BERQWP_LICENSE_KEY');
694
695 if (!empty($berqwp_license_key_from_parent) && empty(berqwp_get_license_key())) {
696 $key = sanitize_text_field($berqwp_license_key_from_parent);
697 $key_response = $this->verify_license_key($key, 'slm_activate');
698
699
700 if (!empty($key_response) && $key_response->result == 'success') {
701 berqwp_update_license_key($key);
702
703 if (is_admin()) {
704 ?>
705 <div class="notice notice-success is-dismissible">
706 <?php esc_html_e('The BerqWP license has been activated for your parent multisite.', 'searchpro'); ?>
707 </div>
708 <?php
709 }
710 } elseif ($key_response->result == 'error') {
711 $error = $key_response->message;
712
713 if (is_admin()) {
714 ?>
715 <div class="notice notice-error is-dismissible">
716 <?php echo esc_html($error); ?>
717 </div>
718 <?php
719
720 }
721 }
722 }
723 }
724
725 function handle_upgrade() {
726
727 $berqconfigs = berqConfigs::getInstance();
728 $configs = $berqconfigs->get_configs();
729 $site_id = $configs['site_id'];
730 $license_key = berqwp_get_license_key();
731 global $berq_log;
732
733 if (!empty($configs['optimization_method']) && $configs['optimization_method'] == 'cloud' && empty($license_key)) {
734
735 $berqconfigs->update_configs([
736 'secret' => '',
737 'optimization_method' => 'local'
738 ]);
739 return;
740 }
741
742 $license_check_only = false;
743
744 if ( !empty($configs['secret']) && !empty($configs['optimization_method']) && $configs['optimization_method'] == 'cloud' && !empty($license_key) && empty(berqwp_get_network_option('berqwp_license_cache')) ) {
745 $license_check_only = true;
746 }
747
748 // user first time upgrades to v4
749 $first_upgrade = empty($configs['optimization_method']) && !empty($license_key);
750 $missing_secret = empty($configs['secret']) && !empty($configs['optimization_method']) && $configs['optimization_method'] == 'cloud' && !empty($license_key);
751
752 if ($first_upgrade || $missing_secret || !empty($license_check_only)) {
753
754 // $berq_log->info("Authenticating secret");
755
756 // $lic_response = wp_remote_post(BerqWPCloud::$endpoint."authenticate", [
757 // 'timeout' => 30,
758 // 'body' => $request_body
759 // ]);
760
761 // if (is_wp_error($lic_response)) {
762 // $berq_log->info("Couldn't reach BerqWP server.");
763 // return;
764 // }
765
766 // $lic_body = wp_remote_retrieve_body($lic_response);
767 // $lic_json = json_decode($lic_body);
768
769 // if (empty($lic_json)) {
770 // $berq_log->info("Authenticate secret invalid response");
771 // return;
772 // }
773
774 $lic_json = $this->authenticate_license($license_key, $license_check_only);
775
776 if (!empty($lic_json->lic) && $lic_json->lic->result == 'success' && ($lic_json->lic->message == 'License key activated' || $lic_json->lic->status == 'active')) {
777
778 if (!empty($lic_json->secret)) {
779 $berqconfigs->update_configs([
780 'secret' => $lic_json->secret,
781 'optimization_method' => 'cloud'
782 ]);
783 }
784
785 berqwp_update_network_option('berqwp_license_cache', $lic_json->lic);
786
787 $berq_log->info("Authentication success.");
788
789 // Fresh installation
790 if (get_option('berqwp_can_use_fluid_images') === false) {
791
792 if ($lic_json->lic->product_ref !== 'AppSumo Deal') {
793 update_option('berqwp_can_use_fluid_images', 1);
794 } else {
795 update_option('berqwp_can_use_fluid_images', 0);
796 update_option('berqwp_sync_addons', true);
797 }
798 }
799
800 } else {
801
802 $berq_log->info("Authentication failed.");
803 berqwp_remove_license_key();
804
805 $berqconfigs->update_configs([
806 'secret' => '',
807 'optimization_method' => 'local'
808 ]);
809
810 berqwp_delete_network_option('berqwp_license_cache');
811 }
812
813 }
814
815 if (!empty(berqwp_get_network_option('berqwp_license_cache'))) {
816 $this->is_key_verified = true;
817 $this->key_response = berqwp_get_network_option('berqwp_license_cache');
818 }
819
820 }
821
822 function initialize()
823 {
824
825 if (defined('DOING_CRON') && DOING_CRON) {
826 return;
827 }
828
829 if (defined('DOING_AJAX') && DOING_AJAX) {
830 return;
831 }
832
833 // Set default settings
834 require_once optifer_PATH . '/inc/initialize.php';
835
836 $this->handle_upgrade();
837
838 if (berqwp_can_use_cloud()) {
839 $license_key = berqwp_get_license_key();
840 $lic_json = $this->authenticate_license($license_key, true);
841
842 if (!empty($lic_json->lic) && $lic_json->lic->result == 'success' && ($lic_json->lic->message == 'License key activated' || $lic_json->lic->status == 'active')) {
843 berqwp_update_network_option('berqwp_license_cache', $lic_json->lic);
844 }
845 }
846
847 // Activate the license from parent site
848 // if (defined('BERQWP_LICENSE_KEY')) {
849 // $this->activate_license_from_multi_site();
850 // }
851
852 if (is_admin()) {
853 $this->berq_post_types();
854 }
855
856 // if (is_admin() && isset($_GET['bwp_get_ip'])) {
857 // $ip = file_get_contents('https://api.ipify.org');
858 // echo 'Server Public IP Address: ' . $ip;
859 // exit;
860 // }
861
862 // if (is_admin() && !empty(berqwp_get_license_key())) {
863 // $license_key = berqwp_get_license_key();
864
865 // global $berq_log;
866 // // $berq_log->info("License key check from initialize function.");
867
868 // $key_response = $this->verify_license_key($license_key);
869
870 // if (!empty($key_response) && $key_response->result == 'success' && $key_response->status == 'active') {
871 // $this->is_key_verified = true;
872 // $this->key_response = $key_response;
873
874 // // Fresh installation
875 // if (get_option('berqwp_can_use_fluid_images') === false) {
876
877 // if ($key_response->product_ref !== 'AppSumo Deal') {
878 // update_option('berqwp_can_use_fluid_images', 1);
879 // } else {
880 // update_option('berqwp_can_use_fluid_images', 0);
881 // update_option('berqwp_sync_addons', true);
882 // }
883 // }
884
885 // } else {
886 // $this->is_key_verified = false;
887
888 // if (!empty($key_response) && $key_response->result == 'error') {
889 // berqwp_delete_license_key();
890 // }
891 // }
892 // }
893
894 // redirect to berqwp admin page
895 if (get_transient('berqwp_redirect')) {
896 delete_transient('berqwp_redirect');
897 // Set the URL to redirect to after activation
898 $redirect_url = admin_url('admin.php?page=berqwp');
899
900 // Redirect after activation
901 wp_redirect($redirect_url);
902
903 // Make sure to exit after the redirect
904 exit;
905 }
906
907 // Deactivate conflicting plugins
908 if (is_admin() && isset($_POST['berqwp_plugins_deactivate']) && wp_verify_nonce($_POST['berqwp_plugins_deactivate'], 'berqwp_plugins_deactivate')) {
909 foreach ($this->conflicting_plugins as $plugin) {
910 // Deactivate each conflicting plugin
911 if (is_plugin_active($plugin)) {
912 deactivate_plugins($plugin);
913 }
914 }
915 header('location: ' . esc_url(get_site_url() . add_query_arg($_GET)));
916 exit;
917 }
918 }
919
920 function save_settings()
921 {
922 require_once optifer_PATH . '/admin/save-settings.php';
923 }
924
925 function notices()
926 {
927
928 $plugin_name = defined('BERQWP_PLUGIN_NAME') ? BERQWP_PLUGIN_NAME : 'BerqWP';
929
930 if (isset($_GET['berqwp_page_compression_enabled'])) {
931 bwp_notice('success', 'Page Compression Enabled', "<p>Page compression has been successfully enabled on your website.</p>");
932 }
933
934 if (isset($_GET['dismiss_feedback'])) {
935 set_transient('bqwp_hide_feedback_notice', true, DAY_IN_SECONDS * 14);
936 }
937
938 if (isset($_GET['bwp_quit_feedback'])) {
939 update_option('bwp_quit_feedback', true);
940 }
941
942
943 if (!empty($this->key_response) && $this->key_response->result == 'success' && $this->key_response->status == 'expired') {
944 ?>
945 <div class="notice notice-error">
946 <p><strong>Error:</strong> <?php echo $plugin_name; ?> license key has expired. Please renew your subscription.</p>
947 </div>
948 <?php
949 }
950
951 // Check connection
952 // $check_rest = bwp_check_connection(false, !empty($_GET['bwp_connection_test']) === true);
953 // if ($check_rest['status'] == 'error') {
954 // 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>", [
955 // [
956 // 'href' => esc_attr(add_query_arg(['bwp_connection_test' => true], get_admin_url())),
957 // 'text' => 'Check again',
958 // 'classes' => '',
959 // ]
960 // ]);
961 // }
962
963 // Check Permissions
964 $cache_directory = WP_CONTENT_DIR . '/cache/berqwp/';
965 $wp_config_file = defined('BERQWP_WP_CONFIG') ? BERQWP_WP_CONFIG : ABSPATH . 'wp-config.php';
966
967 if (!is_writable($cache_directory)) {
968 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>", []);
969 }
970
971 if (!defined('WP_CACHE') && !is_writable($wp_config_file)) {
972 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>", []);
973 }
974
975 if (defined('BERQWP_ADVANCED_CACHE_PATH')) {
976 $adv_cache_path = BERQWP_ADVANCED_CACHE_PATH;
977 } else {
978 $adv_cache_path = WP_CONTENT_DIR . '/advanced-cache.php';
979 }
980
981 // if (file_exists($adv_cache_path) && !is_writable($adv_cache_path)) {
982 // 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>", []);
983 // }
984
985 if (isset($_GET['page']) && $_GET['page'] == 'berqwp' && !get_transient('bqwp_hide_feedback_notice') && !get_option('bwp_quit_feedback') && $this->is_key_verified && bwp_show_account()) {
986 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>', [
987 [
988 'href' => 'https://wordpress.org/support/plugin/searchpro/reviews/#new-post',
989 'text' => '❤️ You deserve it',
990 'classes' => '',
991 'target' => '_blank',
992 ],
993 [
994 'href' => get_admin_url() . 'admin.php?page=berqwp&bwp_quit_feedback',
995 'text' => '👍 Already did',
996 'classes' => '',
997 'target' => '',
998 ],
999 [
1000 'href' => get_admin_url() . 'admin.php?page=berqwp&dismiss_feedback',
1001 'text' => 'Not Now',
1002 'classes' => '',
1003 'target' => '',
1004 ]
1005 ]);
1006
1007 // $notice = '<div class="bwp-notice bwp_feedback">';
1008 // $notice .= '<p>';
1009 // $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');
1010 // $notice .= '<a href="'.get_admin_url().'admin.php?page=berqwp&dismiss_feedback" style="display: table;margin-left: 50px;color: #969595;display: table;">Dismiss</a>';
1011 // $notice .= '</p>';
1012 // $notice .= '</div>';
1013 // echo wp_kses_post($notice);
1014 }
1015
1016 // purge single page notice
1017 if (get_transient('berq_purge_page_notice')) {
1018 $flushed_page = esc_url(get_transient('berq_purge_page_notice'));
1019 delete_transient('berq_purge_page_notice');
1020 bwp_notice('success', '', "<p>Page cache has been flushed for $flushed_page.</p>", []);
1021 }
1022
1023 // purge all cache notice
1024 if (get_transient('berq_cache_cleared_notice')) {
1025 delete_transient('berq_cache_cleared_notice');
1026 bwp_notice('success', '', '<p>The cache has been cleared. Our automatic cache warm-up system will generate the cache. Alternatively, you can
1027 visit any page to create its cache immediately.</p>', []);
1028 }
1029
1030 // purge cdn cache notice
1031 if (get_transient('berq_purge_cdn_notice')) {
1032 delete_transient('berq_purge_cdn_notice');
1033 bwp_notice('success', '', '<p>The CDN and page cache have been flushed.</p>', []);
1034 }
1035
1036 // purge critical css cache notice
1037 if (get_transient('berq_purge_criticalcss_notice')) {
1038 delete_transient('berq_purge_criticalcss_notice');
1039 bwp_notice('success', '', '<p>Critical CSS cache has been flushed from the cloud.</p>', []);
1040 }
1041
1042 // cache warmup notice
1043 if (get_transient('berq_cache_warmup_notice')) {
1044 delete_transient('berq_cache_warmup_notice');
1045 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>', []);
1046 }
1047
1048 // force page cache notice
1049 if (get_transient('berq_force_cache_notice')) {
1050 $forced_page = esc_url(get_transient('berq_force_cache_notice'));
1051 delete_transient('berq_force_cache_notice');
1052 bwp_notice('success', '', "<p>The cache for page ($forced_page) has been queued with high priority and will be generated soon.</p>", []);
1053 }
1054
1055 if (get_option('bwp_require_flush_cache', false)) {
1056 bwp_notice('warning', 'Cache Flush Required', '<p>To apply the changes, please flush the cache.</p>', [
1057 [
1058 'href' => esc_attr(wp_nonce_url(admin_url('admin-post.php?action=clear_cache'), 'clear_cache_action')),
1059 'text' => 'Flush cache',
1060 'classes' => '',
1061 ]
1062 ]);
1063 }
1064
1065 if (berq_is_localhost() && berqwp_can_use_cloud()) {
1066 bwp_notice('warning', 'Localhost environment detected:', "<p>$plugin_name requires a live, publicly accessible website to function.</p>", []);
1067 }
1068
1069 $plugins_to_deactivate = '';
1070
1071 foreach ($this->conflicting_plugins as $plugin) {
1072 if (is_plugin_active($plugin)) {
1073 $plugins_to_deactivate .= '<li><b>' . basename(dirname($plugin)) . '</b></li>';
1074 }
1075 }
1076
1077 if (!empty($plugins_to_deactivate)) {
1078 echo "<style>.berqwp-plugin-conflict ul {
1079 list-style: disc;
1080 margin-left: 20px;
1081 }.berqwp-plugin-conflict form {
1082 padding: 10px;
1083 }
1084 .berqwp-plugin-conflict {
1085 display: grid;
1086 grid-template-columns: auto min-content;
1087 }</style>";
1088 echo '<div class="bwp-notice notice notice-error berqwp-plugin-conflict">';
1089 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'));
1090 ?>
1091 <form action="<?php echo esc_url(get_site_url() . add_query_arg($_GET)); ?>" method="post">
1092
1093 <?php
1094 $my_nonce = wp_create_nonce('berqwp_plugins_deactivate');
1095 echo '<input type="hidden" name="berqwp_plugins_deactivate" value="' . esc_attr($my_nonce) . '" />';
1096 ?>
1097
1098 <input type="submit" class="button-secondary alignright" value="Deactivate Conflicting Plugins">
1099 </form>
1100 <?php
1101 echo wp_kses_post("<ul>$plugins_to_deactivate</ul>");
1102 echo '</div>';
1103 }
1104 }
1105
1106 function berq_post_types()
1107 {
1108 // Get post type names
1109 $post_type_names = get_post_types(['public' => true, 'exclude_from_search' => false], 'names');
1110 unset($post_type_names['attachment']);
1111
1112 // var_dump($post_type_names);
1113
1114 // Modify which post types to optimize
1115 $post_type_names = apply_filters('berqwp_post_types', $post_type_names);
1116
1117 // Save the names in a WordPress option
1118 update_option('berqwp_post_type_names', $post_type_names);
1119 }
1120
1121 function plugin_settings_links($links)
1122 {
1123 $mylinks = array(
1124 '<a target="_blank" href="https://berqwp.com/help-center/">' . __('Help Center', 'searchpro') . '</a>',
1125 '<a href="' . admin_url('admin.php?page=berqwp') . '">' . __('Settings', 'searchpro') . '</a>',
1126 );
1127
1128 return array_merge($links, $mylinks);
1129 }
1130
1131 function authenticate_license($license_key, $check_only = false) {
1132
1133 $berqconfigs = berqConfigs::getInstance();
1134 $berqwp_configs = $berqconfigs->get_configs();
1135 $site_id = $berqwp_configs['site_id'];
1136
1137 if (empty($site_id)) {
1138 $blog_id = get_current_blog_id();
1139 $network_id = function_exists('get_current_network_id') ? get_current_network_id() : 1;
1140 $siteurl = get_option('siteurl');
1141 $site_id = md5("berqwp|$network_id|$blog_id|$siteurl");
1142
1143 $berqconfigs->update_configs(['site_id' => $site_id]);
1144 }
1145
1146 global $berq_log;
1147 $transient_key = 'berqwp_lic_response_cache'; // Set a unique key for the transient
1148 $expire_transient_key = 'berqwp_lic_cache_expire'; // Set a unique key for the transient
1149
1150 if (!$check_only) {
1151 berqwp_delete_network_option($transient_key);
1152 }
1153
1154 // Check if the response is already cached
1155 $lic_json = berqwp_get_network_option($transient_key);
1156 $cache_expire_time = (int) berqwp_get_network_option($expire_transient_key);
1157
1158 if (false === $lic_json || $cache_expire_time < time()) {
1159
1160 $berq_log->info("Authenticating license key");
1161
1162 $body = [
1163 'license_key' => $license_key,
1164 'site_id' => $site_id,
1165 'site_url' => home_url(),
1166 ];
1167
1168 if ($check_only) {
1169 $body['check'] = true;
1170 }
1171
1172 $lic_response = wp_remote_post(BerqWPCloud::$endpoint."authenticate", [
1173 'timeout' => 30,
1174 'body' => $body
1175 ]);
1176
1177 if (is_wp_error($lic_response)) {
1178 $berq_log->info("Couldn't reach BerqWP server.");
1179 return;
1180 }
1181
1182 $lic_body = wp_remote_retrieve_body($lic_response);
1183 $lic_json = json_decode($lic_body);
1184
1185 if (!empty($lic_json)) {
1186 berqwp_update_network_option($transient_key, $lic_json);
1187 berqwp_update_network_option($expire_transient_key, time() + DAY_IN_SECONDS);
1188 }
1189
1190 }
1191
1192
1193 return $lic_json;
1194
1195 }
1196
1197 function verify_license_key($license_key, $action = 'slm_check')
1198 {
1199 if ($action !== 'slm_deactivate') {
1200 return;
1201 }
1202
1203 // Action
1204 // slm_activate
1205 // slm_deactivate
1206 // slm_check
1207
1208 if (empty($license_key)) {
1209 return;
1210 }
1211
1212 if (defined('BERQWP_DOING_LICENSE_CHECK')) {
1213 // sleep(1);
1214 return;
1215 }
1216
1217 /**
1218 * Replaced transients with options
1219 */
1220
1221 global $berq_log;
1222 $transient_key = 'berq_lic_response_cache'; // Set a unique key for the transient
1223 $expire_transient_key = 'berq_lic_cache_expire'; // Set a unique key for the transient
1224
1225 if ($action !== 'slm_check') {
1226 // delete_transient( $transient_key );
1227 berqwp_delete_network_option($transient_key);
1228 }
1229
1230 // Check if the response is already cached
1231 // $cached_response = get_transient($transient_key);
1232 $cached_response = berqwp_get_network_option($transient_key);
1233 $cache_expire_time = (int) berqwp_get_network_option($expire_transient_key);
1234
1235
1236 if (false === $cached_response || $cache_expire_time < time()) {
1237 // If not cached, perform the API request
1238
1239 $rateLimiter = new RateLimiter(5, 60, optifer_cache . 'ratelimit/');
1240 $clientIdentifier = gethostname();
1241 if (function_exists('is_multisite') && is_multisite()) {
1242 $clientIdentifier .= '-site-' . get_current_blog_id();
1243 }
1244
1245 if ($rateLimiter->isRateLimited($clientIdentifier)) {
1246 return false;
1247 }
1248
1249 define('BERQWP_DOING_LICENSE_CHECK', true);
1250
1251 $berq_log->info('Checking the license key.');
1252
1253 $parsed_url = parse_url(home_url());
1254 $domain = $parsed_url['host'];
1255
1256 $api_params = array(
1257 'registered_domain' => $domain,
1258 'slm_action' => $action,
1259 'secret_key' => BERQ_SECRET,
1260 'license_key' => $license_key,
1261 'version' => BERQWP_VERSION,
1262 't' => '',
1263 );
1264
1265 $endpoint_url = esc_url(add_query_arg($api_params, BERQ_SERVER));
1266
1267 $args = array(
1268 'method' => 'POST', // Only POST works for unknown reason
1269 'timeout' => 20,
1270 'redirection' => 5,
1271 'blocking' => true,
1272 'headers' => array(
1273 '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',
1274 'Accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
1275 'Accept-Encoding' => 'gzip, deflate, br',
1276 'Accept-Language' => 'en-US,en;q=0.9',
1277 'Connection' => 'keep-alive',
1278 'Referer' => 'https://berqwp.com/', // Adjust based on actual referer
1279 ),
1280 'cookies' => array(),
1281 'sslverify' => false, // Disable SSL verification (for debugging purposes)
1282 );
1283
1284 // $request = wp_remote_request( $endpoint_url, $args );
1285
1286
1287 $berq_log->info('Making request 1');
1288
1289 $query_string = http_build_query($api_params);
1290 // $client = new HttpClient(BERQ_SERVER);
1291 // $client->setUserAgent('BerqWP');
1292 // $client->post('?' . $query_string, $api_params);
1293 // $client->setTimeout(30);
1294
1295 $client = new \BerqWP_Deps\GuzzleHttp\Client([
1296 'timeout' => 60,
1297 'http_errors' => false,
1298 'verify' => false,
1299 ]);
1300
1301 $response = $client->post(BERQ_SERVER . '?' . $query_string, [
1302 'form_params' => $api_params,
1303 ]);
1304 $statusCode = $response->getStatusCode();
1305 $response = $response->getBody()->getContents();
1306
1307 // var_dump($client->getContent(), $client->getError(), $api_params);
1308
1309 // $berq_log->info(print_r($client->getContent(), true).'---'.$client->ok());
1310
1311 if ($statusCode >= 200 && $statusCode < 300) {
1312 // $response = $client->getContent();
1313 $JSON = json_decode($response);
1314
1315 if ($action == 'slm_activate' && isset($JSON->error_code) && $JSON->message !== 'Invalid license key') {
1316 sleep(1);
1317 $api_params = array(
1318 'registered_domain' => $domain,
1319 'slm_action' => 'slm_check',
1320 'secret_key' => BERQ_SECRET,
1321 'license_key' => $license_key,
1322 't' => '',
1323 );
1324
1325 $berq_log->info('Making request 2');
1326
1327 $query_string = http_build_query($api_params);
1328 // $client = new HttpClient(BERQ_SERVER);
1329 // $client->setUserAgent('BerqWP');
1330 // $client->post('?' . $query_string, $api_params);
1331
1332
1333 // if ($client->ok()) {
1334 // $response = $client->getContent();
1335 // }
1336
1337 $response = $client->post(BERQ_SERVER . '?' . $query_string, [
1338 'form_params' => $api_params,
1339 ]);
1340
1341 $response = $response->getBody()->getContents();
1342 }
1343 }
1344
1345 if ($action !== 'slm_check') {
1346 $api_params = array(
1347 'registered_domain' => $domain,
1348 'slm_action' => 'slm_check',
1349 'secret_key' => BERQ_SECRET,
1350 'license_key' => $license_key,
1351 'version' => BERQWP_VERSION,
1352 't' => '',
1353 );
1354
1355 $berq_log->info('Making request 3');
1356
1357 $query_string = http_build_query($api_params);
1358 // $client = new HttpClient(BERQ_SERVER);
1359 // $client->setUserAgent('BerqWP');
1360 // $client->post('?' . $query_string, $api_params);
1361
1362
1363 // if ($client->ok()) {
1364 // $response = $client->getContent();
1365 // }
1366
1367 $response = $client->post(BERQ_SERVER . '?' . $query_string, [
1368 'form_params' => $api_params,
1369 ]);
1370
1371 $response = $response->getBody()->getContents();
1372 }
1373
1374 if (empty($response)) {
1375 return;
1376 }
1377
1378 $cached_response = json_decode($response);
1379
1380
1381 if ($action == 'slm_check' && !empty($cached_response) && !empty($cached_response->result)) {
1382 $domain_found = false;
1383
1384 foreach ($cached_response->registered_domains as $reg_domain) {
1385 $domain_name = str_replace('www.', '', $domain);
1386 $domain_name_www = 'www.' . $domain;
1387
1388 if ($reg_domain->registered_domain == $domain_name || $reg_domain->registered_domain == $domain_name_www || $reg_domain->registered_domain == $domain) {
1389 $domain_found = true;
1390 break;
1391 }
1392 }
1393
1394 if ($domain_found) {
1395 // Cache the response for 24 hours
1396 // set_transient($transient_key, $cached_response, 24 * HOUR_IN_SECONDS);
1397 berqwp_update_network_option($transient_key, $cached_response);
1398 berqwp_update_network_option($expire_transient_key, time() + MONTH_IN_SECONDS);
1399 } else {
1400
1401 berqwp_delete_network_option($transient_key);
1402 berqwp_delete_network_option($expire_transient_key);
1403 berqwp_delete_license_key();
1404
1405 return false;
1406 }
1407 }
1408
1409 // if ($action == 'slm_check' && !empty($cached_response) && $cached_response->result == 'success' && $cached_response->status == 'active') {
1410 // // Cache the response for 24 hours
1411 // set_transient($transient_key, $cached_response, 24 * HOUR_IN_SECONDS);
1412 // }
1413
1414 // if ($action == 'slm_check' && !empty($cached_response) && $cached_response->result == 'error') {
1415 // // Key verification failed, cache the response for 14 hours
1416 // // preventing unnecessary verification requests
1417 // set_transient($transient_key, $cached_response, 14 * HOUR_IN_SECONDS);
1418 // }
1419
1420 } else {
1421 // $berq_log->info('Delivering license key object from the transient cache.');
1422 }
1423
1424 // Return the cached response
1425 return $cached_response;
1426 }
1427
1428 // Disable emoji functionality
1429 function disable_emoji()
1430 {
1431 // Remove emoji-related actions and filters
1432 remove_action('wp_head', 'print_emoji_detection_script', 7);
1433 remove_action('admin_print_scripts', 'print_emoji_detection_script');
1434 remove_action('wp_print_styles', 'print_emoji_styles');
1435 remove_action('admin_print_styles', 'print_emoji_styles');
1436 remove_filter('the_content_feed', 'wp_staticize_emoji');
1437 remove_filter('comment_text_rss', 'wp_staticize_emoji');
1438 remove_filter('wp_mail', 'wp_staticize_emoji_for_email');
1439
1440 // Remove emoji-related TinyMCE plugins
1441 add_filter('tiny_mce_plugins', [$this, 'disable_emoji_tinymce']);
1442 }
1443
1444 // Filter function to disable emoji-related TinyMCE plugins
1445 function disable_emoji_tinymce($plugins)
1446 {
1447 if (is_array($plugins)) {
1448 return array_diff($plugins, array('wpemoji'));
1449 } else {
1450 return array();
1451 }
1452 }
1453
1454 // function clear_cache(WP_REST_Request $request)
1455 // {
1456 // require_once optifer_PATH . 'api/clear_cache.php';
1457 // }
1458
1459 // function warmup_cache(WP_REST_Request $request)
1460 // {
1461 // require_once optifer_PATH . 'api/warmup_cache.php';
1462 // }
1463
1464 // function store_cache(WP_REST_Request $request)
1465 // {
1466 // require_once optifer_PATH . 'api/store_cache.php';
1467 // }
1468
1469 // function store_javascript_cache(WP_REST_Request $request)
1470 // {
1471 // require_once optifer_PATH . 'api/store_javascript_cache.php';
1472 // }
1473
1474 // ==========================================
1475 // Multisite Network Support
1476 // ==========================================
1477
1478 function register_network_menu()
1479 {
1480 $svg = '<svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
1481 <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"/>
1482 </svg>';
1483
1484 $plugin_name = defined('BERQWP_PLUGIN_NAME') ? BERQWP_PLUGIN_NAME : 'BerqWP';
1485
1486 add_menu_page(
1487 $plugin_name . ' Network',
1488 $plugin_name,
1489 'manage_network_options',
1490 'berqwp-network',
1491 [$this, 'network_admin_page'],
1492 'data:image/svg+xml;base64,' . base64_encode($svg),
1493 10
1494 );
1495 }
1496
1497 function network_admin_page()
1498 {
1499 require_once optifer_PATH . 'admin/network-admin-page.php';
1500 }
1501
1502 function save_network_settings()
1503 {
1504 check_admin_referer('berqwp_network_save');
1505
1506 if (!current_user_can('manage_network_options')) {
1507 wp_die('Unauthorized');
1508 }
1509
1510 // License activation
1511 if (!empty($_POST['berqwp_license_key'])) {
1512 $key = sanitize_text_field($_POST['berqwp_license_key']);
1513 // $key_response = $this->verify_license_key($key, 'slm_activate');
1514 $key_response = $this->authenticate_license($key);
1515 if (!empty($key_response) && isset($key_response->result) && $key_response->result == 'success') {
1516 berqwp_update_license_key($key);
1517 }
1518 }
1519
1520 // License deactivation
1521 if (!empty($_POST['berq_deactivate_key'])) {
1522 $existing_key = berqwp_get_license_key();
1523 if (!empty($existing_key)) {
1524 $this->verify_license_key($existing_key, 'slm_deactivate');
1525 }
1526 berqwp_delete_license_key();
1527 berqwp_delete_network_option('berq_lic_response_cache');
1528 berqwp_delete_network_option('berq_lic_cache_expire');
1529 berqwp_delete_network_option('berqwp_lic_response_cache');
1530 berqwp_delete_network_option('berqwp_lic_cache_expire');
1531 }
1532
1533 // Flush all sites cache
1534 if (!empty($_POST['berqwp_flush_all_cache'])) {
1535 $cache_directory = WP_CONTENT_DIR . '/cache/berqwp/html/';
1536 if (is_dir($cache_directory)) {
1537 berqwp_unlink_recursive($cache_directory);
1538 }
1539 }
1540
1541 wp_safe_redirect(network_admin_url('admin.php?page=berqwp-network&updated=true'));
1542 exit;
1543 }
1544
1545 function regenerate_blog_map()
1546 {
1547 if (!function_exists('is_multisite') || !is_multisite()) {
1548 return;
1549 }
1550
1551 $sites = get_sites(['fields' => 'ids', 'number' => 0]);
1552 $map = [
1553 'subdomains' => [],
1554 'subdirs' => [],
1555 ];
1556
1557 $is_subdomain = defined('SUBDOMAIN_INSTALL') && SUBDOMAIN_INSTALL;
1558
1559 foreach ($sites as $site_id) {
1560 $site = get_site($site_id);
1561 if (!$site) continue;
1562
1563 if ($is_subdomain) {
1564 $map['subdomains'][strtolower($site->domain)] = (int) $site_id;
1565 } else {
1566 $path = rtrim($site->path, '/') . '/';
1567 if ($path !== '/') {
1568 $map['subdirs'][$path] = (int) $site_id;
1569 }
1570 }
1571 }
1572
1573 $map_file = WP_CONTENT_DIR . '/cache/berqwp/blog-map.json';
1574 $map_dir = dirname($map_file);
1575 if (!is_dir($map_dir)) {
1576 wp_mkdir_p($map_dir);
1577 }
1578 file_put_contents($map_file, json_encode($map, JSON_PRETTY_PRINT));
1579 }
1580
1581 function on_new_site_created($new_site)
1582 {
1583 if (function_exists('is_plugin_active_for_network') && is_plugin_active_for_network('searchpro/berqwp.php')) {
1584 switch_to_blog($new_site->blog_id);
1585 berqwp_activate_single_site();
1586 restore_current_blog();
1587 }
1588 $this->regenerate_blog_map();
1589 }
1590
1591 function register_menu()
1592 {
1593 $svg = '<svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
1594 <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"/>
1595 </svg>';
1596
1597 $plugin_name = defined('BERQWP_PLUGIN_NAME') ? BERQWP_PLUGIN_NAME : 'BerqWP';
1598
1599 add_menu_page($plugin_name, $plugin_name, 'manage_options', 'berqwp', [$this, 'admin_page'], 'data:image/svg+xml;base64,' . base64_encode($svg), 10);
1600 }
1601
1602 function admin_page()
1603 {
1604
1605 $berqconfigs = berqConfigs::getInstance();
1606 $configs = $berqconfigs->get_configs();
1607
1608 if (!empty($configs['optimization_method'])) {
1609 require_once optifer_PATH . 'admin/admin-page.php';
1610 } else {
1611 require_once optifer_PATH . 'admin/intro-page.php';
1612 }
1613 }
1614 }
1615
1616 berqWP::getInstance();
1617 // global $berqWP;
1618 // $berqWP = new berqWP();
1619 }
1620