| @@ -243,8 +243,47 @@ | ||
| 243 | 243 | function berqwp_home_url() { |
| 244 | 244 | return untrailingslashit(apply_filters('berqwp_site_url', home_url())); |
| 245 | 245 | } |
| 246 | 246 | |
| 247 | +function bwp_canonicalize_page_url($url) { | |
| 248 | + $permalink_structure = get_option('permalink_structure'); | |
| 249 | + | |
| 250 | + if (!$permalink_structure) { | |
| 251 | + return $url; | |
| 252 | + } | |
| 253 | + | |
| 254 | + $path = parse_url($url, PHP_URL_PATH) ?? '/'; | |
| 255 | + | |
| 256 | + if ($path === '/') { | |
| 257 | + return $url; | |
| 258 | + } | |
| 259 | + | |
| 260 | + $uses_trailing_slash = substr(rtrim($permalink_structure), -1) === '/'; | |
| 261 | + $has_trailing_slash = substr($path, -1) === '/'; | |
| 262 | + | |
| 263 | + if ($uses_trailing_slash && !$has_trailing_slash) { | |
| 264 | + return trailingslashit($url); | |
| 265 | + } | |
| 266 | + | |
| 267 | + if (!$uses_trailing_slash && $has_trailing_slash) { | |
| 268 | + return untrailingslashit($url); | |
| 269 | + } | |
| 270 | + | |
| 271 | + return $url; | |
| 272 | +} | |
| 273 | + | |
| 274 | +function bwp_sync_permalink_config() { | |
| 275 | + $permalink_structure = get_option('permalink_structure'); | |
| 276 | + $trailing_slash = empty($permalink_structure) ? null : (substr(rtrim($permalink_structure), -1) === '/'); | |
| 277 | + | |
| 278 | + $berqconfigs = berqConfigs::getInstance(); | |
| 279 | + $current = $berqconfigs->get_configs(); | |
| 280 | + | |
| 281 | + if ($current === false || !array_key_exists('permalink_trailing_slash', $current) || $current['permalink_trailing_slash'] !== $trailing_slash) { | |
| 282 | + $berqconfigs->update_configs(['permalink_trailing_slash' => $trailing_slash]); | |
| 283 | + } | |
| 284 | +} | |
| 285 | + | |
| 247 | 286 | function berqwp_get_page_params($page_url, $is_forced = false) |
| 248 | 287 | { |
| 249 | 288 | |
| 250 | 289 | if (empty($page_url)) { |
| @@ -1889,8 +1928,22 @@ | ||
| 1889 | 1928 | if (!file_exists($cache_dir)) { |
| 1890 | 1929 | wp_mkdir_p($cache_dir); |
| 1891 | 1930 | } |
| 1892 | 1931 | |
| 1932 | + if (!function_exists('got_mod_rewrite')) { | |
| 1933 | + require_once ABSPATH . 'wp-admin/includes/misc.php'; | |
| 1934 | + } | |
| 1935 | + | |
| 1936 | + if (!got_mod_rewrite()) { | |
| 1937 | + return; | |
| 1938 | + } | |
| 1939 | + | |
| 1940 | + $htaccess_path = $cache_dir . '.htaccess'; | |
| 1941 | + | |
| 1942 | + if (!is_writable($htaccess_path)) { | |
| 1943 | + return; | |
| 1944 | + } | |
| 1945 | + | |
| 1893 | 1946 | $rules = <<<HTACCESS |
| 1894 | 1947 | Order allow,deny |
| 1895 | 1948 | Deny from all |
| 1896 | 1949 | |
| @@ -1909,9 +1962,9 @@ | ||
| 1909 | 1962 | Deny from all |
| 1910 | 1963 | </FilesMatch> |
| 1911 | 1964 | HTACCESS; |
| 1912 | 1965 | |
| 1913 | - file_put_contents($cache_dir . '.htaccess', $rules); | |
| 1966 | + file_put_contents($htaccess_path, $rules); | |
| 1914 | 1967 | |
| 1915 | 1968 | // Suppress directory listing |
| 1916 | 1969 | $index_stub = $cache_dir . 'index.php'; |
| 1917 | 1970 | if (!file_exists($index_stub)) { |
| @@ -1916,10 +1969,31 @@ | ||
| 1916 | 1969 | $index_stub = $cache_dir . 'index.php'; |
| 1917 | 1970 | if (!file_exists($index_stub)) { |
| 1918 | 1971 | file_put_contents($index_stub, '<?php // Silence is golden'); |
| 1919 | 1972 | } |
| 1973 | + | |
| 1920 | 1974 | } |
| 1921 | 1975 | |
| 1976 | +function bwp_delete_php_files_in_cache() | |
| 1977 | +{ | |
| 1978 | + $cache_dir = optifer_cache; | |
| 1979 | + if (!is_dir($cache_dir)) { | |
| 1980 | + return; | |
| 1981 | + } | |
| 1982 | + | |
| 1983 | + $php_extensions = ['php', 'php3', 'php4', 'php5', 'php7', 'php8', 'phtml', 'phar']; | |
| 1984 | + | |
| 1985 | + $iterator = new RecursiveIteratorIterator( | |
| 1986 | + new RecursiveDirectoryIterator($cache_dir, RecursiveDirectoryIterator::SKIP_DOTS) | |
| 1987 | + ); | |
| 1988 | + | |
| 1989 | + foreach ($iterator as $file) { | |
| 1990 | + if ($file->isFile() && in_array(strtolower($file->getExtension()), $php_extensions, true)) { | |
| 1991 | + @unlink($file->getRealPath()); | |
| 1992 | + } | |
| 1993 | + } | |
| 1994 | +} | |
| 1995 | + | |
| 1922 | 1996 | function bwp_write_htaccess_rules($ignore_sandbox = false) |
| 1923 | 1997 | { |
| 1924 | 1998 | if (!got_mod_rewrite() || bwp_is_openlitespeed_server()) { |
| 1925 | 1999 | return; |
| @@ -1931,9 +2005,22 @@ | ||
| 1931 | 2005 | |
| 1932 | 2006 | $htaccess = get_home_path() . '.htaccess'; |
| 1933 | 2007 | $cache_tag_host = parse_url(home_url(), PHP_URL_HOST); |
| 1934 | 2008 | |
| 1935 | - $rules = [ | |
| 2009 | + if (!is_writable($htaccess)) { | |
| 2010 | + return; | |
| 2011 | + } | |
| 2012 | + | |
| 2013 | + // Match the cache-serving RewriteCond to the site's actual permalink convention, | |
| 2014 | + // so caching works whether the site uses trailing slashes or not. | |
| 2015 | + $permalink_structure = get_option('permalink_structure'); | |
| 2016 | + $uses_trailing_slash = empty($permalink_structure) || substr(rtrim($permalink_structure), -1) === '/'; | |
| 2017 | + | |
| 2018 | + $slash_conds = $uses_trailing_slash | |
| 2019 | + ? [' RewriteCond %{REQUEST_URI} /$'] | |
| 2020 | + : [' RewriteCond %{REQUEST_URI} ^/$ [OR]', ' RewriteCond %{REQUEST_URI} !/$']; | |
| 2021 | + | |
| 2022 | + $rules = array_merge([ | |
| 1936 | 2023 | '<IfModule mod_rewrite.c>', |
| 1937 | 2024 | ' RewriteEngine On', |
| 1938 | 2025 | ' RewriteCond %{REQUEST_METHOD} !POST', |
| 1939 | 2026 | ' RewriteCond %{QUERY_STRING} ^$', |
| @@ -1938,8 +2025,9 @@ | ||
| 1938 | 2025 | ' RewriteCond %{REQUEST_METHOD} !POST', |
| 1939 | 2026 | ' RewriteCond %{QUERY_STRING} ^$', |
| 1940 | 2027 | ' RewriteCond %{HTTP_COOKIE} !(wp\-postpass|wordpress_logged_in|comment_author|woocommerce_cart_hash|edd_items_in_cart) [NC]', |
| 1941 | 2028 | ' 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]', |
| 2029 | + ], $slash_conds, [ | |
| 1942 | 2030 | ' RewriteCond %{DOCUMENT_ROOT}/wp-content/cache/berqwp/html/%{HTTP_HOST}%{REQUEST_URI}/index.html.gz -f', |
| 1943 | 2031 | ' RewriteRule .* /wp-content/cache/berqwp/html/%{HTTP_HOST}%{REQUEST_URI}/index.html.gz [L]', |
| 1944 | 2032 | '</IfModule>', |
| 1945 | 2033 | '<IfModule mod_mime.c>', |
| @@ -1991,9 +2079,9 @@ | ||
| 1991 | 2079 | ' Header set Cache-Control "public, max-age=31536000, immutable"', |
| 1992 | 2080 | ' Header set Access-Control-Allow-Origin "*"', |
| 1993 | 2081 | ' </FilesMatch>', |
| 1994 | 2082 | '</IfModule>', |
| 1995 | - ]; | |
| 2083 | + ]); | |
| 1996 | 2084 | |
| 1997 | 2085 | // Must appear before the WordPress block so Apache processes it first |
| 1998 | 2086 | $marker = 'BerqWP Cache'; |
| 1999 | 2087 | $start = "# BEGIN $marker"; |