diff --git a/.changeset/yellow-foxes-complain.md b/.changeset/yellow-foxes-complain.md new file mode 100644 index 000000000..98ec986b2 --- /dev/null +++ b/.changeset/yellow-foxes-complain.md @@ -0,0 +1,5 @@ +--- +'@faustwp/wordpress-plugin': patch +--- + +Fixed a bug where links were rewritten to the Faust Front-end Site URL when using the post editor, resulting in those rewritten links being saved to the post content and guid fields when they shouldn't be. These links are now saved with the URL pointing to the WP site, as they should be. They are still rewritten at runtime to link to the Front-end Site URL when appropriate. diff --git a/plugins/faustwp/includes/replacement/callbacks.php b/plugins/faustwp/includes/replacement/callbacks.php index 0115469f2..9cf215124 100644 --- a/plugins/faustwp/includes/replacement/callbacks.php +++ b/plugins/faustwp/includes/replacement/callbacks.php @@ -234,13 +234,35 @@ function post_preview_link( $link, $post ) { * @return string URL used for the post. */ function post_link( $link ) { + global $pagenow; + $target_pages = array( 'admin-ajax.php', 'index.php', 'edit.php', 'post.php', 'post-new.php', 'upload.php', 'media-new.php' ); + + // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Nonce verified in `is_ajax_generate_permalink_request()` and `is_wp_link_ajax_request()`. + if ( empty( $_POST ) && 'post-new.php' === $pagenow ) { + return $link; + } + + // Ajax requests to generate permalink. + if ( in_array( $pagenow, $target_pages, true ) + && is_ajax_generate_permalink_request() + ) { + return $link; + } + if ( ! is_rewrites_enabled() || ( function_exists( 'is_graphql_request' ) && is_graphql_request() ) + // Block editor makes REST requests on these pages to query content. + || ( in_array( $pagenow, $target_pages, true ) && current_user_can( 'edit_posts' ) && defined( 'REST_REQUEST' ) && REST_REQUEST ) ) { return $link; } + // Check for wp-link-ajax requests. Used by Classic Editor when linking content. + if ( is_wp_link_ajax_request() ) { + return $link; + } + return equivalent_frontend_url( $link ); } diff --git a/plugins/faustwp/includes/replacement/functions.php b/plugins/faustwp/includes/replacement/functions.php index 84768450a..056a932b7 100644 --- a/plugins/faustwp/includes/replacement/functions.php +++ b/plugins/faustwp/includes/replacement/functions.php @@ -110,3 +110,24 @@ function has_file_extension( $string ) { } } +/** + * Determines if an AJAX request to generate permalinks is in progress. + * + * @return boolean + */ +function is_ajax_generate_permalink_request(): bool { + return ( ! empty( $_POST['samplepermalinknonce'] ) && check_ajax_referer( 'samplepermalink', 'samplepermalinknonce' ) ); +} + +/** + * Determines if a wp-link-ajax request is in progress. + * + * @return boolean + */ +function is_wp_link_ajax_request(): bool { + return ( wp_doing_ajax() + && ! empty( $_POST['_ajax_linking_nonce'] ) + && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['_ajax_linking_nonce'] ) ), 'internal-linking' ) + && ! empty( $_POST['action'] ) + && 'wp-link-ajax' === $_POST['action'] ); +} diff --git a/plugins/faustwp/tests/integration/ReplacementCallbacksTests.php b/plugins/faustwp/tests/integration/ReplacementCallbacksTests.php index de3f4be75..6ad1c77a5 100644 --- a/plugins/faustwp/tests/integration/ReplacementCallbacksTests.php +++ b/plugins/faustwp/tests/integration/ReplacementCallbacksTests.php @@ -11,7 +11,8 @@ content_replacement, post_preview_link, image_source_replacement, - image_source_srcset_replacement + image_source_srcset_replacement, + post_link }; use function WPE\FaustWP\Settings\faustwp_update_setting; @@ -159,11 +160,51 @@ public function test_post_link_returns_unfiltered_link_when_content_replacement_ */ public function test_post_link_returns_filtered_link_when_content_replacement_is_enabled() { faustwp_update_setting( 'frontend_uri', 'http://moo' ); - faustwp_update_setting( 'enable_rewrites', true ); + faustwp_update_setting( 'enable_rewrites', '1' ); $this->assertSame( 'http://moo/?p=' . $this->post_id, get_permalink( $this->post_id ) ); } + public function test_post_link_returns_unfiltered_link_when_on_post_new_page(): void { + global $pagenow; + $pagenow = 'post-new.php'; + self::assertSame( 'http://example.org/hello-world', post_link( 'http://example.org/hello-world' ) ); + } + + public function test_post_link_returns_unfiltered_link_on_ajax_requests_to_generate_permalinks_using_samplepermalinknonce(): void { + global $pagenow, $_REQUEST, $_POST; + $pagenow = 'admin-ajax.php'; + wp_set_current_user( 1 ); + faustwp_update_setting( 'frontend_uri', 'http://moo' ); + faustwp_update_setting( 'enable_rewrites', '1' ); + $_REQUEST['samplepermalinknonce'] = wp_create_nonce( 'samplepermalink' ); + $_POST['samplepermalinknonce'] = $_REQUEST['samplepermalinknonce']; + + self::assertSame( 'http://example.org/hello-world', post_link( 'http://example.org/hello-world' ) ); + + unset( $_REQUEST['samplepermalinknonce'], $_POST['samplepermalinknonce'] ); + unset( $pagenow ); + wp_set_current_user( null ); + } + + public function test_post_link_returns_unfiltered_link_on_ajax_requests_to_generate_permalinks_using_ajax_linking_nonce(): void { + global $pagenow, $_POST; + $pagenow = 'admin-ajax.php'; + wp_set_current_user( 1 ); + faustwp_update_setting( 'frontend_uri', 'http://moo' ); + faustwp_update_setting( 'enable_rewrites', '1' ); + add_filter( 'wp_doing_ajax', '__return_true' ); + $_POST['_ajax_linking_nonce'] = wp_create_nonce( 'internal-linking' ); + $_POST['action'] = 'wp-link-ajax'; + + self::assertSame( 'http://example.org/hello-world', post_link( 'http://example.org/hello-world' ) ); + + unset( $_POST['_ajax_linking_nonce'], $_POST['action'] ); + unset( $pagenow ); + remove_filter( 'wp_doing_ajax', '__return_true' ); + wp_set_current_user( null ); + } + /** * Tests get_preview_post_link() returns rewritten value. */ @@ -203,7 +244,7 @@ public function test_post_preview_link_uses_frontend_uri_scheme() { public function test_custom_post_type_post_preview_link_returns_filtered_link_when_content_replacement_is_enabled() { faustwp_update_setting( 'frontend_uri', 'http://moo' ); - faustwp_update_setting( 'enable_rewrites', true ); + faustwp_update_setting( 'enable_rewrites', '1' ); $post_id = $this->getCustomPostType(); $this->assertSame( 'http://moo/?document=' . $post_id . '&preview=true&previewPathname=' . rawurlencode( wp_make_link_relative( get_permalink( $post_id ) ) ) . '&p=' . $post_id . '&typeName=Document', get_preview_post_link( $post_id ) ); faustwp_update_setting( 'frontend_uri', null ); @@ -216,7 +257,7 @@ public function test_custom_post_type_post_preview_link_returns_filtered_link_wh public function test_custom_post_type_post_link_returns_unfiltered_link_when_content_replacement_is_enabled() { faustwp_update_setting( 'frontend_uri', 'http://moo' ); - faustwp_update_setting( 'enable_rewrites', true ); + faustwp_update_setting( 'enable_rewrites', '1' ); $post_id = $this->getCustomPostType(); $this->assertSame( 'http://example.org/?document=' . $post_id, get_permalink($post_id) ); faustwp_update_setting( 'frontend_uri', null );