diff --git a/plugins/faustwp/includes/deny-public-access/callbacks.php b/plugins/faustwp/includes/deny-public-access/callbacks.php index c5eac2c6d..dd8516ff5 100644 --- a/plugins/faustwp/includes/deny-public-access/callbacks.php +++ b/plugins/faustwp/includes/deny-public-access/callbacks.php @@ -55,13 +55,8 @@ function deny_public_access() { return; } - $frontend_uri = trailingslashit( $frontend_uri ); - - // Get the request uri with query params. - $request_uri = home_url( add_query_arg( null, null ) ); - $response_code = apply_filters( 'faustwp_public_redirect_status_code', 302 ); - $redirect_url = str_replace( trailingslashit( get_home_url() ), $frontend_uri, $request_uri ); + $redirect_url = get_public_redirect_url( add_query_arg( null, null ), $frontend_uri ); $protocols = array( 'http', 'https' ); header( 'X-Redirect-By: WP Engine Headless plugin' ); // For support teams. See https://developer.yoast.com/blog/x-redirect-by-header/. diff --git a/plugins/faustwp/includes/deny-public-access/functions.php b/plugins/faustwp/includes/deny-public-access/functions.php index 9b423c6b9..2ae25a254 100644 --- a/plugins/faustwp/includes/deny-public-access/functions.php +++ b/plugins/faustwp/includes/deny-public-access/functions.php @@ -37,3 +37,32 @@ function doing_file_editor_save() { return true; } + +/** + * Builds the front-end URL to redirect a public request to. + * + * Strips the WordPress home path from the request first, so a site installed in + * a subdirectory (such as https://example.com/wp) redirects to the matching + * front-end path instead of repeating the subdirectory. + * + * @param string $request_uri The request path and query string, such as `/wp/sample-page/?p=1`. + * @param string $frontend_uri The front-end site URL. + * + * @return string + */ +function get_public_redirect_url( $request_uri, $frontend_uri ) { + $home_path = untrailingslashit( (string) wp_parse_url( home_url(), PHP_URL_PATH ) ); + + if ( + '' !== $home_path && + ( + $request_uri === $home_path || + 0 === strpos( $request_uri, $home_path . '/' ) || + 0 === strpos( $request_uri, $home_path . '?' ) + ) + ) { + $request_uri = substr( $request_uri, strlen( $home_path ) ); + } + + return trailingslashit( $frontend_uri ) . ltrim( $request_uri, '/' ); +} diff --git a/plugins/faustwp/tests/integration/DenyPublicAccessFunctionsTests.php b/plugins/faustwp/tests/integration/DenyPublicAccessFunctionsTests.php new file mode 100644 index 000000000..0a0ed6401 --- /dev/null +++ b/plugins/faustwp/tests/integration/DenyPublicAccessFunctionsTests.php @@ -0,0 +1,58 @@ +assertSame( + 'http://localhost:3000/sample-page/?foo=bar', + get_public_redirect_url( '/sample-page/?foo=bar', $this->frontend_uri ) + ); + } + + public function test_get_public_redirect_url_strips_subdirectory_install_path() { + update_option( 'home', 'http://example.org/wp' ); + + $this->assertSame( + 'http://localhost:3000/sample-page/', + get_public_redirect_url( '/wp/sample-page/', $this->frontend_uri ) + ); + } + + public function test_get_public_redirect_url_maps_subdirectory_root_to_frontend_root() { + update_option( 'home', 'http://example.org/wp/' ); + + $this->assertSame( 'http://localhost:3000/', get_public_redirect_url( '/wp/', $this->frontend_uri ) ); + $this->assertSame( 'http://localhost:3000/', get_public_redirect_url( '/wp', $this->frontend_uri ) ); + $this->assertSame( 'http://localhost:3000/?p=1', get_public_redirect_url( '/wp?p=1', $this->frontend_uri ) ); + } + + public function test_get_public_redirect_url_does_not_strip_a_partial_path_match() { + update_option( 'home', 'http://example.org/wp' ); + + $this->assertSame( + 'http://localhost:3000/wpfoo/page/', + get_public_redirect_url( '/wpfoo/page/', $this->frontend_uri ) + ); + } + + public function test_get_public_redirect_url_keeps_frontend_path() { + update_option( 'home', 'http://example.org/wp' ); + + $this->assertSame( + 'https://example.com/app/sample-page/', + get_public_redirect_url( '/wp/sample-page/', 'https://example.com/app' ) + ); + } +}