Skip to content

Commit

Permalink
MERL-1228: Fix issue with rewriting links to front end (#1624)
Browse files Browse the repository at this point in the history
* test: confirm content replacement behavior with a mixed content blob

* test: confirm unrelated URLs are untouched

* chore: add `use_wp_domain_for_post_and_category_urls()` function.

Determines if post and category URLs should link to the WP site.

* chore: add `use_wp_domain_for_media()` function.

Determines if WP media URLs should link to the WP site.

* chore: remove callback attached to `graphql_request_results` filter

* chore: use new `use_wp_domain_for_post_and_category_urls()` function inside `domain_replacement_enabled()`

* fix: adjust content replacement logic to avoid rewriting media links incorrectly

* filter block content via `wpgraphql_content_blocks_resolver_content`

* refactor: Adjust logic in `image_source_srcset_replacement`

* chore: add changeset
  • Loading branch information
mindctrl authored Nov 15, 2023
1 parent 77da190 commit 78a061a
Show file tree
Hide file tree
Showing 7 changed files with 121 additions and 30 deletions.
5 changes: 5 additions & 0 deletions .changeset/four-books-invent.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@faustwp/wordpress-plugin': patch
---

Fixed a bug that caused links to files in wp-content to be rewritten to the Faust Front-end site URL when they should not have been.
68 changes: 51 additions & 17 deletions plugins/faustwp/includes/replacement/callbacks.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
use function WPE\FaustWP\Settings\{
faustwp_get_setting,
is_image_source_replacement_enabled,
is_rewrites_enabled
is_rewrites_enabled,
use_wp_domain_for_media,
use_wp_domain_for_post_and_category_urls,
};
use function WPE\FaustWP\Utilities\{
plugin_version,
Expand All @@ -21,32 +23,49 @@
}

add_filter( 'the_content', __NAMESPACE__ . '\\content_replacement' );
add_filter( 'wpgraphql_content_blocks_resolver_content', __NAMESPACE__ . '\\content_replacement' );
/**
* Callback for WordPress 'the_content' filter.
*
* @param string $content The post content.
*
* @return string The post content.
* @todo Needs work...
*/
function content_replacement( $content ) {
if ( ! domain_replacement_enabled() ) {
$use_wp_domain_for_permalinks = ! domain_replacement_enabled();
$use_wp_domain_for_media = use_wp_domain_for_media();

if ( $use_wp_domain_for_permalinks && $use_wp_domain_for_media ) {
return $content;
}

$replacement = faustwp_get_setting( 'frontend_uri' );
$site_url = site_url();

if ( ! $replacement ) {
$replacement = '/';
}

$content = str_replace( "href=\"{$site_url}", "href=\"{$replacement}", $content );
$site_url = site_url();
$media_dir = str_replace( $site_url, '', wp_upload_dir()['baseurl'] );
$media_url = $site_url . $media_dir;

if ( $use_wp_domain_for_permalinks && ! $use_wp_domain_for_media ) {
$content = str_replace( $media_url, $replacement . $media_dir, $content );
return $content;
}

if ( ! $use_wp_domain_for_permalinks && ! $use_wp_domain_for_media ) {
$content = str_replace( $site_url, $replacement, $content );
return $content;
}

if ( ! $use_wp_domain_for_permalinks && $use_wp_domain_for_media ) {
$content = preg_replace( "#{$site_url}(?!{$media_dir})#", "{$replacement}", $content );
return $content;
}

return str_replace( 'href="//', 'href="/', $content );
return $content;
}

add_filter( 'the_content', __NAMESPACE__ . '\\image_source_replacement' );
/**
* Callback for WordPress 'the_content' filter to replace paths to media.
*
Expand Down Expand Up @@ -79,21 +98,36 @@ function image_source_replacement( $content ) {
* @return string One or more arrays of source data.
*/
function image_source_srcset_replacement( $sources ) {
if ( ! is_image_source_replacement_enabled() ) {
return $sources;
}
$use_wp_domain_for_media = use_wp_domain_for_media();
$frontend_uri = faustwp_get_setting( 'frontend_uri' );
$site_url = site_url();

/**
* For urls with no domain or the frontend domain, replace with the WP site_url.
* This was the default replacement pattern until Faust 1.2, at which point this
* was adjusted to correct replacement bugs.
*/
$patterns = array(
"#^{$site_url}/#",
'#^/#',
);

$frontend_uri = faustwp_get_setting( 'frontend_uri' );
$site_url = site_url();
$replacement = $frontend_uri;

if ( is_array( $sources ) ) {
// For urls with no domain or the frontend domain, replace with the wp site_url.
$patterns = array(
/**
* If using WP domain for media and a frontend URL is encountered, rewrite it to WP URL.
*/
if ( $use_wp_domain_for_media ) {
$patterns = array(
"#^{$frontend_uri}/#",
'#^/#',
);
$replacement = $site_url;
}

if ( is_array( $sources ) ) {
foreach ( $sources as $width => $source ) {
$sources[ $width ]['url'] = preg_replace( $patterns, "$site_url/", $sources[ $width ]['url'] );
$sources[ $width ]['url'] = preg_replace( $patterns, "$replacement/", $source['url'] );
}
}

Expand Down
7 changes: 3 additions & 4 deletions plugins/faustwp/includes/replacement/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@

use function WPE\FaustWP\Settings\{
faustwp_get_setting,
is_rewrites_enabled
is_rewrites_enabled,
use_wp_domain_for_post_and_category_urls,
};

if ( ! defined( 'ABSPATH' ) ) {
Expand All @@ -19,8 +20,6 @@
/**
* Determine if domain replacement can be done.
*
* Enabled if query string parameter 'replace-domain' is present.
*
* @return bool True if can proceed with replacement, false if else.
*/
function domain_replacement_enabled() {
Expand All @@ -31,7 +30,7 @@ function domain_replacement_enabled() {
*
* @param bool $enabled True if domain replacement is enabled, false if else.
*/
return apply_filters( 'faustwp_domain_replacement_enabled', is_rewrites_enabled() );
return apply_filters( 'faustwp_domain_replacement_enabled', ! use_wp_domain_for_post_and_category_urls() );
}

/**
Expand Down
1 change: 0 additions & 1 deletion plugins/faustwp/includes/replacement/graphql-callbacks.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
exit;
}

add_filter( 'graphql_request_results', __NAMESPACE__ . '\\url_replacement' );
/**
* Callback for WP GraphQL 'graphql_request_results' filter.
*
Expand Down
17 changes: 17 additions & 0 deletions plugins/faustwp/includes/settings/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,15 @@ function is_rewrites_enabled() {
return '1' === faustwp_get_setting( 'enable_rewrites' );
}

/**
* Determines if posts and category URLs should link to the WP site.
*
* @return bool
*/
function use_wp_domain_for_post_and_category_urls() {
return ! is_rewrites_enabled();
}

/**
* Determine if themes are disabled.
*
Expand All @@ -47,6 +56,14 @@ function is_image_source_replacement_enabled() {
return '1' === faustwp_get_setting( 'enable_image_source' );
}

/**
* Determine if sourcing images from WP domain is enabled.
*
* @return bool True if image sources from WP are enabled, false if else.
*/
function use_wp_domain_for_media() {
return is_image_source_replacement_enabled();
}

/**
* Get the secret key setting.
Expand Down
4 changes: 0 additions & 4 deletions plugins/faustwp/tests/integration/GraphQLCallbacksTests.php
Original file line number Diff line number Diff line change
Expand Up @@ -115,10 +115,6 @@ public function test_graphql_section_field_value() {
$this->assertSame( 10, has_action( 'graphql_get_setting_section_field_value', 'WPE\FaustWP\GraphQL\filter_introspection' ) );
}

public function test_graphql_request_results_filter() {
$this->assertSame( 10, has_action( 'graphql_request_results', 'WPE\FaustWP\Replacement\url_replacement' ) );
}

/**
* Tests url_replacement() returns original data when rewrites are not enabled.
*/
Expand Down
49 changes: 45 additions & 4 deletions plugins/faustwp/tests/integration/ReplacementCallbacksTests.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,6 @@ public function test_term_link_filter() {
$this->assertSame( 1000, has_action( 'term_link', 'WPE\FaustWP\Replacement\term_link' ) );
}

public function test_graphql_request_results_filter() {
$this->assertSame( 10, has_action( 'graphql_request_results', 'WPE\FaustWP\Replacement\url_replacement' ) );
}

public function test_enqueue_preview_scripts_action() {
$this->assertSame( 10, has_action( 'enqueue_block_editor_assets', 'WPE\FaustWP\Replacement\enqueue_preview_scripts' ) );
}
Expand All @@ -68,6 +64,10 @@ public function test_wpseo_xml_sitemap_post_url_filter() {
$this->assertSame( 10, has_action( 'wpseo_xml_sitemap_post_url', 'WPE\FaustWP\Replacement\yoast_sitemap_post_url' ) );
}

public function test_wp_calculate_image_srcset_filter(): void {
self::assertSame( 10, has_action( 'wp_calculate_image_srcset', 'WPE\FaustWP\Replacement\image_source_srcset_replacement' ) );
}

/**
* Tests content_replacement() returns original value when content replacement is not enabled.
*/
Expand Down Expand Up @@ -131,6 +131,9 @@ public function test_image_source_srcset_replacement_filters_content_when_image_
public function test_image_source_replacement_filters_content_when_image_replacement_not_enabled() {
faustwp_update_setting( 'enable_image_source', '0' );
$this->assertSame( '<img src="/image.png">', image_source_replacement( '<img src="/image.png">' ) );

// Ensure unrelated domains are left alone.
$this->assertSame( '<img src="http://fake/image.png">', image_source_replacement( '<img src="http://fake/image.png">' ) );
}

/**
Expand Down Expand Up @@ -255,6 +258,44 @@ public function test_term_link_returns_filtered_link_when_rewrite_term_links_ena
$this->assertSame( 'http://moo/?cat=' . $term_id, get_term_link( $term_id ) );
}

/**
* Tests content_replacement() handles mixed content blobs properly.
*/
public function test_content_replacement_properly_handles_a_mixed_content_blob() {
faustwp_update_setting( 'frontend_uri', 'http://moo' );
faustwp_update_setting( 'enable_image_source', '1' );
faustwp_update_setting( 'enable_rewrites', '1' );

$input = <<<INPUT
<p>This is a <a href="http://example.org/hello-world/" data-type="post" data-id="1">post link</a>.</p><p>This is a <a href="http://example.org/wp-content/uploads/2023/10/out-of-the-tar-pit.pdf" data-type="attachment" data-id="12">media link</a> to a PDF file.</p><p>This is a <a href="http://example.org/wp-content/uploads/2023/10/IMG_8963-scaled.jpg" data-type="attachment" data-id="15">media link</a> to an image.</p>
INPUT;

$output = <<<OUTPUT
<p>This is a <a href="http://moo/hello-world/" data-type="post" data-id="1">post link</a>.</p><p>This is a <a href="http://example.org/wp-content/uploads/2023/10/out-of-the-tar-pit.pdf" data-type="attachment" data-id="12">media link</a> to a PDF file.</p><p>This is a <a href="http://example.org/wp-content/uploads/2023/10/IMG_8963-scaled.jpg" data-type="attachment" data-id="15">media link</a> to an image.</p>
OUTPUT;

self::assertSame(
$output,
content_replacement( $input )
);

// Check that media URLs are rewritten when enable_image_source setting is configured to NOT use the WP domain.
faustwp_update_setting( 'enable_image_source', '0' );

$input = <<<INPUT
<p>This is a <a href="http://example.org/hello-world/" data-type="post" data-id="1">post link</a>.</p><p>This is a <a href="http://example.org/wp-content/uploads/2023/10/out-of-the-tar-pit.pdf" data-type="attachment" data-id="12">media link</a> to a PDF file.</p><p>This is a <a href="http://example.org/wp-content/uploads/2023/10/IMG_8963-scaled.jpg" data-type="attachment" data-id="15">media link</a> to an image.</p>
INPUT;

$output = <<<OUTPUT
<p>This is a <a href="http://moo/hello-world/" data-type="post" data-id="1">post link</a>.</p><p>This is a <a href="http://moo/wp-content/uploads/2023/10/out-of-the-tar-pit.pdf" data-type="attachment" data-id="12">media link</a> to a PDF file.</p><p>This is a <a href="http://moo/wp-content/uploads/2023/10/IMG_8963-scaled.jpg" data-type="attachment" data-id="15">media link</a> to an image.</p>
OUTPUT;

self::assertSame(
$output,
content_replacement( $input )
);
}

private function getCustomPostType() {
register_post_type('document', [
'public' => true,
Expand Down

0 comments on commit 78a061a

Please sign in to comment.