| @@ -1,8 +1,8 @@ | ||
| 1 | 1 | <?php |
| 2 | 2 | |
| 3 | 3 | use BerqWP\BerqWP; |
| 4 | -use voku\helper\HtmlDomParser; | |
| 4 | +use BerqWP_Deps\voku\helper\HtmlDomParser; | |
| 5 | 5 | |
| 6 | 6 | if (!defined('ABSPATH')) |
| 7 | 7 | exit; |
| 8 | 8 | |
| @@ -82,9 +82,8 @@ | ||
| 82 | 82 | } |
| 83 | 83 | |
| 84 | 84 | function berqwp_activate_single_site() { |
| 85 | 85 | if (empty(berqwp_get_license_key())) { |
| 86 | - set_transient('bqwp_hide_feedback_notice', true, 60 * 60); | |
| 87 | 86 | set_transient('berqwp_redirect', true, 1); |
| 88 | 87 | } |
| 89 | 88 | update_option('berqwp_sync_addons', true); |
| 90 | 89 | do_action('berqwp_activate_plugin'); |
| @@ -225,8 +224,9 @@ | ||
| 225 | 224 | "/embed", |
| 226 | 225 | "/view-order/", |
| 227 | 226 | "/redirect/", |
| 228 | 227 | "/elementskit-content/", |
| 228 | + "/checkout/", | |
| 229 | 229 | ]; |
| 230 | 230 | |
| 231 | 231 | $exclude_items = apply_filters('berqwp_exclude_slug_match', $exclude_items); |
| 232 | 232 | |
| @@ -490,9 +490,9 @@ | ||
| 490 | 490 | if (file_exists($cache_file)) { |
| 491 | 491 | $buffer = file_get_contents($cache_file); |
| 492 | 492 | |
| 493 | 493 | if (!empty($buffer)) { |
| 494 | - $html = berqwp_str_get_html($buffer); | |
| 494 | + $html = HtmlDomParser::str_get_html($buffer); | |
| 495 | 495 | |
| 496 | 496 | if ($html !== false) { |
| 497 | 497 | $style_tag = $html->find('style#berqwp-critical-css', 0); |
| 498 | 498 | |
| @@ -1480,8 +1480,9 @@ | ||
| 1480 | 1480 | |
| 1481 | 1481 | $berqconfigs = berqConfigs::getInstance(); |
| 1482 | 1482 | $configs = $berqconfigs->get_configs(); |
| 1483 | 1483 | $post_params['cache_lifespan'] = $configs['cache_lifespan']; |
| 1484 | + $post_params['sandbox'] = get_option('berqwp_enable_sandbox'); | |
| 1484 | 1485 | |
| 1485 | 1486 | if ($query->have_posts()) { |
| 1486 | 1487 | $sitemap_urls = []; |
| 1487 | 1488 | |
| @@ -1504,8 +1505,24 @@ | ||
| 1504 | 1505 | $post_name = get_post_field( 'post_name', $post_id ); |
| 1505 | 1506 | $url = trailingslashit( home_url( '/' . $rewrite_map[ $post_type ] . '/' . $post_name ) ); |
| 1506 | 1507 | } |
| 1507 | 1508 | |
| 1509 | + // SEO Generator | |
| 1510 | + if (class_exists('NSG_Seo_Generator')) { | |
| 1511 | + $nsg = NSG_Seo_Generator::get_instance(); | |
| 1512 | + $slugs = $nsg->nsg_get_seo_page_slugs( $post_id ); | |
| 1513 | + | |
| 1514 | + if ( is_array( $slugs ) ) { | |
| 1515 | + foreach ( $slugs as $slug ) { | |
| 1516 | + $generated_url = trailingslashit( $url ) . $slug . '/'; | |
| 1517 | + | |
| 1518 | + if (bwp_can_optimize_page_url($generated_url)) { | |
| 1519 | + $sitemap_urls[] = $generated_url; | |
| 1520 | + } | |
| 1521 | + } | |
| 1522 | + } | |
| 1523 | + } | |
| 1524 | + | |
| 1508 | 1525 | $translation_urls = apply_filters('berqwp_page_translation_urls', [], $url); |
| 1509 | 1526 | |
| 1510 | 1527 | if (!bwp_can_optimize_page_url($url)) { |
| 1511 | 1528 | continue; |
| @@ -1623,21 +1640,21 @@ | ||
| 1623 | 1640 | |
| 1624 | 1641 | if (!empty($_GET['tab_id'])) { |
| 1625 | 1642 | if (sanitize_text_field($_GET['tab_id']) == $tab_id) { |
| 1626 | 1643 | // echo ' style="display:block" '; |
| 1627 | - echo ' style="visibility:visible;opacity:1;height:auto;" '; | |
| 1644 | + echo ' style="visibility:visible;opacity:1;height:auto;display:block;" '; | |
| 1628 | 1645 | } else { |
| 1629 | 1646 | // echo ' style="display:none" '; |
| 1630 | - echo ' style="visibility:hidden;opacity:0;height:0;overflow:hidden;" '; | |
| 1647 | + echo ' style="visibility:hidden;opacity:0;height:0;overflow:hidden;display:none;" '; | |
| 1631 | 1648 | } |
| 1632 | 1649 | } else { |
| 1633 | 1650 | |
| 1634 | 1651 | if ($tab_id == $default_tab) { |
| 1635 | 1652 | // echo ' style="display:block" '; |
| 1636 | - echo ' style="visibility:visible;opacity:1;height:auto;" '; | |
| 1653 | + echo ' style="visibility:visible;opacity:1;height:auto;display:block;" '; | |
| 1637 | 1654 | } else { |
| 1638 | 1655 | // echo ' style="display:none" '; |
| 1639 | - echo ' style="visibility:hidden;opacity:0;height:0;overflow:hidden;" '; | |
| 1656 | + echo ' style="visibility:hidden;opacity:0;height:0;overflow:hidden;display:none;" '; | |
| 1640 | 1657 | } |
| 1641 | 1658 | } |
| 1642 | 1659 | } |
| 1643 | 1660 | |
| @@ -1675,15 +1692,15 @@ | ||
| 1675 | 1692 | 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" |
| 1676 | 1693 | fill="#1f72ff" /> |
| 1677 | 1694 | </svg></div> |
| 1678 | 1695 | <div class="content"> |
| 1679 | - <div class="status-tag"><?php esc_html_e($status, 'searchpro'); ?></div> | |
| 1696 | + <div class="status-tag"><?php echo esc_html($status); ?></div> | |
| 1680 | 1697 | <?php if (!empty($title)) { ?> |
| 1681 | - <h5><?php echo wp_kses_post(__($title, 'searchpro')); ?></h5> | |
| 1698 | + <h5><?php echo wp_kses_post($title); ?></h5> | |
| 1682 | 1699 | <?php } ?> |
| 1683 | 1700 | |
| 1684 | 1701 | <?php if (!empty($message)) { ?> |
| 1685 | - <?php echo wp_kses_post(__($message, 'searchpro')); ?> | |
| 1702 | + <?php echo wp_kses_post($message); ?> | |
| 1686 | 1703 | <?php } ?> |
| 1687 | 1704 | |
| 1688 | 1705 | <?php if (!empty($btn) && is_array($btn)) { ?> |
| 1689 | 1706 | <div class="bwp-notice-btn"> |
| @@ -1707,9 +1724,9 @@ | ||
| 1707 | 1724 | ?> |
| 1708 | 1725 | <a target="<?php echo esc_attr($bwp_btn['target']) ?? ''; ?>" |
| 1709 | 1726 | href="<?php echo esc_attr($bwp_btn['href']) ?? ''; ?>" |
| 1710 | 1727 | class="bwp-btn <?php echo esc_attr($bwp_btn['classes']) ?? ''; ?>"> |
| 1711 | - <?php echo esc_html__($bwp_btn['text'], 'searchpro') ?? ''; ?> | |
| 1728 | + <?php echo esc_html($bwp_btn['text']); ?> | |
| 1712 | 1729 | </a> |
| 1713 | 1730 | <?php |
| 1714 | 1731 | } |
| 1715 | 1732 | ?> |
| @@ -1794,9 +1811,9 @@ | ||
| 1794 | 1811 | if (isset($_GET['berqwp_logs'])) { |
| 1795 | 1812 | |
| 1796 | 1813 | // Check if the current user is logged in and has admin privileges |
| 1797 | 1814 | if (!is_user_logged_in() || !current_user_can('administrator')) { |
| 1798 | - wp_die(__('You are not allowed to access this page.', 'berqwp')); | |
| 1815 | + wp_die(__('You are not allowed to access this page.', 'searchpro')); | |
| 1799 | 1816 | } |
| 1800 | 1817 | |
| 1801 | 1818 | // Define the path to the BerqWP logs file |
| 1802 | 1819 | $log_file_path = optifer_cache . '/logs/berqwp.log'; // Adjust path if needed |
| @@ -1872,11 +1889,27 @@ | ||
| 1872 | 1889 | <FilesMatch "index\.html\.gz$"> |
| 1873 | 1890 | Order allow,deny |
| 1874 | 1891 | Allow from all |
| 1875 | 1892 | </FilesMatch> |
| 1893 | + | |
| 1894 | +# Block PHP execution and dot-files to prevent webshell deployment | |
| 1895 | +<FilesMatch "\.php\d*$|\.phtml$|\.phar$"> | |
| 1896 | + Order allow,deny | |
| 1897 | + Deny from all | |
| 1898 | +</FilesMatch> | |
| 1899 | +<FilesMatch "^\."> | |
| 1900 | + Order allow,deny | |
| 1901 | + Deny from all | |
| 1902 | +</FilesMatch> | |
| 1876 | 1903 | HTACCESS; |
| 1877 | 1904 | |
| 1878 | 1905 | file_put_contents($cache_dir . '.htaccess', $rules); |
| 1906 | + | |
| 1907 | + // Suppress directory listing | |
| 1908 | + $index_stub = $cache_dir . 'index.php'; | |
| 1909 | + if (!file_exists($index_stub)) { | |
| 1910 | + file_put_contents($index_stub, '<?php // Silence is golden'); | |
| 1911 | + } | |
| 1879 | 1912 | } |
| 1880 | 1913 | |
| 1881 | 1914 | function bwp_write_htaccess_rules($ignore_sandbox = false) |
| 1882 | 1915 | { |
| @@ -1888,8 +1921,10 @@ | ||
| 1888 | 1921 | return; |
| 1889 | 1922 | } |
| 1890 | 1923 | |
| 1891 | 1924 | $htaccess = get_home_path() . '.htaccess'; |
| 1925 | + $cache_tag_host = parse_url(home_url(), PHP_URL_HOST); | |
| 1926 | + | |
| 1892 | 1927 | $rules = [ |
| 1893 | 1928 | '<IfModule mod_rewrite.c>', |
| 1894 | 1929 | ' RewriteEngine On', |
| 1895 | 1930 | ' RewriteCond %{REQUEST_METHOD} !POST', |
| @@ -1894,8 +1929,9 @@ | ||
| 1894 | 1929 | ' RewriteEngine On', |
| 1895 | 1930 | ' RewriteCond %{REQUEST_METHOD} !POST', |
| 1896 | 1931 | ' RewriteCond %{QUERY_STRING} ^$', |
| 1897 | 1932 | ' RewriteCond %{HTTP_COOKIE} !(wp\-postpass|wordpress_logged_in|comment_author|woocommerce_cart_hash|edd_items_in_cart) [NC]', |
| 1933 | + ' RewriteCond %{HTTP_USER_AGENT} !(Googlebot|Google-InspectionTool|Bingbot|Slurp|DuckDuckBot|Baiduspider|YandexBot|Sogou|Exabot|facebookexternalhit|Twitterbot|LinkedInBot|WhatsApp|TelegramBot|Applebot|AhrefsBot|SemrushBot|MJ12bot|DotBot|PetalBot|BLEXBot|archive\.org_bot|UptimeRobot|Pingdom|ChatGPT-User|GPTBot|ClaudeBot|Bytespider) [NC]', | |
| 1898 | 1934 | ' RewriteCond %{DOCUMENT_ROOT}/wp-content/cache/berqwp/html/%{HTTP_HOST}%{REQUEST_URI}/index.html.gz -f', |
| 1899 | 1935 | ' RewriteRule .* /wp-content/cache/berqwp/html/%{HTTP_HOST}%{REQUEST_URI}/index.html.gz [L]', |
| 1900 | 1936 | '</IfModule>', |
| 1901 | 1937 | '<IfModule mod_mime.c>', |
| @@ -1901,15 +1937,54 @@ | ||
| 1901 | 1937 | '<IfModule mod_mime.c>', |
| 1902 | 1938 | ' <FilesMatch "index\.html\.gz$">', |
| 1903 | 1939 | ' ForceType text/html', |
| 1904 | 1940 | ' AddEncoding gzip .gz', |
| 1941 | + ' AddDefaultCharset utf-8', | |
| 1905 | 1942 | ' </FilesMatch>', |
| 1906 | 1943 | '</IfModule>', |
| 1907 | 1944 | '<IfModule mod_headers.c>', |
| 1908 | 1945 | ' <FilesMatch "index\.html\.gz$">', |
| 1946 | + ' Header set X-BerqWP-Cache "HIT"', | |
| 1909 | 1947 | ' Header set X-Served "server"', |
| 1948 | + ' Header set Content-Encoding "gzip"', | |
| 1949 | + ' Header set Vary "Accept-Encoding, Cookie"', | |
| 1950 | + ' Header set CDN-Cache-Control "max-age=2592000"', | |
| 1951 | + ' Header set Cache-Control "public, max-age=600, s-maxage=2592000, stale-while-revalidate=86400"', | |
| 1952 | + ' Header set Cache-Tag "' . $cache_tag_host . '"', | |
| 1953 | + ' Header set X-Content-Type-Options "nosniff"', | |
| 1910 | 1954 | ' </FilesMatch>', |
| 1911 | 1955 | '</IfModule>', |
| 1956 | + '<IfModule mod_expires.c>', | |
| 1957 | + ' ExpiresActive On', | |
| 1958 | + ' ExpiresByType text/css "access plus 1 year"', | |
| 1959 | + ' ExpiresByType application/javascript "access plus 1 year"', | |
| 1960 | + ' ExpiresByType text/javascript "access plus 1 year"', | |
| 1961 | + ' ExpiresByType image/jpeg "access plus 1 year"', | |
| 1962 | + ' ExpiresByType image/png "access plus 1 year"', | |
| 1963 | + ' ExpiresByType image/gif "access plus 1 year"', | |
| 1964 | + ' ExpiresByType image/webp "access plus 1 year"', | |
| 1965 | + ' ExpiresByType image/avif "access plus 1 year"', | |
| 1966 | + ' ExpiresByType image/svg+xml "access plus 1 year"', | |
| 1967 | + ' ExpiresByType image/x-icon "access plus 1 year"', | |
| 1968 | + ' ExpiresByType font/woff "access plus 1 year"', | |
| 1969 | + ' ExpiresByType font/woff2 "access plus 1 year"', | |
| 1970 | + ' ExpiresByType application/font-woff "access plus 1 year"', | |
| 1971 | + ' ExpiresByType application/font-woff2 "access plus 1 year"', | |
| 1972 | + ' ExpiresByType application/x-font-ttf "access plus 1 year"', | |
| 1973 | + ' ExpiresByType application/x-font-opentype "access plus 1 year"', | |
| 1974 | + '</IfModule>', | |
| 1975 | + '<IfModule mod_headers.c>', | |
| 1976 | + ' <FilesMatch "\.(css|js)$">', | |
| 1977 | + ' Header set Cache-Control "public, max-age=31536000, immutable"', | |
| 1978 | + ' </FilesMatch>', | |
| 1979 | + ' <FilesMatch "\.(jpg|jpeg|png|gif|webp|avif|svg|ico)$">', | |
| 1980 | + ' Header set Cache-Control "public, max-age=31536000, immutable"', | |
| 1981 | + ' </FilesMatch>', | |
| 1982 | + ' <FilesMatch "\.(woff|woff2|ttf|otf|eot)$">', | |
| 1983 | + ' Header set Cache-Control "public, max-age=31536000, immutable"', | |
| 1984 | + ' Header set Access-Control-Allow-Origin "*"', | |
| 1985 | + ' </FilesMatch>', | |
| 1986 | + '</IfModule>', | |
| 1912 | 1987 | ]; |
| 1913 | 1988 | |
| 1914 | 1989 | // Must appear before the WordPress block so Apache processes it first |
| 1915 | 1990 | $marker = 'BerqWP Cache'; |
| @@ -2200,9 +2275,8 @@ | ||
| 2200 | 2275 | |
| 2201 | 2276 | function berqwp_validate_url_array($urls) |
| 2202 | 2277 | { |
| 2203 | 2278 | $home_host = parse_url(home_url(), PHP_URL_HOST); |
| 2204 | - $home_scheme = parse_url(home_url(), PHP_URL_SCHEME); | |
| 2205 | 2279 | |
| 2206 | 2280 | $urls = array_filter($urls, function ($url) use ($home_host) { |
| 2207 | 2281 | $url_host = parse_url($url, PHP_URL_HOST); |
| 2208 | 2282 | |
| @@ -2213,35 +2287,9 @@ | ||
| 2213 | 2287 | |
| 2214 | 2288 | return $url_host === $home_host; |
| 2215 | 2289 | }); |
| 2216 | 2290 | |
| 2217 | - $urls = array_map(function ($url) use ($home_scheme) { | |
| 2218 | - // Skip invalid URLs | |
| 2219 | - if (!is_string($url) || $url === '') { | |
| 2220 | - return $url; | |
| 2221 | - } | |
| 2222 | - | |
| 2223 | - $parts = parse_url($url); | |
| 2224 | - | |
| 2225 | - // Relative URL → leave as-is | |
| 2226 | - if (empty($parts['scheme'])) { | |
| 2227 | - return $url; | |
| 2228 | - } | |
| 2229 | - | |
| 2230 | - // Rebuild URL with home scheme | |
| 2231 | - $parts['scheme'] = $home_scheme; | |
| 2232 | - | |
| 2233 | - $new_url = $parts['scheme'] . '://'; | |
| 2234 | - $new_url .= $parts['host'] ?? ''; | |
| 2235 | - $new_url .= isset($parts['port']) ? ':' . $parts['port'] : ''; | |
| 2236 | - $new_url .= $parts['path'] ?? ''; | |
| 2237 | - $new_url .= isset($parts['query']) ? '?' . $parts['query'] : ''; | |
| 2238 | - $new_url .= isset($parts['fragment']) ? '#' . $parts['fragment'] : ''; | |
| 2239 | - | |
| 2240 | - return $new_url; | |
| 2241 | - }, $urls); | |
| 2242 | - | |
| 2243 | - return $urls; | |
| 2291 | + return array_values($urls); | |
| 2244 | 2292 | } |
| 2245 | 2293 | |
| 2246 | 2294 | function berqwp_render_toggle($name, $checked) { |
| 2247 | 2295 | ?> |
| @@ -2251,8 +2299,52 @@ | ||
| 2251 | 2299 | </label> |
| 2252 | 2300 | <?php |
| 2253 | 2301 | } |
| 2254 | 2302 | |
| 2303 | +function bwp_log_recently_optimized_page($page_url) | |
| 2304 | +{ | |
| 2305 | + if (empty($page_url)) return; | |
| 2306 | + | |
| 2307 | + // berqwp_stored_page_cache passes a slug/path, not a full URL — reconstruct it | |
| 2308 | + if (!str_starts_with($page_url, 'http')) { | |
| 2309 | + $page_url = home_url($page_url); | |
| 2310 | + } | |
| 2311 | + $page_url = urldecode($page_url); | |
| 2312 | + | |
| 2313 | + $log = json_decode(get_option('berqwp_recently_optimized', '[]'), true); | |
| 2314 | + if (!is_array($log)) $log = []; | |
| 2315 | + | |
| 2316 | + // Remove existing entry for this URL so re-caching moves it to the top | |
| 2317 | + $log = array_values(array_filter($log, fn($e) => $e['url'] !== $page_url)); | |
| 2318 | + | |
| 2319 | + array_unshift($log, [ | |
| 2320 | + 'url' => esc_url_raw($page_url), | |
| 2321 | + 'cached_at' => current_time('Y-m-d H:i:s'), | |
| 2322 | + ]); | |
| 2323 | + | |
| 2324 | + if (count($log) > 200) { | |
| 2325 | + $log = array_slice($log, 0, 200); | |
| 2326 | + } | |
| 2327 | + | |
| 2328 | + update_option('berqwp_recently_optimized', wp_json_encode($log), false); | |
| 2329 | +} | |
| 2330 | + | |
| 2331 | +function bwp_clear_recently_optimized_log() | |
| 2332 | +{ | |
| 2333 | + delete_option('berqwp_recently_optimized'); | |
| 2334 | +} | |
| 2335 | + | |
| 2336 | +function bwp_remove_recently_optimized_entry($page_url) | |
| 2337 | +{ | |
| 2338 | + if (empty($page_url)) return; | |
| 2339 | + | |
| 2340 | + $log = json_decode(get_option('berqwp_recently_optimized', '[]'), true); | |
| 2341 | + if (!is_array($log)) return; | |
| 2342 | + | |
| 2343 | + $log = array_values(array_filter($log, fn($e) => $e['url'] !== $page_url)); | |
| 2344 | + update_option('berqwp_recently_optimized', wp_json_encode($log), false); | |
| 2345 | +} | |
| 2346 | + | |
| 2255 | 2347 | function berqwp_can_use_cloud() { |
| 2256 | 2348 | $berqconfigs = berqConfigs::getInstance(); |
| 2257 | 2349 | $configs = $berqconfigs->get_configs(); |
| 2258 | 2350 | $license_key = berqwp_get_license_key(); |
| @@ -2258,4 +2350,11 @@ | ||
| 2258 | 2350 | $license_key = berqwp_get_license_key(); |
| 2259 | 2351 | |
| 2260 | 2352 | return !empty($configs['site_id']) && !empty($configs['secret']) && !empty($configs['optimization_method']) && $configs['optimization_method'] == 'cloud' && !empty($license_key); |
| 2261 | 2353 | } |
| 2354 | + | |
| 2355 | +function berqwp_generate_site_id() { | |
| 2356 | + $blog_id = get_current_blog_id(); | |
| 2357 | + $network_id = function_exists('get_current_network_id') ? get_current_network_id() : 1; | |
| 2358 | + $siteurl = get_option('siteurl'); | |
| 2359 | + return md5("berqwp|$network_id|$blog_id|$siteurl"); | |
| 2360 | +} | |