PluginProbe
BerqWP – All-In-One Optimization for Core Web Vitals, Cache, CDN, Images, CSS & JavaScript / 1.9.3
BerqWP – All-In-One Optimization for Core Web Vitals, Cache, CDN, Images, CSS & JavaScript v1.9.3
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 / helper-functions.php

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

772 lines 25.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if (!defined('ABSPATH'))
3 exit;
4
5
6 function berqwp_is_slug_excludable($slug)
7 {
8 if (empty($slug)) {
9 return true;
10 }
11
12 $exclude_items = ["elementor_library=", "add_to_wishlist=", "robots.txt", ".html", ".php", "run_warmup=", "et-compare-page=", "add_to_compare=", "min_price=", "max_price=", "view_mode=", "view_mode_smart=", "et_columns-count=", "add_to_wishlist=", "et-wishlist-page=", "remove_wishlist=", "stock_status=", "page_id=", "?p="];
13
14 $exclude_items = apply_filters('berqwp_exclude_slug_match', $exclude_items);
15
16 foreach ($exclude_items as $item) {
17 if (strpos($slug, $item) !== false) {
18 return true;
19 }
20 }
21
22 return false;
23 }
24
25 function berqwp_get_page_params($slug, $is_forced = false) {
26 if (empty($slug)) {
27 return;
28 }
29
30 $url = home_url() . $slug;
31 $slug_md5 = md5($slug);
32
33 $cache_directory = optifer_cache . '/html/';
34 $cache_file = $cache_directory . $slug_md5 . '.html';
35 $key = uniqid();
36 $cache_max_life = @filemtime($cache_file) + (18 * 60 * 60);
37
38 if (!file_exists($cache_file) || (file_exists($cache_file) && $cache_max_life < time()) || (file_exists($cache_file) && bwp_is_partial_cache($slug) === true)) {
39 // Priority 1
40 $key = '';
41 }
42
43 $optimization_mode = get_option('berq_opt_mode');
44
45 if ($optimization_mode == 4) {
46 $optimization_mode = 'aggressive';
47 } elseif ($optimization_mode == 3) {
48 $optimization_mode = 'blaze';
49 } elseif ($optimization_mode == 2) {
50 $optimization_mode = 'medium';
51 } elseif ($optimization_mode == 1) {
52 $optimization_mode = 'basic';
53 }
54
55 // Data to send as POST parameters
56 $post_data = array(
57 'license_key' => get_option('berqwp_license_key'),
58 'page_url' => $url,
59 'page_slug' => $slug,
60 'site_url' => home_url(),
61 'webp_max_width' => (int) get_option('berqwp_webp_max_width'),
62 'webp_quality' => (int) get_option('berqwp_webp_quality'),
63 'img_lazyloading' => get_option('berqwp_image_lazyloading'),
64 'youtube_lazyloading' => get_option('berqwp_lazyload_youtube_embed'),
65 'js_mode' => get_option('berqwp_javascript_execution_mode'),
66 'key' => $key,
67 'interaction_delay' => get_option('berqwp_interaction_delay'),
68 'cache_js' => true,
69 'use_cdn' => get_option('berqwp_enable_cdn'),
70 'opt_mode' => $optimization_mode,
71 'disable_webp' => get_option('berqwp_disable_webp'),
72 'js_css_exclude_urls' => get_option('berq_exclude_js_css', []),
73 'preload_fontfaces' => get_option('berqwp_preload_fontfaces'),
74 // 'mobile_lcp' => json_encode($mobile_lcp),
75 // 'desktop_lcp' => json_encode($desktop_lcp),
76 'version' => BERQWP_VERSION
77 );
78
79 if (defined('BERQ_STAGING') || $is_forced) {
80 $post_data['run_queue'] = 1;
81 $post_data['doing_queue'] = true;
82 }
83
84 return $post_data;
85
86
87 }
88
89 function bwp_pass_account_requirement() {
90 global $berqWP, $berq_log;
91
92 $license_key = get_option('berqwp_license_key');
93 $key_response = $berqWP->verify_license_key($license_key);
94
95 if ($key_response->result !== 'success' || $key_response->status !== 'active') {
96 $berq_log->error("account requirement: license verification failed");
97 return false;
98 }
99
100 if ($key_response->product_ref == 'Free Account' && bwp_cached_pages_count() >= 10) {
101 return false;
102 }
103
104 if ($key_response->product_ref == 'Starter' && bwp_cached_pages_count() >= 100) {
105 return false;
106 }
107
108 return true;
109 }
110
111 function warmup_cache_by_slug($slug, $is_forced = false)
112 {
113 if (empty($slug)) {
114 return;
115 }
116
117 if (berqwp_is_slug_excludable($slug)) {
118 return;
119 }
120
121 $slug_md5 = md5($slug);
122
123 $cache_directory = optifer_cache . '/html/';
124 $cache_file = $cache_directory . $slug_md5 . '.html';
125 $cache_max_life = @filemtime($cache_file) + (18 * 60 * 60);
126
127 if (!file_exists($cache_file) && bwp_pass_account_requirement() === false) {
128 return;
129 }
130
131 // Return if page is excluded from cache
132 $pages_to_exclude = get_option('berq_exclude_urls', []);
133
134 if (in_array(home_url() . $slug, $pages_to_exclude)) {
135 return;
136 }
137
138 $check_rest = bwp_check_rest_api(true);
139 if ( $check_rest['status'] == 'error' ) {
140 global $berq_log;
141 $berq_log->error('Exiting cache warmup by slug, rest api not working.');
142 return;
143 }
144
145 // Hook to modify cache lifespan
146 $cache_max_life = apply_filters('berqwp_cache_lifespan', $cache_max_life);
147
148 if (file_exists($cache_file) && bwp_is_partial_cache($slug) === false && $cache_max_life > time()) {
149 return;
150 }
151
152 // API endpoint URL
153 $api_endpoint = 'https://boost.berqwp.com/photon/';
154
155 if (get_site_url() == 'http://berq-test.local') {
156 $api_endpoint = 'http://dev-berqwp.local/photon/';
157 }
158
159 // Modify photon engine endpoint for testing purposes
160 $api_endpoint = apply_filters( 'berqwp_photon_endpoint', $api_endpoint );
161
162 $post_data = berqwp_get_page_params($slug, $is_forced);
163
164 // Set up the request arguments
165 $args = array(
166 'body' => $post_data, // Pass the POST data here
167 'method' => 'POST',
168 // 'blocking' => false,
169 'timeout' => $is_forced === true ? 20 : 0.1,
170 'headers' => array(
171 'Content-Type' => 'application/x-www-form-urlencoded', // Adjust content type if needed
172 ),
173 );
174
175 // Send the POST request
176 $response = wp_remote_post($api_endpoint, $args);
177
178 // Check for errors and handle the response
179 if (is_wp_error($response)) {
180 // There was an error with the request
181 error_log('Error: ' . $response->get_error_message());
182 }
183
184 }
185
186 function bwp_is_home_cached() {
187 $slug_md5 = md5('/');
188 $cache_directory = optifer_cache . '/html/';
189 $cache_file = $cache_directory . $slug_md5 . '.html';
190
191 return file_exists($cache_file);
192 }
193
194 function bwp_is_partial_cache($slug) {
195 require_once optifer_PATH . '/simplehtmldom/simple_html_dom.php';
196 $cache_directory = optifer_cache . '/html/';
197 $cache_key = md5($slug);
198 $cache_file = $cache_directory . $cache_key . '.html';
199
200 if (file_exists($cache_file)) {
201 $buffer = file_get_contents($cache_file);
202
203 if (!empty($buffer)) {
204 $html = str_get_html($buffer);
205 $style_tag = $html->find('style#berqwp-critical-css', 0);
206
207 if ($style_tag === null) {
208 return true;
209 }
210
211 }
212 }
213
214 return false;
215
216 }
217
218 function berq_is_localhost()
219 {
220 $whitelist = array('127.0.0.1', '::1');
221
222 if (in_array($_SERVER['REMOTE_ADDR'], $whitelist)) {
223 return true;
224 }
225
226 return false;
227 }
228
229 function berqwp_remove_ignore_params($slug)
230 {
231 // List of tracking parameters to remove
232 $tracking_params = get_option('berq_ignore_urls_params', []);
233
234 $tracking_params = apply_filters( 'berqwp_ignored_urls_params', $tracking_params );
235
236 // Parse the provided slug
237 $url_parts = parse_url($slug);
238
239 // Get the current URL parameters
240 $url_params = array();
241 if (isset($url_parts['query'])) {
242 parse_str($url_parts['query'], $url_params);
243 }
244
245 // Remove specified tracking parameters from the URL
246 foreach ($tracking_params as $param) {
247 $param = trim($param);
248 if (isset($url_params[$param])) {
249 unset($url_params[$param]);
250 }
251 }
252
253 // Build the new query string
254 $new_query_string = http_build_query($url_params);
255
256 // Reconstruct the URL with the new query string
257 $new_slug = $url_parts['path'];
258 if (!empty($new_query_string)) {
259 $new_slug .= '?' . $new_query_string;
260 }
261
262 return $new_slug;
263 }
264
265 function berqwp_is_sub_dir_wp()
266 {
267 // remove http
268 $site_url = explode('//', home_url())[1];
269 $break_slash = explode('/', $site_url);
270
271 return count($break_slash) > 1;
272 }
273
274 function berqwp_current_page_cache_file()
275 {
276 $slug_uri = $_SERVER['REQUEST_URI'];
277
278 // if wordpress is installed in a sub directory
279 if (berqwp_is_sub_dir_wp()) {
280 // Parse strings to extract paths
281 $path1 = explode('/', parse_url(home_url(), PHP_URL_PATH));
282 $path2 = explode('/', parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH));
283
284 // Find the common part of the paths
285 $commonPath = implode('/', array_intersect($path1, $path2));
286
287 // Subtract the common part from the first string
288 $slug_uri = str_replace($commonPath, '', $_SERVER['REQUEST_URI']);
289 }
290
291 // Return if page is excluded from cache
292 $pages_to_exclude = get_option('berq_exclude_urls', []);
293
294 if (in_array(get_site_url() . $slug_uri, $pages_to_exclude)) {
295 return;
296 }
297
298
299 $slug = berqwp_remove_ignore_params($slug_uri);
300
301 if (isset($_GET['creating_cache'])) {
302 return;
303 }
304
305 if (get_option('berqwp_enable_sandbox') == 1 && isset($_GET['berqwp'])) {
306 $slug = explode('?berqwp', $slug_uri)[0];
307 } elseif (get_option('berqwp_enable_sandbox') == 1 && !isset($_GET['creating_cache'])) {
308 return;
309 }
310
311
312 // Attempt to retrieve the cached HTML from the cache directory
313 $cache_directory = optifer_cache . '/html/';
314
315 // Generate a unique cache key based on the current page URL
316 $cache_key = md5($slug);
317 $cache_file = $cache_directory . $cache_key . '.html';
318
319 return $cache_file;
320
321 }
322
323 function berqwp_get_LCP_details($url, $device = 'mobile')
324 {
325 $google_pagespeed_api_url = "https://www.googleapis.com/pagespeedonline/v5/runPagespeed?url=$url&strategy=$device ";
326
327 // Send a GET request to the Google PageSpeed Insights API
328 // $response = wp_remote_get($google_pagespeed_api_url, array('timeout' => 60));
329 $response = bwp_wp_remote_get($google_pagespeed_api_url, array('timeout' => 60));
330
331 if (is_wp_error($response)) {
332 return 'Error: ' . $response->get_error_message();
333 }
334
335 // Convert the JSON response to a PHP array
336 $body = wp_remote_retrieve_body($response);
337 $output = json_decode($body, true);
338
339 // Get the LCP data
340 return $output['lighthouseResult']['audits']['largest-contentful-paint-element']['details']['items'][0]['items'][0]['node'];
341 }
342
343 function berqwp_enable_object_cache($enable) {
344 global $berq_log;
345 $berq_log->info("Updating wp-config.php");
346
347 // Specify the wp-config.php file path
348 $wp_config_file = ABSPATH . 'wp-config.php';
349
350 // Read the contents of wp-config.php
351 $wp_config_content = file_get_contents($wp_config_file);
352
353 // Find the position of the first PHP tag using a regular expression
354 preg_match('/<\?php/', $wp_config_content, $matches, PREG_OFFSET_CAPTURE);
355
356 // Check if the PHP opening tag exists
357 if (!empty($matches)) {
358 $first_php_comment_position = $matches[0][1] + 5; // Move past the length of '<?php'
359
360 // Check if the WP_CACHE definition exists in the file
361 if (strpos($wp_config_content, "define('WP_CACHE'") === false && strpos($wp_config_content, "define( 'WP_CACHE' ") === false) {
362 // If not, add the definition right after the opening PHP tag
363 $wp_config_content = substr_replace($wp_config_content, "\n"
364 . "// Enable or disable BerqWP object cache\n"
365 . "define('WP_CACHE', " . ($enable ? 'true' : 'false') . ");\n",
366 $first_php_comment_position, 0);
367 } else {
368 // Otherwise, enable or disable the existing definition
369 // $wp_config_content = preg_replace(
370 // "/define\('WP_CACHE', [^\n]*\);/",
371 // "define('WP_CACHE', " . ($enable ? 'true' : 'false') . ");",
372 // $wp_config_content
373 // );
374
375 $wp_config_content = preg_replace(
376 "/define\(\s*'WP_CACHE'\s*,\s*[^\n]*\);/",
377 "define('WP_CACHE', " . ($enable ? 'true' : 'false') . ");",
378 $wp_config_content
379 );
380 }
381
382 // Write the modified content back to wp-config.php
383 file_put_contents($wp_config_file, $wp_config_content);
384 } else {
385
386 global $berq_log;
387 $berq_log->error("Error: PHP opening tag not found in wp-config.php");
388
389 }
390 }
391
392 // Copied from Nginx Helper plugin
393 function berqwp_unlink_recursive( $dir ) {
394
395 if ( ! is_dir( $dir ) ) {
396 return;
397 }
398
399 $dh = opendir( $dir );
400
401 if ( ! $dh ) {
402 return;
403 }
404
405 // phpcs:ignore -- WordPress.CodeAnalysis.AssignmentInCondition.FoundInWhileCondition -- Variable assignment required for recursion.
406 while ( false !== ( $obj = readdir( $dh ) ) ) {
407
408 if ( '.' === $obj || '..' === $obj ) {
409 continue;
410 }
411
412 if ( ! @unlink( $dir . '/' . $obj ) ) { // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
413 berqwp_unlink_recursive( $dir . '/' . $obj, false );
414 }
415 }
416
417 closedir( $dh );
418 }
419
420 function berqwp_get_last_modified_timestamp() {
421 global $post;
422
423 // Check if it's a single post or page
424 if (is_singular()) {
425 return get_the_modified_time('U', $post->ID); // 'U' format parameter returns Unix timestamp
426 }
427
428 // Check if it's a taxonomy term
429 if (is_tax() || is_category() || is_tag()) {
430 $term = get_queried_object(); // Get the current term object
431
432 // For tags, get the last modified date of the most recent post associated with the tag
433 if (is_tag()) {
434 $args = array(
435 'tag_id' => $term->term_id,
436 'posts_per_page' => 1,
437 'orderby' => 'modified',
438 'order' => 'DESC',
439 'fields' => 'ids', // Return only post IDs to reduce overhead
440 );
441 $posts = get_posts($args);
442 if ($posts) {
443 $latest_post_id = $posts[0];
444 return get_the_modified_time('U', $latest_post_id); // 'U' format parameter returns Unix timestamp
445 }
446 }
447
448 // For category archives, get the last modified date of the most recent post within the category
449 if (is_category()) {
450 $args = array(
451 'category' => $term->term_id,
452 'posts_per_page' => 1,
453 'orderby' => 'modified',
454 'order' => 'DESC',
455 'fields' => 'ids', // Return only post IDs to reduce overhead
456 );
457 $posts = get_posts($args);
458 if ($posts) {
459 $latest_post_id = $posts[0];
460 return get_the_modified_time('U', $latest_post_id); // 'U' format parameter returns Unix timestamp
461 }
462 }
463
464 return strtotime($term->modified); // Convert modified date to timestamp
465 }
466
467 // Check if it's an archive
468 if (is_archive()) {
469 // For other archives
470 $archive_id = get_queried_object_id(); // Get the ID of the current archive
471 $archive = get_post($archive_id); // Get the archive post object
472 return strtotime($archive->post_modified); // Convert modified date to timestamp
473 }
474
475 // For other cases (fallback)
476 return false;
477 }
478
479 function bwp_is_gzip_supported() {
480 return function_exists('gzencode') && isset($_SERVER['HTTP_ACCEPT_ENCODING']) && strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== false;
481 }
482
483 function bwp_cached_pages_count() {
484 $cache_directory = optifer_cache . DIRECTORY_SEPARATOR . 'html';
485 $cache_files = glob($cache_directory . DIRECTORY_SEPARATOR . "*.html");
486 return count($cache_files);
487 }
488
489 function bwp_wp_remote_get($url, $args = array()) {
490 // Default arguments
491 $defaults = array(
492 'headers' => array(
493 'User-Agent' => 'BerqWP Bot', // Customize user agent if needed
494 ),
495 );
496
497 // Merge provided arguments with defaults
498 $args = wp_parse_args($args, $defaults);
499
500 if (empty($args['timeout'])) {
501 $args['timeout'] = 30;
502 }
503
504 // Initialize cURL session
505 $ch = curl_init();
506
507 // Set the URL
508 curl_setopt($ch, CURLOPT_URL, $url);
509
510 // Set to return the transfer as a string
511 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
512
513 // Set timeout in seconds
514 curl_setopt($ch, CURLOPT_TIMEOUT, $args['timeout']);
515
516 // Set the user-agent
517 curl_setopt($ch, CURLOPT_USERAGENT, $args['headers']['User-Agent']);
518
519 // Include header in the output
520 curl_setopt($ch, CURLOPT_HEADER, true);
521
522 // Execute the request
523 $response = curl_exec($ch);
524
525 // Check for errors
526 if (curl_errno($ch)) {
527 $error_message = curl_error($ch);
528 curl_close($ch);
529 return new WP_Error('curl_error', $error_message);
530 }
531
532 // Close cURL session
533 curl_close($ch);
534
535 // Separate headers and body
536 list($headers, $body) = explode("\r\n\r\n", $response, 2);
537
538 // Parse headers into array
539 $header_lines = explode("\r\n", $headers);
540 $headers = array();
541 foreach ($header_lines as $line) {
542 $parts = explode(':', $line, 2);
543 if (count($parts) == 2) {
544 $headers[trim($parts[0])] = trim($parts[1]);
545 }
546 }
547
548 // Construct response array similar to wp_remote_get
549 $response = array(
550 'headers' => $headers,
551 'body' => $body,
552 'response' => array(
553 'code' => curl_getinfo($ch, CURLINFO_HTTP_CODE),
554 'message' => curl_getinfo($ch, CURLINFO_HTTP_CODE),
555 ),
556 'cookies' => array(),
557 'filename' => '',
558 );
559
560 return $response;
561 }
562
563 function bwp_is_openlitespeed_server() {
564 return isset($_SERVER['SERVER_SOFTWARE']) && strpos($_SERVER['SERVER_SOFTWARE'], 'LiteSpeed') !== false;
565 }
566
567 function verify_request_origin($request) {
568 // Check the referrer header to ensure the request is coming from the same site
569 $referrer = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '';
570 $site_url = get_site_url();
571
572 // Optionally, check the origin header
573 $origin = isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : '';
574
575 // Ensure the request comes from the same site
576 if (strpos($referrer, $site_url) !== 0 && strpos($origin, $site_url) !== 0) {
577 return new WP_Error('rest_forbidden', esc_html__('You cannot access this resource.', 'searchpro'), array('status' => 403));
578 }
579
580 // Ensure the origin is a subdomain of berqwp.com
581 if (!preg_match('/^https?:\/\/([a-z0-9-]+\.)?berqwp\.com$/', $origin)) {
582 return new WP_Error('rest_forbidden', esc_html__('You cannot access this resource.', 'searchpro'), array('status' => 403));
583 }
584
585 return true;
586 }
587
588 function berq_rest_permission_callback(WP_REST_Request $request) {
589 // Get the nonce from the request
590 $nonce = $request->get_header('X-WP-Nonce');
591
592 // Verify the nonce
593 if (!wp_verify_nonce($nonce, 'wp_rest')) {
594 return new WP_Error('rest_invalid_nonce', __('Invalid nonce', 'searchpro'), array('status' => 403));
595 }
596
597 return true; // Return true to allow the request
598 }
599
600 function berq_rest_verify_license_callback(WP_REST_Request $request) {
601 $license_key_hash = sanitize_text_field($request->get_param('license_key_hash'));
602
603 if (empty($license_key_hash) || $license_key_hash !== md5(get_option('berqwp_license_key'))) {
604 global $berq_log;
605 $berq_log->error("Exiting... Invalid license key.");
606 return new WP_Error('rest_invalid_nonce', __('Invalid license key', 'searchpro'), array('status' => 403));
607
608 }
609
610 return true; // Return true to allow the request
611 }
612
613 function bwp_dash_notification($msg = '', $status = 'warning') {
614 ?>
615 <div class="berqwp-notification <?php echo esc_attr($status)?>">
616 <?php
617
618 echo "<div class='icon'>";
619 if ($status == 'warning') {
620 echo '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--!Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M256 32c14.2 0 27.3 7.5 34.5 19.8l216 368c7.3 12.4 7.3 27.7 .2 40.1S486.3 480 472 480L40 480c-14.3 0-27.6-7.7-34.7-20.1s-7-27.8 .2-40.1l216-368C228.7 39.5 241.8 32 256 32zm0 128c-13.3 0-24 10.7-24 24l0 112c0 13.3 10.7 24 24 24s24-10.7 24-24l0-112c0-13.3-10.7-24-24-24zm32 224a32 32 0 1 0 -64 0 32 32 0 1 0 64 0z"/></svg>';
621 } elseif ($status == 'error') {
622 echo '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--!Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M256 0c53 0 96 43 96 96l0 3.6c0 15.7-12.7 28.4-28.4 28.4l-135.1 0c-15.7 0-28.4-12.7-28.4-28.4l0-3.6c0-53 43-96 96-96zM41.4 105.4c12.5-12.5 32.8-12.5 45.3 0l64 64c.7 .7 1.3 1.4 1.9 2.1c14.2-7.3 30.4-11.4 47.5-11.4l112 0c17.1 0 33.2 4.1 47.5 11.4c.6-.7 1.2-1.4 1.9-2.1l64-64c12.5-12.5 32.8-12.5 45.3 0s12.5 32.8 0 45.3l-64 64c-.7 .7-1.4 1.3-2.1 1.9c6.2 12 10.1 25.3 11.1 39.5l64.3 0c17.7 0 32 14.3 32 32s-14.3 32-32 32l-64 0c0 24.6-5.5 47.8-15.4 68.6c2.2 1.3 4.2 2.9 6 4.8l64 64c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0l-63.1-63.1c-24.5 21.8-55.8 36.2-90.3 39.6L272 240c0-8.8-7.2-16-16-16s-16 7.2-16 16l0 239.2c-34.5-3.4-65.8-17.8-90.3-39.6L86.6 502.6c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3l64-64c1.9-1.9 3.9-3.4 6-4.8C101.5 367.8 96 344.6 96 320l-64 0c-17.7 0-32-14.3-32-32s14.3-32 32-32l64.3 0c1.1-14.1 5-27.5 11.1-39.5c-.7-.6-1.4-1.2-2.1-1.9l-64-64c-12.5-12.5-12.5-32.8 0-45.3z"/></svg>';
623 } elseif ($status == 'info') {
624 echo '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 512"><!--!Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M96 64c0-17.7-14.3-32-32-32S32 46.3 32 64l0 256c0 17.7 14.3 32 32 32s32-14.3 32-32L96 64zM64 480a40 40 0 1 0 0-80 40 40 0 1 0 0 80z"/></svg>';
625 } else {
626 return;
627 }
628 echo "</div>";
629 echo esc_html($msg);
630 ?>
631 </div>
632 <?php
633 }
634
635 function bwp_can_warmup_cache($slug) {
636
637 if (get_transient( 'bwp_warmup_lock_'.md5($slug) ) === false) {
638
639 set_transient( 'bwp_warmup_lock_'.md5($slug), true, 100 );
640 return true;
641
642 }
643
644 return false;
645 }
646
647 function bwp_clear_warmup_lock($slug) {
648 delete_transient( 'bwp_warmup_lock_'.md5($slug) );
649 }
650
651 function bwp_extractUrlsFromCss($cssContent) {
652 $urls = [];
653 $pattern = '/url\((.*?)\)/i';
654
655 preg_match_all($pattern, $cssContent, $matches);
656
657 if (!empty($matches[1])) {
658 foreach ($matches[1] as $match) {
659 // Trim any surrounding quotes and whitespace
660 $urls[] = trim($match, '\'" ');
661 }
662 }
663
664 return $urls;
665 }
666
667 function bwp_getBaseUrl($fileUrl) {
668 // Parse the URL and get its components
669 $parsedUrl = parse_url($fileUrl);
670 $scheme = isset($parsedUrl['scheme']) ? $parsedUrl['scheme'] . '://' : '';
671 $host = isset($parsedUrl['host']) ? $parsedUrl['host'] : '';
672 $path = isset($parsedUrl['path']) ? $parsedUrl['path'] : '';
673
674 // Remove the file name from the path to get the base URL
675 $basePath = preg_replace('/\/[^\/]+$/', '/', $path);
676
677 // Construct the base URL
678 return $scheme . $host . $basePath;
679 }
680
681 function bwp_rel2abs($rel, $base)
682 {
683 /* return if already absolute URL */
684 if (parse_url($rel, PHP_URL_SCHEME) != '') return $rel;
685
686 /* queries and anchors */
687 if ($rel[0]=='#' || $rel[0]=='?') return $base.$rel;
688
689 /* parse base URL and convert to local variables:
690 $scheme, $host, $path */
691 extract(parse_url($base));
692
693 /* remove non-directory element from path */
694 $path = preg_replace('#/[^/]*$#', '', $path);
695
696 /* destroy path if relative url points to root */
697 if ($rel[0] == '/') $path = '';
698
699 /* dirty absolute URL */
700 $abs = "$host$path/$rel";
701
702 /* replace '//' or '/./' or '/foo/../' with '/' */
703 $re = array('#(/\.?/)#', '#/(?!\.\.)[^/]+/\.\./#');
704 for($n=1; $n>0; $abs=preg_replace($re, '/', $abs, -1, $n)) {}
705
706 /* absolute URL is ready! */
707 return $scheme.'://'.$abs;
708 }
709
710 function update_image_url_extension($image_url, $file_extension) {
711 $url_arr = explode('.', $image_url);
712 $last_index = count($url_arr) - 1;
713
714 // Extract the file extension
715 $current_file_extension = pathinfo($image_url, PATHINFO_EXTENSION);
716
717 $url_arr[$last_index] = str_replace("$current_file_extension", $file_extension, $url_arr[$last_index]);
718 $new_image_url = implode('.', $url_arr);
719
720 return $new_image_url;
721
722 }
723
724 if (!function_exists('str_contains')) {
725 function str_contains(string $haystack, string $needle): bool {
726 return strpos($haystack, $needle) !== false;
727 }
728 }
729
730 function bwp_check_rest_api($force_check = false) {
731 // Allow cache busting by passing $force_check = true
732 if ($force_check) {
733 delete_transient('berqwp_rest_api_status');
734 }
735
736 // Check if the result is cached
737 $cached_status = get_transient('berqwp_rest_api_status');
738
739 if ($cached_status && !$force_check) {
740 return $cached_status;
741 }
742
743 // Perform the actual REST API check
744 $response = wp_safe_remote_get( rest_url(), ['timeout' => 10] );
745
746 if ( is_wp_error( $response ) ) {
747 $result = array(
748 'status' => 'error',
749 'message' => 'The REST API is not working. Error: ' . $response->get_error_message(),
750 );
751 } else {
752 $status_code = wp_remote_retrieve_response_code( $response );
753
754 if ( $status_code == 200 ) {
755 $result = array(
756 'status' => 'success',
757 'message' => 'The REST API is working correctly.',
758 );
759 } else {
760 $result = array(
761 'status' => 'error',
762 'message' => 'The REST API returned an unexpected status code: ' . $status_code,
763 );
764 }
765 }
766
767 set_transient('berqwp_rest_api_status', $result, 10 * MINUTE_IN_SECONDS);
768
769 return $result;
770 }
771
772