diff --git a/packages/block-library/src/media-text/index.php b/packages/block-library/src/media-text/index.php index f828aed645fb1..87be164a04bb9 100644 --- a/packages/block-library/src/media-text/index.php +++ b/packages/block-library/src/media-text/index.php @@ -29,28 +29,78 @@ function render_block_core_media_text( $attributes, $content ) { return $content; } - $image_tag = '
'; - $content = preg_replace( '//', $image_tag, $content ); + $media_tag_processor = new WP_HTML_Tag_Processor( $content ); + $wrapping_figure_query = array( + 'tag_name' => 'figure', + 'class_name' => 'wp-block-media-text__media', + ); + $has_media_on_right = isset( $attributes['mediaPosition'] ) && 'right' === $attributes['mediaPosition']; + $image_fill = isset( $attributes['imageFill'] ) && $attributes['imageFill']; + $focal_point = isset( $attributes['focalPoint'] ) ? round( $attributes['focalPoint']['x'] * 100 ) . '% ' . round( $attributes['focalPoint']['y'] * 100 ) . '%' : '50% 50%'; + $unique_id = 'wp-block-media-text__media-' . wp_unique_id(); - $processor = new WP_HTML_Tag_Processor( $content ); - if ( isset( $attributes['imageFill'] ) && $attributes['imageFill'] ) { - $position = '50% 50%'; - if ( isset( $attributes['focalPoint'] ) ) { - $position = round( $attributes['focalPoint']['x'] * 100 ) . '% ' . round( $attributes['focalPoint']['y'] * 100 ) . '%'; + if ( $has_media_on_right ) { + // Loop through all the figure tags and set a bookmark on the last figure tag. + while ( $media_tag_processor->next_tag( $wrapping_figure_query ) ) { + $media_tag_processor->set_bookmark( 'last_figure' ); + } + if ( $media_tag_processor->has_bookmark( 'last_figure' ) ) { + $media_tag_processor->seek( 'last_figure' ); + if ( $image_fill ) { + $media_tag_processor->set_attribute( 'style', 'background-image:url(' . esc_url( $current_featured_image ) . ');background-position:' . $focal_point . ';' ); + } else { + // Insert a unique ID to identify the figure tag. + $media_tag_processor->set_attribute( 'id', $unique_id ); + } + } + } else { + if ( $media_tag_processor->next_tag( $wrapping_figure_query ) ) { + if ( $image_fill ) { + $media_tag_processor->set_attribute( 'style', 'background-image:url(' . esc_url( $current_featured_image ) . ');background-position:' . $focal_point . ';' ); + } else { + // Insert a unique ID to identify the figure tag. + $media_tag_processor->set_attribute( 'id', $unique_id ); + } } - $processor->next_tag( 'figure' ); - $processor->set_attribute( 'style', 'background-image:url(' . esc_url( $current_featured_image ) . ');background-position:' . $position . ';' ); - } - $processor->next_tag( 'img' ); - $media_size_slug = 'full'; - if ( isset( $attributes['mediaSizeSlug'] ) ) { - $media_size_slug = $attributes['mediaSizeSlug']; } - $processor->set_attribute( 'src', esc_url( $current_featured_image ) ); - $processor->set_attribute( 'class', 'wp-image-' . get_post_thumbnail_id() . ' size-' . $media_size_slug ); - $processor->set_attribute( 'alt', trim( strip_tags( get_post_meta( get_post_thumbnail_id(), '_wp_attachment_image_alt', true ) ) ) ); - $content = $processor->get_updated_html(); + $content = $media_tag_processor->get_updated_html(); + + // If the image is not set to fill, add the image tag inside the figure tag, + // and update the image attributes in order to display the featured image. + if ( ! $image_fill ) { + $media_size_slug = isset( $attributes['mediaSizeSlug'] ) ? $attributes['mediaSizeSlug'] : 'full'; + $image_tag = ''; + $content = preg_replace( + '/()/', + '$1' . $image_tag, + $content + ); + + $image_tag_processor = new WP_HTML_Tag_Processor( $content ); + if ( $image_tag_processor->next_tag( + array( + 'tag_name' => 'figure', + 'id' => $unique_id, + ) + ) ) { + // The ID is only used to ensure that the correct figure tag is selected, + // and can now be removed. + $image_tag_processor->remove_attribute( 'id' ); + if ( $image_tag_processor->next_tag( + array( + 'tag_name' => 'img', + 'class_name' => 'wp-block-media-text__featured_image', + ) + ) ) { + $image_tag_processor->set_attribute( 'src', esc_url( $current_featured_image ) ); + $image_tag_processor->set_attribute( 'class', 'wp-image-' . get_post_thumbnail_id() . ' size-' . $media_size_slug ); + $image_tag_processor->set_attribute( 'alt', trim( strip_tags( get_post_meta( get_post_thumbnail_id(), '_wp_attachment_image_alt', true ) ) ) ); + + $content = $image_tag_processor->get_updated_html(); + } + } + } return $content; } diff --git a/phpunit/blocks/render-block-media-text-test.php b/phpunit/blocks/render-block-media-text-test.php new file mode 100644 index 0000000000000..94c184408c89f --- /dev/null +++ b/phpunit/blocks/render-block-media-text-test.php @@ -0,0 +1,179 @@ +post->create_and_get(); + $file = DIR_TESTDATA . '/images/canola.jpg'; + + self::$attachment_id = self::factory()->attachment->create_upload_object( + $file, + self::$post->ID, + array( + 'post_mime_type' => 'image/jpeg', + ) + ); + + set_post_thumbnail( self::$post, self::$attachment_id ); + } + + /** + * Tear down method. + */ + public static function wpTearDownAfterClass() { + wp_delete_post( self::$post->ID, true ); + wp_delete_post( self::$attachment_id, true ); + } + + /** + * Helper method for $wp_query. + */ + public static function setup_query() { + global $wp_query; + $wp_query->in_the_loop = true; + $wp_query->post = self::$post; + $wp_query->posts = array( self::$post ); + $GLOBALS['post'] = self::$post; + } + + /** + * Test gutenberg_render_block_core_media_text with the featured image on the left. + */ + public function test_render_block_core_media_text_featured_image() { + $this->setup_query(); + + $content = '

