$markerline ) { if ( strpos( $markerline, '# BEGIN ' . $marker ) !== false ) { $state = false; } if ( $state ) { if ( $n + 1 < count( $markerdata ) ) { fwrite( $f, "{$markerline}\n" ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fwrite } else { fwrite( $f, "{$markerline}" ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fwrite } } if ( strpos( $markerline, '# END ' . $marker ) !== false ) { $state = true; } } return true; } else { return false; } } function update_cached_mobile_ua_list( $mobile_browsers, $mobile_prefixes = 0, $mobile_groups = 0 ) { global $wp_cache_config_file, $wp_cache_mobile_browsers, $wp_cache_mobile_prefixes, $wp_cache_mobile_groups; wp_cache_setting( 'wp_cache_mobile_browsers', $mobile_browsers ); wp_cache_setting( 'wp_cache_mobile_prefixes', $mobile_prefixes ); if ( is_array( $mobile_groups ) ) { $wp_cache_mobile_groups = $mobile_groups; wp_cache_replace_line('^ *\$wp_cache_mobile_groups', "\$wp_cache_mobile_groups = '" . implode( ', ', $mobile_groups ) . "';", $wp_cache_config_file); } return true; } function wpsc_update_htaccess() { extract( wpsc_get_htaccess_info() ); // $document_root, $apache_root, $home_path, $home_root, $home_root_lc, $inst_root, $wprules, $scrules, $condition_rules, $rules, $gziprules // @phan-suppress-next-line PhanTypeSuspiciousStringExpression -- $home_path is set via extract() wpsc_remove_marker( $home_path.'.htaccess', 'WordPress' ); // remove original WP rules so SuperCache rules go on top // @phan-suppress-next-line PhanTypeSuspiciousStringExpression -- $home_path is set via extract() if( insert_with_markers( $home_path.'.htaccess', 'WPSuperCache', explode( "\n", $rules ) ) && insert_with_markers( $home_path.'.htaccess', 'WordPress', explode( "\n", $wprules ) ) ) { return true; } else { return false; } } function wpsc_update_htaccess_form( $short_form = true ) { global $wpmu_version; $admin_url = admin_url( 'options-general.php?page=wpsupercache' ); extract( wpsc_get_htaccess_info() ); // $document_root, $apache_root, $home_path, $home_root, $home_root_lc, $inst_root, $wprules, $scrules, $condition_rules, $rules, $gziprules // @phan-suppress-next-line PhanTypeSuspiciousStringExpression -- $home_path is set via extract() if( !is_writeable_ACLSafe( $home_path . ".htaccess" ) ) { echo "
" . __( 'Cannot update .htaccess', 'wp-super-cache' ) . "

" . sprintf( __( 'The file %s.htaccess cannot be modified by the web server. Please correct this using the chmod command or your ftp client.', 'wp-super-cache' ), $home_path ) . "

" . __( 'Refresh this page when the file permissions have been modified.' ) . "

" . sprintf( __( 'Alternatively, you can edit your %s.htaccess file manually and add the following code (before any WordPress rules):', 'wp-super-cache' ), $home_path ) . "

"; echo "

# BEGIN WPSuperCache\n" . esc_html( $rules ) . "# END WPSuperCache

"; } else { if ( $short_form == false ) { echo "

" . sprintf( __( 'To serve static html files your server must have the correct mod_rewrite rules added to a file called %s.htaccess', 'wp-super-cache' ), $home_path ) . " "; _e( "You can edit the file yourself. Add the following rules.", 'wp-super-cache' ); echo __( " Make sure they appear before any existing WordPress rules. ", 'wp-super-cache' ) . "

"; echo "
"; echo "
# BEGIN WPSuperCache\n" . esc_html( $rules ) . "# END WPSuperCache

"; echo "
"; echo "
" . sprintf( __( 'Rules must be added to %s too:', 'wp-super-cache' ), WP_CONTENT_DIR . "/cache/.htaccess" ) . "
"; echo "
"; echo "
# BEGIN supercache\n" . esc_html( $gziprules ) . "# END supercache

"; echo "
"; } if ( !isset( $wpmu_version ) || $wpmu_version == '' ) { echo '
'; echo ''; echo '
'; wp_nonce_field('wp-cache'); echo "
\n"; } } } /* * Return LOGGED_IN_COOKIE if it doesn't begin with wordpress_logged_in * to avoid having people update their .htaccess file */ function wpsc_get_logged_in_cookie() { $logged_in_cookie = 'wordpress_logged_in'; if ( defined( 'LOGGED_IN_COOKIE' ) && substr( constant( 'LOGGED_IN_COOKIE' ), 0, 19 ) != 'wordpress_logged_in' ) $logged_in_cookie = constant( 'LOGGED_IN_COOKIE' ); return $logged_in_cookie; } function wpsc_get_htaccess_info() { global $wp_cache_mobile_enabled, $wp_cache_mobile_prefixes, $wp_cache_mobile_browsers, $wp_cache_disable_utf8; global $htaccess_path; if ( isset( $_SERVER[ "PHP_DOCUMENT_ROOT" ] ) ) { $document_root = $_SERVER[ "PHP_DOCUMENT_ROOT" ]; $apache_root = $_SERVER[ "PHP_DOCUMENT_ROOT" ]; } else { $document_root = $_SERVER[ "DOCUMENT_ROOT" ]; $apache_root = '%{DOCUMENT_ROOT}'; } $content_dir_root = $document_root; if ( strpos( $document_root, '/kunden/homepages/' ) === 0 ) { // https://wordpress.org/support/topic/plugin-wp-super-cache-how-to-get-mod_rewrite-working-on-1and1-shared-hosting?replies=1 // On 1and1, PHP's directory structure starts with '/homepages'. The // Apache directory structure has an extra '/kunden' before it. // Also 1and1 does not support the %{DOCUMENT_ROOT} variable in // .htaccess files. // This prevents the $inst_root from being calculated correctly and // means that the $apache_root is wrong. // // e.g. This is an example of how Apache and PHP see the directory // structure on 1and1: // Apache: /kunden/homepages/xx/dxxxxxxxx/htdocs/site1/index.html // PHP: /homepages/xx/dxxxxxxxx/htdocs/site1/index.html // Here we fix up the paths to make mode_rewrite work on 1and1 shared hosting. $content_dir_root = substr( $content_dir_root, 7 ); $apache_root = $document_root; } $home_path = get_home_path(); $home_root = parse_url(get_bloginfo('url')); $home_root = isset( $home_root[ 'path' ] ) ? trailingslashit( $home_root[ 'path' ] ) : '/'; if ( isset( $htaccess_path ) ) { $home_path = $htaccess_path; } elseif ( $home_root == '/' && $home_path != $_SERVER[ 'DOCUMENT_ROOT' ] ) { $home_path = $_SERVER[ 'DOCUMENT_ROOT' ]; } elseif ( $home_root != '/' && $home_path != str_replace( '//', '/', $_SERVER[ 'DOCUMENT_ROOT' ] . $home_root ) && is_dir( $_SERVER[ 'DOCUMENT_ROOT' ] . $home_root ) ) { $home_path = str_replace( '//', '/', $_SERVER[ 'DOCUMENT_ROOT' ] . $home_root ); } $home_path = trailingslashit( $home_path ); // The rewrite rules point at supercache directories, so the home root has to // be spelled the way those directories are. See #1081. $home_root_lc = str_replace( '//', '/', wpsc_normalize_uri_case( $home_root ) ); $inst_root = str_replace( '//', '/', '/' . trailingslashit( str_replace( $content_dir_root, '', str_replace( '\\', '/', WP_CONTENT_DIR ) ) ) ); $wprules = implode( "\n", extract_from_markers( $home_path.'.htaccess', 'WordPress' ) ); $wprules = str_replace( "RewriteEngine On\n", '', $wprules ); $wprules = str_replace( "RewriteBase $home_root\n", '', $wprules ); $scrules = implode( "\n", extract_from_markers( $home_path.'.htaccess', 'WPSuperCache' ) ); if( substr( get_option( 'permalink_structure' ), -1 ) == '/' ) { $condition_rules[] = "RewriteCond %{REQUEST_URI} !^.*[^/]$"; $condition_rules[] = "RewriteCond %{REQUEST_URI} !^.*//.*$"; } $condition_rules[] = "RewriteCond %{REQUEST_METHOD} !POST"; $condition_rules[] = "RewriteCond %{QUERY_STRING} ^$"; $condition_rules[] = "RewriteCond %{HTTP:Cookie} !^.*(comment_author_|" . wpsc_get_logged_in_cookie() . wpsc_get_extra_cookies() . "|wp-postpass_).*$"; $condition_rules[] = "RewriteCond %{HTTP:X-Wap-Profile} !^[a-z0-9\\\"]+ [NC]"; $condition_rules[] = "RewriteCond %{HTTP:Profile} !^[a-z0-9\\\"]+ [NC]"; if ( $wp_cache_mobile_enabled ) { if ( isset( $wp_cache_mobile_browsers ) && "" != $wp_cache_mobile_browsers ) $condition_rules[] = "RewriteCond %{HTTP_USER_AGENT} !^.*(" . addcslashes( str_replace( ', ', '|', $wp_cache_mobile_browsers ), ' ' ) . ").* [NC]"; if ( isset( $wp_cache_mobile_prefixes ) && "" != $wp_cache_mobile_prefixes ) $condition_rules[] = "RewriteCond %{HTTP_USER_AGENT} !^(" . addcslashes( str_replace( ', ', '|', $wp_cache_mobile_prefixes ), ' ' ) . ").* [NC]"; } $condition_rules = apply_filters( 'supercacherewriteconditions', $condition_rules ); $rules = "\n"; $rules .= "RewriteEngine On\n"; $rules .= "RewriteBase $home_root\n"; // props Chris Messina $rules .= "#If you serve pages from behind a proxy you may want to change 'RewriteCond %{HTTPS} on' to something more sensible\n"; if ( isset( $wp_cache_disable_utf8 ) == false || $wp_cache_disable_utf8 == 0 ) { $charset = get_option('blog_charset') == '' ? 'UTF-8' : get_option('blog_charset'); $rules .= "AddDefaultCharset {$charset}\n"; } $rules .= "CONDITION_RULES"; $rules .= "RewriteCond %{HTTP:Accept-Encoding} gzip\n"; $rules .= "RewriteCond %{HTTPS} on\n"; $rules .= "RewriteCond {$apache_root}{$inst_root}cache/supercache/%{SERVER_NAME}{$home_root_lc}$1/index-https.html.gz -f\n"; $rules .= "RewriteRule ^(.*) \"{$inst_root}cache/supercache/%{SERVER_NAME}{$home_root_lc}$1/index-https.html.gz\" [L]\n\n"; $rules .= "CONDITION_RULES"; $rules .= "RewriteCond %{HTTP:Accept-Encoding} gzip\n"; $rules .= "RewriteCond %{HTTPS} !on\n"; $rules .= "RewriteCond {$apache_root}{$inst_root}cache/supercache/%{SERVER_NAME}{$home_root_lc}$1/index.html.gz -f\n"; $rules .= "RewriteRule ^(.*) \"{$inst_root}cache/supercache/%{SERVER_NAME}{$home_root_lc}$1/index.html.gz\" [L]\n\n"; $rules .= "CONDITION_RULES"; $rules .= "RewriteCond %{HTTPS} on\n"; $rules .= "RewriteCond {$apache_root}{$inst_root}cache/supercache/%{SERVER_NAME}{$home_root_lc}$1/index-https.html -f\n"; $rules .= "RewriteRule ^(.*) \"{$inst_root}cache/supercache/%{SERVER_NAME}{$home_root_lc}$1/index-https.html\" [L]\n\n"; $rules .= "CONDITION_RULES"; $rules .= "RewriteCond %{HTTPS} !on\n"; $rules .= "RewriteCond {$apache_root}{$inst_root}cache/supercache/%{SERVER_NAME}{$home_root_lc}$1/index.html -f\n"; $rules .= "RewriteRule ^(.*) \"{$inst_root}cache/supercache/%{SERVER_NAME}{$home_root_lc}$1/index.html\" [L]\n"; $rules .= "\n"; $rules = apply_filters( 'supercacherewriterules', $rules ); $rules = str_replace( "CONDITION_RULES", implode( "\n", $condition_rules ) . "\n", $rules ); $gziprules = "\n \n ForceType text/html\n FileETag None\n \n AddEncoding gzip .gz\n AddType text/html .gz\n\n"; $gziprules .= "\n SetEnvIfNoCase Request_URI \.gz$ no-gzip\n\n"; // Default headers. $headers = array( 'Vary' => 'Accept-Encoding, Cookie', 'Cache-Control' => 'max-age=3, must-revalidate', ); // Allow users to override the Vary header with WPSC_VARY_HEADER. if ( defined( 'WPSC_VARY_HEADER' ) && ! empty( WPSC_VARY_HEADER ) ) { $headers['Vary'] = WPSC_VARY_HEADER; } // Allow users to override Cache-control header with WPSC_CACHE_CONTROL_HEADER if ( defined( 'WPSC_CACHE_CONTROL_HEADER' ) && ! empty( WPSC_CACHE_CONTROL_HEADER ) ) { $headers['Cache-Control'] = WPSC_CACHE_CONTROL_HEADER; } // Allow overriding headers with a filter. $headers = apply_filters( 'wpsc_htaccess_mod_headers', $headers ); // Combine headers into a block of text. $headers_text = implode( "\n", array_map( function ( $key, $value ) { return " Header set $key '" . addcslashes( $value, "'" ) . "'"; }, array_keys( $headers ), array_values( $headers ) ) ); // Pack headers into gziprules (for historic reasons) - TODO refactor the values // returned to better reflect the blocks being written. if ( $headers_text != '' ) { $gziprules .= "\n$headers_text\n\n"; } // Deafult mod_expires rules. $expires_rules = array( 'ExpiresActive On', 'ExpiresByType text/html A3', ); // Allow overriding mod_expires rules with a filter. $expires_rules = apply_filters( 'wpsc_htaccess_mod_expires', $expires_rules ); $gziprules .= "\n"; $gziprules .= implode( "\n", array_map( function ( $line ) { return " $line"; }, $expires_rules ) ); $gziprules .= "\n\n"; $gziprules .= "Options -Indexes\n"; return array( 'document_root' => $document_root, 'apache_root' => $apache_root, 'home_path' => $home_path, 'home_root' => $home_root, 'home_root_lc' => $home_root_lc, 'inst_root' => $inst_root, 'wprules' => $wprules, 'scrules' => $scrules, 'condition_rules' => $condition_rules, 'rules' => $rules, 'gziprules' => $gziprules, ); } function add_mod_rewrite_rules() { return update_mod_rewrite_rules(); } function remove_mod_rewrite_rules() { return update_mod_rewrite_rules( false ); } function update_mod_rewrite_rules( $add_rules = true ) { global $cache_path, $update_mod_rewrite_rules_error; $update_mod_rewrite_rules_error = false; if ( defined( "DO_NOT_UPDATE_HTACCESS" ) ) { $update_mod_rewrite_rules_error = ".htaccess update disabled by admin: DO_NOT_UPDATE_HTACCESS defined"; return false; } if ( ! function_exists( 'get_home_path' ) ) { include_once( ABSPATH . 'wp-admin/includes/file.php' ); // get_home_path() include_once( ABSPATH . 'wp-admin/includes/misc.php' ); // extract_from_markers() } $home_path = trailingslashit( get_home_path() ); $home_root = parse_url( get_bloginfo( 'url' ) ); $home_root = isset( $home_root[ 'path' ] ) ? trailingslashit( $home_root[ 'path' ] ) : '/'; if ( $home_root == '/' && $home_path != $_SERVER[ 'DOCUMENT_ROOT' ] ) { $home_path = $_SERVER[ 'DOCUMENT_ROOT' ]; } elseif ( $home_root != '/' && $home_path != str_replace( '//', '/', $_SERVER[ 'DOCUMENT_ROOT' ] . $home_root ) && is_dir( $_SERVER[ 'DOCUMENT_ROOT' ] . $home_root ) ) { $home_path = str_replace( '//', '/', $_SERVER[ 'DOCUMENT_ROOT' ] . $home_root ); } $home_path = trailingslashit( $home_path ); if ( ! file_exists( $home_path . ".htaccess" ) ) { $update_mod_rewrite_rules_error = ".htaccess not found: {$home_path}.htaccess"; return false; } $generated_rules = wpsc_get_htaccess_info(); $existing_rules = implode( "\n", extract_from_markers( $home_path . '.htaccess', 'WPSuperCache' ) ); $rules = $add_rules ? $generated_rules[ 'rules' ] : ''; if ( $existing_rules == $rules ) { $update_mod_rewrite_rules_error = "rules have not changed"; return true; } if ( $generated_rules[ 'wprules' ] == '' ) { $update_mod_rewrite_rules_error = "WordPress rules empty"; return false; } if ( empty( $rules ) ) { return insert_with_markers( $home_path . '.htaccess', 'WPSuperCache', array() ); } $url = trailingslashit( get_bloginfo( 'url' ) ); $original_page = wp_remote_get( $url, array( 'timeout' => 60, 'blocking' => true ) ); if ( is_wp_error( $original_page ) ) { $update_mod_rewrite_rules_error = "Problem loading page"; return false; } $backup_filename = $cache_path . 'htaccess.' . wp_rand() . '.php'; $backup_file_contents = file_get_contents( $home_path . '.htaccess' ); file_put_contents( $backup_filename, "<" . "?php die(); ?" . ">" . $backup_file_contents ); $existing_gzip_rules = implode( "\n", extract_from_markers( $cache_path . '.htaccess', 'supercache' ) ); if ( $existing_gzip_rules != $generated_rules[ 'gziprules' ] ) { insert_with_markers( $cache_path . '.htaccess', 'supercache', explode( "\n", $generated_rules[ 'gziprules' ] ) ); } $wprules = extract_from_markers( $home_path . '.htaccess', 'WordPress' ); wpsc_remove_marker( $home_path . '.htaccess', 'WordPress' ); // remove original WP rules so SuperCache rules go on top if ( insert_with_markers( $home_path . '.htaccess', 'WPSuperCache', explode( "\n", $rules ) ) && insert_with_markers( $home_path . '.htaccess', 'WordPress', $wprules ) ) { $new_page = wp_remote_get( $url, array( 'timeout' => 60, 'blocking' => true ) ); $restore_backup = false; if ( is_wp_error( $new_page ) ) { $restore_backup = true; $update_mod_rewrite_rules_error = "Error testing page with new .htaccess rules: " . $new_page->get_error_message() . "."; wp_cache_debug( 'update_mod_rewrite_rules: failed to update rules. error fetching second page: ' . $new_page->get_error_message() ); } elseif ( $new_page[ 'body' ] != $original_page[ 'body' ] ) { $restore_backup = true; $update_mod_rewrite_rules_error = "Page test failed as pages did not match with new .htaccess rules."; wp_cache_debug( 'update_mod_rewrite_rules: failed to update rules. page test failed as pages did not match. Files dumped in ' . $cache_path . ' for inspection.' ); wp_cache_debug( 'update_mod_rewrite_rules: original page: 1-' . md5( $original_page[ 'body' ] ) . '.txt' ); wp_cache_debug( 'update_mod_rewrite_rules: new page: 1-' . md5( $new_page[ 'body' ] ) . '.txt' ); file_put_contents( $cache_path . '1-' . md5( $original_page[ 'body' ] ) . '.txt', $original_page[ 'body' ] ); file_put_contents( $cache_path . '2-' . md5( $new_page[ 'body' ] ) . '.txt', $new_page[ 'body' ] ); } if ( $restore_backup ) { global $wp_cache_debug; file_put_contents( $home_path . '.htaccess', $backup_file_contents ); unlink( $backup_filename ); if ( $wp_cache_debug ) { $update_mod_rewrite_rules_error .= "
See debug log for further details"; } else { $update_mod_rewrite_rules_error .= "
Enable debug log on Debugging page for further details and try again"; } return false; } } else { file_put_contents( $home_path . '.htaccess', $backup_file_contents ); unlink( $backup_filename ); $update_mod_rewrite_rules_error = "problem inserting rules in .htaccess and original .htaccess restored"; return false; } return true; }