get_option('berqwp_license_key'), 'page_url' => $url, 'page_slug' => $slug, 'site_url' => home_url(), 'webp_max_width' => (int) get_option('berqwp_webp_max_width'), 'webp_quality' => (int) get_option('berqwp_webp_quality'), 'img_lazyloading' => get_option('berqwp_image_lazyloading'), 'youtube_lazyloading' => get_option('berqwp_lazyload_youtube_embed'), 'js_mode' => get_option('berqwp_javascript_execution_mode'), 'key' => $key, 'interaction_delay' => get_option('berqwp_interaction_delay'), 'cache_js' => true, 'use_cdn' => get_option('berqwp_enable_cdn'), 'opt_mode' => $optimization_mode, 'disable_webp' => get_option('berqwp_disable_webp'), 'js_css_exclude_urls' => get_option('berq_exclude_js_css', []), 'preload_fontfaces' => get_option('berqwp_preload_fontfaces'), // 'mobile_lcp' => json_encode($mobile_lcp), // 'desktop_lcp' => json_encode($desktop_lcp), 'version' => BERQWP_VERSION ); if (defined('BERQ_STAGING') || $is_forced) { $post_data['run_queue'] = 1; $post_data['doing_queue'] = true; } return $post_data; } function bwp_pass_account_requirement() { global $berqWP, $berq_log; $license_key = get_option('berqwp_license_key'); $key_response = $berqWP->verify_license_key($license_key); if (empty($key_response->product_ref)) { return false; } if ($key_response->result !== 'success' || $key_response->status !== 'active') { $berq_log->error("account requirement: license verification failed"); return false; } if ($key_response->product_ref == 'Free Account' && bwp_cached_pages_count() >= 10) { return false; } if ($key_response->product_ref == 'Starter' && bwp_cached_pages_count() >= 100) { return false; } return true; } function warmup_cache_by_slug($slug, $is_forced = false) { if (empty($slug)) { return; } if (berqwp_is_slug_excludable($slug)) { return; } $slug_md5 = md5($slug); $cache_directory = optifer_cache . '/html/'; $cache_file = $cache_directory . $slug_md5 . '.html'; $cache_max_life = @filemtime($cache_file) + (18 * 60 * 60); if (!file_exists($cache_file) && bwp_pass_account_requirement() === false) { return; } // Return if page is excluded from cache $pages_to_exclude = get_option('berq_exclude_urls', []); if (in_array(home_url() . $slug, $pages_to_exclude)) { return; } $check_rest = bwp_check_rest_api(true); if ( $check_rest['status'] == 'error' ) { global $berq_log; $berq_log->error('Exiting cache warmup by slug, rest api not working.'); return; } // Hook to modify cache lifespan $cache_max_life = apply_filters('berqwp_cache_lifespan', $cache_max_life); if (file_exists($cache_file) && bwp_is_partial_cache($slug) === false && $cache_max_life > time()) { return; } // API endpoint URL $api_endpoint = 'https://boost.berqwp.com/photon/'; if (get_site_url() == 'http://berq-test.local') { $api_endpoint = 'http://dev-berqwp.local/photon/'; } // Modify photon engine endpoint for testing purposes $api_endpoint = apply_filters( 'berqwp_photon_endpoint', $api_endpoint ); $post_data = berqwp_get_page_params($slug, $is_forced); // Set up the request arguments $args = array( 'body' => $post_data, // Pass the POST data here 'method' => 'POST', // 'blocking' => false, 'timeout' => $is_forced === true ? 20 : 0.1, 'headers' => array( 'Content-Type' => 'application/x-www-form-urlencoded', // Adjust content type if needed ), ); // Send the POST request $response = wp_remote_post($api_endpoint, $args); // Check for errors and handle the response if (is_wp_error($response)) { // There was an error with the request error_log('Error: ' . $response->get_error_message()); } } function bwp_is_home_cached() { $slug_md5 = md5('/'); $cache_directory = optifer_cache . '/html/'; $cache_file = $cache_directory . $slug_md5 . '.html'; return file_exists($cache_file); } function bwp_is_partial_cache($slug) { if (!function_exists('str_get_html')) { require_once optifer_PATH . '/simplehtmldom/simple_html_dom.php'; } $cache_directory = optifer_cache . '/html/'; $cache_key = md5($slug); $cache_file = $cache_directory . $cache_key . '.html'; if (file_exists($cache_file)) { $buffer = file_get_contents($cache_file); if (!empty($buffer)) { $html = str_get_html($buffer); if ($html !== false) { $style_tag = $html->find('style#berqwp-critical-css', 0); if ($style_tag === null) { return true; } } } } return false; } function berq_is_localhost() { $whitelist = array('127.0.0.1', '::1'); if (in_array($_SERVER['REMOTE_ADDR'], $whitelist)) { return true; } return false; } function berqwp_remove_ignore_params($slug) { // List of tracking parameters to remove $tracking_params = get_option('berq_ignore_urls_params', []); $tracking_params = apply_filters( 'berqwp_ignored_urls_params', $tracking_params ); // Parse the provided slug $url_parts = parse_url($slug); // Get the current URL parameters $url_params = array(); if (isset($url_parts['query'])) { parse_str($url_parts['query'], $url_params); } // Remove specified tracking parameters from the URL foreach ($tracking_params as $param) { $param = trim($param); if (isset($url_params[$param])) { unset($url_params[$param]); } } // Build the new query string $new_query_string = http_build_query($url_params); // Reconstruct the URL with the new query string $new_slug = $url_parts['path']; if (!empty($new_query_string)) { $new_slug .= '?' . $new_query_string; } return $new_slug; } function berqwp_is_sub_dir_wp() { // remove http $site_url = explode('//', home_url())[1]; $break_slash = explode('/', $site_url); return count($break_slash) > 1; } function berqwp_current_page_cache_file() { $slug_uri = $_SERVER['REQUEST_URI']; // if wordpress is installed in a sub directory if (berqwp_is_sub_dir_wp()) { // Parse strings to extract paths $path1 = explode('/', parse_url(home_url(), PHP_URL_PATH)); $path2 = explode('/', parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH)); // Find the common part of the paths $commonPath = implode('/', array_intersect($path1, $path2)); // Subtract the common part from the first string $slug_uri = str_replace($commonPath, '', $_SERVER['REQUEST_URI']); } // Return if page is excluded from cache $pages_to_exclude = get_option('berq_exclude_urls', []); if (in_array(get_site_url() . $slug_uri, $pages_to_exclude)) { return; } $slug = berqwp_remove_ignore_params($slug_uri); if (isset($_GET['creating_cache'])) { return; } if (get_option('berqwp_enable_sandbox') == 1 && isset($_GET['berqwp'])) { $slug = explode('?berqwp', $slug_uri)[0]; } elseif (get_option('berqwp_enable_sandbox') == 1 && !isset($_GET['creating_cache'])) { return; } // Attempt to retrieve the cached HTML from the cache directory $cache_directory = optifer_cache . '/html/'; // Generate a unique cache key based on the current page URL $cache_key = md5($slug); $cache_file = $cache_directory . $cache_key . '.html'; return $cache_file; } function berqwp_get_LCP_details($url, $device = 'mobile') { $google_pagespeed_api_url = "https://www.googleapis.com/pagespeedonline/v5/runPagespeed?url=$url&strategy=$device "; // Send a GET request to the Google PageSpeed Insights API // $response = wp_remote_get($google_pagespeed_api_url, array('timeout' => 60)); $response = bwp_wp_remote_get($google_pagespeed_api_url, array('timeout' => 60)); if (is_wp_error($response)) { return 'Error: ' . $response->get_error_message(); } // Convert the JSON response to a PHP array $body = wp_remote_retrieve_body($response); $output = json_decode($body, true); // Get the LCP data return $output['lighthouseResult']['audits']['largest-contentful-paint-element']['details']['items'][0]['items'][0]['node']; } function berqwp_enable_object_cache($enable) { global $berq_log; $berq_log->info("Updating wp-config.php"); // Specify the wp-config.php file path $wp_config_file = ABSPATH . 'wp-config.php'; // Read the contents of wp-config.php $wp_config_content = file_get_contents($wp_config_file); // Find the position of the first PHP tag using a regular expression preg_match('/<\?php/', $wp_config_content, $matches, PREG_OFFSET_CAPTURE); // Check if the PHP opening tag exists if (!empty($matches)) { $first_php_comment_position = $matches[0][1] + 5; // Move past the length of 'error("Error: PHP opening tag not found in wp-config.php"); } } // Copied from Nginx Helper plugin function berqwp_unlink_recursive( $dir ) { if ( ! is_dir( $dir ) ) { return; } $dh = opendir( $dir ); if ( ! $dh ) { return; } // phpcs:ignore -- WordPress.CodeAnalysis.AssignmentInCondition.FoundInWhileCondition -- Variable assignment required for recursion. while ( false !== ( $obj = readdir( $dh ) ) ) { if ( '.' === $obj || '..' === $obj ) { continue; } if ( ! @unlink( $dir . '/' . $obj ) ) { // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged berqwp_unlink_recursive( $dir . '/' . $obj, false ); } } closedir( $dh ); } function berqwp_get_last_modified_timestamp() { global $post; // Check if it's a single post or page if (is_singular()) { return get_the_modified_time('U', $post->ID); // 'U' format parameter returns Unix timestamp } // Check if it's a taxonomy term if (is_tax() || is_category() || is_tag()) { $term = get_queried_object(); // Get the current term object // For tags, get the last modified date of the most recent post associated with the tag if (is_tag()) { $args = array( 'tag_id' => $term->term_id, 'posts_per_page' => 1, 'orderby' => 'modified', 'order' => 'DESC', 'fields' => 'ids', // Return only post IDs to reduce overhead ); $posts = get_posts($args); if ($posts) { $latest_post_id = $posts[0]; return get_the_modified_time('U', $latest_post_id); // 'U' format parameter returns Unix timestamp } } // For category archives, get the last modified date of the most recent post within the category if (is_category()) { $args = array( 'category' => $term->term_id, 'posts_per_page' => 1, 'orderby' => 'modified', 'order' => 'DESC', 'fields' => 'ids', // Return only post IDs to reduce overhead ); $posts = get_posts($args); if ($posts) { $latest_post_id = $posts[0]; return get_the_modified_time('U', $latest_post_id); // 'U' format parameter returns Unix timestamp } } return strtotime($term->modified); // Convert modified date to timestamp } // Check if it's an archive if (is_archive()) { // For other archives $archive_id = get_queried_object_id(); // Get the ID of the current archive $archive = get_post($archive_id); // Get the archive post object return strtotime($archive->post_modified); // Convert modified date to timestamp } // For other cases (fallback) return false; } function bwp_is_gzip_supported() { return function_exists('gzencode') && isset($_SERVER['HTTP_ACCEPT_ENCODING']) && strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== false; } function bwp_cached_pages_count() { $cache_directory = optifer_cache . DIRECTORY_SEPARATOR . 'html'; $cache_files = glob($cache_directory . DIRECTORY_SEPARATOR . "*.html"); return count($cache_files); } function bwp_wp_remote_get($url, $args = array()) { // Default arguments $defaults = array( 'headers' => array( 'User-Agent' => 'BerqWP Bot', // Customize user agent if needed ), ); // Merge provided arguments with defaults $args = wp_parse_args($args, $defaults); if (empty($args['timeout'])) { $args['timeout'] = 30; } // Initialize cURL session $ch = curl_init(); // Set the URL curl_setopt($ch, CURLOPT_URL, $url); // Set to return the transfer as a string curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // Set timeout in seconds curl_setopt($ch, CURLOPT_TIMEOUT, $args['timeout']); // Set the user-agent curl_setopt($ch, CURLOPT_USERAGENT, $args['headers']['User-Agent']); // Include header in the output curl_setopt($ch, CURLOPT_HEADER, true); // Execute the request $response = curl_exec($ch); // Check for errors if (curl_errno($ch)) { $error_message = curl_error($ch); curl_close($ch); return new WP_Error('curl_error', $error_message); } // Close cURL session curl_close($ch); // Separate headers and body list($headers, $body) = explode("\r\n\r\n", $response, 2); // Parse headers into array $header_lines = explode("\r\n", $headers); $headers = array(); foreach ($header_lines as $line) { $parts = explode(':', $line, 2); if (count($parts) == 2) { $headers[trim($parts[0])] = trim($parts[1]); } } // Construct response array similar to wp_remote_get $response = array( 'headers' => $headers, 'body' => $body, 'response' => array( 'code' => curl_getinfo($ch, CURLINFO_HTTP_CODE), 'message' => curl_getinfo($ch, CURLINFO_HTTP_CODE), ), 'cookies' => array(), 'filename' => '', ); return $response; } function bwp_is_openlitespeed_server() { return isset($_SERVER['SERVER_SOFTWARE']) && strpos($_SERVER['SERVER_SOFTWARE'], 'LiteSpeed') !== false; } function verify_request_origin($request) { // Check the referrer header to ensure the request is coming from the same site $referrer = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : ''; $site_url = get_site_url(); // Optionally, check the origin header $origin = isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : ''; // Ensure the request comes from the same site if (strpos($referrer, $site_url) !== 0 && strpos($origin, $site_url) !== 0) { return new WP_Error('rest_forbidden', esc_html__('You cannot access this resource.', 'searchpro'), array('status' => 403)); } // Ensure the origin is a subdomain of berqwp.com if (!preg_match('/^https?:\/\/([a-z0-9-]+\.)?berqwp\.com$/', $origin)) { return new WP_Error('rest_forbidden', esc_html__('You cannot access this resource.', 'searchpro'), array('status' => 403)); } return true; } function berq_rest_permission_callback(WP_REST_Request $request) { // Get the nonce from the request $nonce = $request->get_header('X-WP-Nonce'); // Verify the nonce if (!wp_verify_nonce($nonce, 'wp_rest')) { return new WP_Error('rest_invalid_nonce', __('Invalid nonce', 'searchpro'), array('status' => 403)); } return true; // Return true to allow the request } function berq_rest_verify_license_callback(WP_REST_Request $request) { $license_key_hash = sanitize_text_field($request->get_param('license_key_hash')); if (empty($license_key_hash) || $license_key_hash !== md5(get_option('berqwp_license_key'))) { global $berq_log; $berq_log->error("Exiting... Invalid license key."); return new WP_Error('rest_invalid_nonce', __('Invalid license key', 'searchpro'), array('status' => 403)); } return true; // Return true to allow the request } function bwp_dash_notification($msg = '', $status = 'warning') { ?>
"; if ($status == 'warning') { echo ''; } elseif ($status == 'error') { echo ''; } elseif ($status == 'info') { echo ''; } else { return; } echo "
"; echo esc_html($msg); ?> 0; $abs=preg_replace($re, '/', $abs, -1, $n)) {} /* absolute URL is ready! */ return $scheme.'://'.$abs; } function update_image_url_extension($image_url, $file_extension) { $url_arr = explode('.', $image_url); $last_index = count($url_arr) - 1; // Extract the file extension $current_file_extension = pathinfo($image_url, PATHINFO_EXTENSION); $url_arr[$last_index] = str_replace("$current_file_extension", $file_extension, $url_arr[$last_index]); $new_image_url = implode('.', $url_arr); return $new_image_url; } if (!function_exists('str_contains')) { function str_contains(string $haystack, string $needle): bool { return strpos($haystack, $needle) !== false; } } function bwp_check_rest_api($force_check = false) { // Allow cache busting by passing $force_check = true if ($force_check) { delete_transient('berqwp_rest_api_status'); } // Check if the result is cached $cached_status = get_transient('berqwp_rest_api_status'); if ($cached_status && !$force_check) { return $cached_status; } // Perform the actual REST API check $response = wp_safe_remote_get( rest_url(), ['timeout' => 10] ); if ( is_wp_error( $response ) ) { $result = array( 'status' => 'error', 'message' => 'The REST API is not working. Error: ' . $response->get_error_message(), ); } else { $status_code = wp_remote_retrieve_response_code( $response ); if ( $status_code == 200 ) { $result = array( 'status' => 'success', 'message' => 'The REST API is working correctly.', ); } else { $result = array( 'status' => 'error', 'message' => 'The REST API returned an unexpected status code: ' . $status_code, ); } } set_transient('berqwp_rest_api_status', $result, 60 * 60 * 24); return $result; } function bwp_sendPostRequestInBackground($url, $params) { $userAgent = 'BerqWP'; $urlParts = parse_url($url); // Ensure we have a valid path and handle query strings $path = isset($urlParts['path']) ? $urlParts['path'] : '/'; if (isset($urlParts['query'])) { $path .= '?' . $urlParts['query']; } $postString = http_build_query($params); $host = $urlParts['host']; $scheme = isset($urlParts['scheme']) ? $urlParts['scheme'] : 'http'; $port = ($scheme === 'https') ? 443 : 80; $transport = ($scheme === 'https') ? 'ssl://' : ''; $request = "POST $path HTTP/1.1\r\n"; $request .= "Host: $host\r\n"; $request .= "User-Agent: $userAgent\r\n"; $request .= "Content-Type: application/x-www-form-urlencoded\r\n"; $request .= "Content-Length: " . strlen($postString) . "\r\n"; $request .= "Connection: Close\r\n\r\n"; $request .= $postString; $fp = fsockopen($transport . $host, $port, $errno, $errstr, 30); if ($fp) { fwrite($fp, $request); fclose($fp); // Close immediately to prevent waiting for the response } else { // If fsockopen fails, fallback to wp_remote_post $args = array( 'timeout' => 0.01, 'headers' => array( 'User-Agent' => $userAgent, ), 'body' => $params ); wp_remote_post($url, $args); } } function bwp_is_webpage() { $headers = headers_list(); $contentType = ''; foreach ($headers as $header) { if (stripos($header, 'Content-Type') !== false) { $contentType = $header; break; } } if (stripos($contentType, 'text/html') !== false) { return true; } return false; }