-
Notifications
You must be signed in to change notification settings - Fork 137
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Bug: Fixes issues for content replacement for the site and media URLs #2014
base: canary
Are you sure you want to change the base?
Conversation
… and also updates tests to use WP 6.6 and 6.7 Fixes various issues with using content replacement for the site URL.
🦋 Changeset detectedLatest commit: e37f7b0 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
📦 Next.js Bundle Analysis for @faustwp/getting-started-exampleThis analysis was generated by the Next.js Bundle Analysis action. 🤖 This PR introduced no changes to the JavaScript bundle! 🙌 |
@josephfusco This is the draft PR for the site URL issues. This fixes the various issues as per our call last week but I also want to update the image srcset replacement with the same functionality so that we replace all HTTP protocols e.g. HTTP, HTTPS or // |
Just noting I am working on also updating the image_source_srcset_replacement function callback aswell to use all HTTP protocols so I will have an updated PR next week after the holidays. |
Awesome! |
Thanks @theodesp I have also now updated the PR with details on how to replicate the issue and test the issue. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
…ng for cotent replacement.
Can you give this another review please. Thanks @whoami-pwd for the suggestions around optimizing some the loops on our call earlier. I have tested locally again the different config for URLs and it is all working as expected but if you could test aswell that would be great please👍 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work on addressing these issues! Please check the comments for a few suggestions.
* | ||
* @return string The replaced string | ||
*/ | ||
function faustwp_replace_media_url( string $content, array $wp_media_urls, string $replace_url ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure if this function is needed. It looks like a wrapper to the str_replace
with an alternative parameters order.
Please remember that the str_replace
can also accept the array as a search param, so no need to loop through each one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We use this function in 2 places.Happy to extract the functionality out if you prefer?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, my point is that the function itself is just a wrapper for the str_replace
. We don't actually do anything except calling the str_replace
here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah sorry I see your point now. I will remove it as a function should really be doing more that one operation
* | ||
* @return mixed The replaced content | ||
*/ | ||
function faustwp_replace_urls( array $patterns, mixed $wp_site_urls, mixed $content ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe it is better for us to keep things more simple here. Let's try to avoid using that function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @whoami-pwd
I was hoping to re-use that function when I built it, but it is only used once so I will remove it 👍
/** | ||
* Get all site URLs for each possible HTTP protocol | ||
*/ | ||
function faustwp_get_wp_site_urls() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you please add the return type here and to the phpdoc?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good spot 💯
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated 👍
return apply_filters( 'faustwp_get_wp_site_urls', array( $site_url ) ); | ||
} | ||
|
||
$is_https = substr( $site_url, 0, 6 ) === 'https:'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
strpos
can be faster for same purpose.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks good to know 😄
$host_url = wp_parse_url( $site_url, PHP_URL_HOST ); | ||
|
||
if ( ! is_string( $host_url ) ) { | ||
return apply_filters( 'faustwp_get_wp_site_urls', array( $site_url ) ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we can reduce the function length and get rid off one return?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This probably isn't needed as the site url should be a string anyway.
$content = preg_replace( "#{$site_url}(?!{$media_dir})#", "{$replacement}", $content ); | ||
return $content; | ||
foreach ( $wp_site_urls as $site_url ) { | ||
$pattern_exclude_media_urls = '#' . preg_quote( $site_url, '#' ) . "(?!{$relative_upload_url}(\/|$))#"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe that we can implode the urls into the pattern itself instead of preg_replace it multiple times inside foreach. I guess if the urls array is less then ~50 it is faster and more compact.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried to use implode but the only way I was able to do this is with array map. I don't know if the performance is worth it compared to readibility as I find the array map part not very readable.
$pattern_exclude_media_urls = '#(' . implode( '|', array_map( function( $url ) {
return preg_quote( $url, '#' );
}, $wp_site_urls ) ) . ")(?!{$relative_upload_url}(\/|$))#";
return preg_replace( $pattern_exclude_media_urls, $frontend_uri, $content );
Happy for a better suggesting on how to do the implode part 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was actually able to tidy up the array_map based on your suggestion above so thanks 😄
@@ -95,40 +102,43 @@ function image_source_replacement( $content ) { | |||
* | |||
* @param array $sources One or more arrays of source data to include in the 'srcset'. | |||
* | |||
* @return string One or more arrays of source data. | |||
* @return array One or more arrays of source data. | |||
*/ | |||
function image_source_srcset_replacement( $sources ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we need to improve the function a little bit. It is definitely worth to keep initial comments here. And I guess there is a chance for us to make it more readable along with more compact.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah that was updated when I ran the phpcbf fix
I will look at seeing what we can improve in terms of readability..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated PHPDocs 👍
$upload_dir = wp_upload_dir()['baseurl']; | ||
|
||
foreach ( $site_urls as $site_url ) { | ||
if ( false !== strpos( $upload_dir, $site_url ) ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are we checking if it starts with or contains?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We cannot use str_starts_with as we need to support PHP 7. I will look at updating this to check if it starts with the site URL
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I mean that strpos($haystack, $needle) === 0
verifies if it starts with and strpos($haystack, $needle) !== false
that it contains.
Thanks @whoami-pwd for the great code review 👍 Can you review the changes in the latest commit please. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work! I appreciate the updates you've made. There are still a couple of areas where we could improve the code quality/performance. Feel free to reach out if you have any questions.
* @return array<string> The array of media Urls | ||
*/ | ||
function faustwp_get_wp_media_urls( array $wp_site_urls ) { | ||
$upload_url = faustwp_get_relative_upload_url( $wp_site_urls ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can just pass the $upload_url
here as a parameter, then we won't need to call it once again inside the function.
* | ||
* @return string The replaced string | ||
*/ | ||
function faustwp_replace_media_url( string $content, array $wp_media_urls, string $replace_url ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, my point is that the function itself is just a wrapper for the str_replace
. We don't actually do anything except calling the str_replace
here.
function faustwp_get_wp_media_urls( array $wp_site_urls ) { | ||
$upload_url = faustwp_get_relative_upload_url( $wp_site_urls ); | ||
|
||
if ( ! is_string( $upload_url ) ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And then we will not need the extra verification like this, because we will force parameter with string type.
|
||
$wp_media_urls = faustwp_get_wp_media_urls( $wp_site_urls ); | ||
$relative_upload_url = faustwp_get_relative_upload_url( $wp_site_urls ); | ||
$frontend_uri = faustwp_get_setting( 'frontend_uri' ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please typecast here to make sure it is string with some default value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not allowed by our phpcs settings 😅
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry I was wrong here.
'#^/#', | ||
); | ||
|
||
$replacement = $frontend_uri; | ||
foreach ( $sources as $width => $source ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That would be great to improve this loop. Currently it has some memory/structure issues.
I believe that would be very helpful to have inline comments here to understand what the functionality is doing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No problem at all. I will add a few comments and review to see if we can remove the loop 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated. I added a comment about why we need to replace media srcsets when it is disabled.
We need to ensure that the wp site URL is used for both any FE URL or relative URL. The latter is a legacy issue.
See #1956
This fixes various issues for content replacement callback functions for both the site and media URLs. There is 2 main fixes in this branch.
The branch also adds 2 new filters to allow developers to modify the URLS used for content replacement
faustwp_get_wp_site_urls
- An array of site URLsfaustwp_get_wp_site_media_urls
- An array of media site URLsThis branch also updated Github actions to also use WordPress 6.6. and 6.7
Tasks
Description
See above.
Related Issue(s):
#1956
Testing
Setup
As per issue #1956 I setup a WordPress Multisite (sub-domains) with the latest version of 6.7.1 using Local.
I setup 3 sub-domains and installed FaustWP, WPGraphQL & ACF and one of the sites was setup as
http://alpha.multisite.local/
I setup a field group for pages and I setup a WYSIWG editor field with the field name
summary
I then updated the sample page to have an image for the WYSIWG field and also a link e.g.
I then used the following GraphQL query in the WPGraphQL IDE for debugging and fixing the issues
I then access the site on HTTPS rather than HTTP (site_url)
Tests
Note
http://localhost:3000
is the frontend URL set in Faust WP and I am accessing the site on HTTPS e.g.https://alpha.multisite.local/wp-admin/
Test 1: URL Rewrites Enabled
Query
Output
All 3 URLs (image src, srcset and link) were updated correctly to the frontend URL
http://localhost:3000/
Test 2: URL Rewrites Enabled and Media Rewrites Disabled
Query
Output
The image URL wasn't updated and the link was updated to the frontend URL.
Test 3: URL Rewrites Disabled and Media Rewrites Disabled
Query
Output
Neither the image src, srcset or link was updated to use the frontend URL
Test 4: URL Rewrites Disabled and Media Rewrites Enabled
Query
Output
Both the image src and srcset URLs were updated with the frontend URL where the link stayed the same
Screenshots
Documentation Changes
There was 2 new filters added
faustwp_get_wp_site_urls
for allowing developers to add or modify an array of site URLS used for content replacementfaustwp_get_wp_site_media_urls
for allowign developers to add or modify an array of media site URLS for content replacemntDependant PRs