'; + + // Assert that the rendered block contains the featured image. + $attributes = array( + 'useFeaturedImage' => true, + ); + $rendered = gutenberg_render_block_core_media_text( $attributes, $content ); + $this->assertStringContainsString( ' true, + 'imageFill' => true, + ); + $rendered = gutenberg_render_block_core_media_text( $attributes, $content ); + $this->assertStringContainsString( 'background-image:url(' . wp_get_attachment_image_url( self::$attachment_id, 'full' ) . ')', $rendered ); + $this->assertStringNotContainsString( 'setup_query(); + $content = '

'; + + // Assert that the rendered block contains the featured image. + $attributes = array( + 'useFeaturedImage' => true, + ); + $rendered = gutenberg_render_block_core_media_text( $attributes, $content ); + $this->assertStringContainsString( ' true, + 'imageFill' => true, + ); + $rendered = gutenberg_render_block_core_media_text( $attributes, $content ); + $this->assertStringContainsString( 'background-image:url(' . wp_get_attachment_image_url( self::$attachment_id, 'full' ) . ')', $rendered ); + $this->assertStringNotContainsString( 'setup_query(); + + $content = '

'; + + // Assert that the rendered block contains the featured image when media is on the right. + $attributes = array( + 'useFeaturedImage' => true, + 'mediaPosition' => 'right', + ); + $rendered = gutenberg_render_block_core_media_text( $attributes, $content ); + $this->assertStringContainsString( ' true, + 'mediaPosition' => 'right', + 'imageFill' => true, + ); + $rendered = gutenberg_render_block_core_media_text( $attributes, $content ); + $this->assertStringContainsString( 'background-image:url(' . wp_get_attachment_image_url( self::$attachment_id, 'full' ) . ')', $rendered ); + $this->assertStringNotContainsString( 'setup_query(); + + $content = '

'; + + // Assert that the rendered block contains the featured image when media is on the right. + $attributes = array( + 'useFeaturedImage' => true, + 'mediaPosition' => 'right', + ); + + $rendered = gutenberg_render_block_core_media_text( $attributes, $content ); + $this->assertStringContainsString( ' true, + 'mediaPosition' => 'right', + 'imageFill' => true, + ); + + $rendered = gutenberg_render_block_core_media_text( $attributes, $content ); + $this->assertStringContainsString( 'background-image:url(' . wp_get_attachment_image_url( self::$attachment_id, 'full' ) . ')', $rendered ); + $this->assertStringNotContainsString( '