Skip to content
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

Add replacing of images only in frontend context #424

Merged
merged 8 commits into from
Jul 14, 2022
23 changes: 23 additions & 0 deletions modules/images/webp-uploads/helper.php
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,29 @@ function webp_uploads_get_attachment_sources( $attachment_id, $size = 'thumbnail
return array();
}

/**
* Verifies if the request is for a frontend context within the <body> tag.
*
* @since n.e.x.t
*
* @return bool True if in the <body> within a frontend request, false otherwise.
*/
function webp_uploads_in_frontend_body() {
global $wp_query;

// Check if this request is generally outside (or before) any frontend context.
if ( ! isset( $wp_query ) || defined( 'REST_REQUEST' ) || defined( 'XMLRPC_REQUEST' ) || is_feed() ) {
return false;
}

// Check if we're anywhere before 'template_redirect' or within the 'wp_head' action.
if ( ! did_action( 'template_redirect' ) || doing_action( 'wp_head' ) ) {
return false;
}

return true;
}

/**
* Check whether the additional image is larger than the original image.
*
Expand Down
5 changes: 5 additions & 0 deletions modules/images/webp-uploads/load.php
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,11 @@ function webp_uploads_remove_sources_files( $attachment_id ) {
* @return string The content with the updated references to the images.
*/
function webp_uploads_update_image_references( $content ) {
// Bail early if request is not for the frontend.
if ( ! webp_uploads_in_frontend_body() ) {
return $content;
}

// This content does not have any tag on it, move forward.
if ( ! preg_match_all( '/<(img)\s[^>]+>/', $content, $img_tags, PREG_SET_ORDER ) ) {
return $content;
Expand Down
53 changes: 53 additions & 0 deletions tests/modules/images/webp-uploads/helper-tests.php
Original file line number Diff line number Diff line change
Expand Up @@ -454,4 +454,57 @@ public function it_should_never_discard_additional_image_if_filter_is_false( $or
$output = webp_uploads_should_discard_additional_image_file( $original_filesize, $additional_filesize );
$this->assertFalse( $output );
}

public function test_webp_uploads_in_frontend_body_without_wp_query() {
unset( $GLOBALS['wp_query'] );

$this->assertFalse( webp_uploads_in_frontend_body() );
}

public function test_webp_uploads_in_frontend_body_with_feed() {
$this->mock_empty_action( 'template_redirect' );
$GLOBALS['wp_query']->is_feed = true;

$this->assertFalse( webp_uploads_in_frontend_body() );
}

public function test_webp_uploads_in_frontend_body_without_template_redirect() {
$this->assertFalse( webp_uploads_in_frontend_body() );
}

public function test_webp_uploads_in_frontend_body_before_template_redirect() {
$result = webp_uploads_in_frontend_body();
$this->mock_empty_action( 'template_redirect' );

$this->assertFalse( $result );
}

public function test_webp_uploads_in_frontend_body_after_template_redirect() {
$this->mock_empty_action( 'template_redirect' );
$result = webp_uploads_in_frontend_body();

$this->assertTrue( $result );
}

public function test_webp_uploads_in_frontend_body_within_wp_head() {
Comment on lines +457 to +489
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More of nit-pick here but the test function names are different than what we actually use the names here like it_should or it_ like that. And these functions doesn't have function doc comment.

cc: @felixarntz @akshitsethi

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mehulkaklotar I didn't think it was too critical to point it out in earlier tests for the plugin, but the convention for WordPress core tests is to always use test_ followed by the function name, then optionally anything else. So I stuck with that here.

I would advise to follow that convention for future tests to monitor the core plan.

Regarding doc comments, test methods do not require any doc comments per core specifications - only when helpful. Preferably, the name of the method should be clear enough to know what is going on, or when it makes sense to clarify specific code, inline comments should be used.

cc @akshitsethi @adamsilverstein @mukeshpanchal27 @jjgrainger @eugene-manuilov

$this->mock_empty_action( 'template_redirect' );

// Call function within a 'wp_head' callback.
remove_all_actions( 'wp_head' );
$result = null;
add_action(
'wp_head',
function() use ( &$result ) {
$result = webp_uploads_in_frontend_body();
}
);
do_action( 'wp_head' );

$this->assertFalse( $result );
}

private function mock_empty_action( $action ) {
remove_all_actions( $action );
do_action( $action );
}
}
20 changes: 20 additions & 0 deletions tests/modules/images/webp-uploads/load-tests.php
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,9 @@ public function it_should_remove_the_backup_sizes_and_sources_if_the_attachment_
* @test
*/
public function it_should_avoid_the_change_of_urls_of_images_that_are_not_part_of_the_media_library() {
// Run critical hooks to satisfy webp_uploads_in_frontend_body() conditions.
$this->mock_frontend_body_hooks();

$paragraph = '<p>Donec accumsan, sapien et <img src="https://ia600200.us.archive.org/16/items/SPD-SLRSY-1867/hubblesite_2001_06.jpg">, id commodo nisi sapien et est. Mauris nisl odio, iaculis vitae pellentesque nec.</p>';

$this->assertSame( $paragraph, webp_uploads_update_image_references( $paragraph ) );
Expand All @@ -343,6 +346,9 @@ public function it_should_avoid_the_change_of_urls_of_images_that_are_not_part_o
* @test
*/
public function it_should_avoid_replacing_not_existing_attachment_i_ds() {
// Run critical hooks to satisfy webp_uploads_in_frontend_body() conditions.
$this->mock_frontend_body_hooks();

$paragraph = '<p>Donec accumsan, sapien et <img class="wp-image-0" src="https://ia600200.us.archive.org/16/items/SPD-SLRSY-1867/hubblesite_2001_06.jpg">, id commodo nisi sapien et est. Mauris nisl odio, iaculis vitae pellentesque nec.</p>';

$this->assertSame( $paragraph, webp_uploads_update_image_references( $paragraph ) );
Expand Down Expand Up @@ -384,6 +390,9 @@ public function it_should_prevent_replacing_a_jpg_image_if_the_image_does_not_ha
TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leafs.jpg'
);

// Run critical hooks to satisfy webp_uploads_in_frontend_body() conditions.
$this->mock_frontend_body_hooks();

$tag = wp_get_attachment_image( $attachment_id, 'medium' );

$this->assertSame( $tag, webp_uploads_update_image_references( $tag ) );
Expand Down Expand Up @@ -729,6 +738,9 @@ public function it_should_add_fallback_script_if_content_has_updated_images() {
TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leafs.jpg'
);

// Run critical hooks to satisfy webp_uploads_in_frontend_body() conditions.
$this->mock_frontend_body_hooks();

apply_filters(
'the_content',
sprintf(
Expand Down Expand Up @@ -803,4 +815,12 @@ public function it_should_create_mime_types_for_allowed_sizes_only_via_global_va
$this->assertImageHasSizeSource( $attachment_id, 'allowed_size_400x300', 'image/webp' );
$this->assertImageNotHasSizeSource( $attachment_id, 'not_allowed_size_200x150', 'image/webp' );
}

/**
* Runs (empty) hooks to satisfy webp_uploads_in_frontend_body() conditions.
*/
private function mock_frontend_body_hooks() {
remove_all_actions( 'template_redirect' );
do_action( 'template_redirect' );
}
}