Skip to content

Commit

Permalink
Media & text: Update the image replacement logic (#62030)
Browse files Browse the repository at this point in the history
* Media & Text: Update the image replacement logic for the featured image. Add a PHPUnit test class for testing the insertion of the featured image.

---------

Co-authored-by: carolinan <poena@git.wordpress.org>
Co-authored-by: ramonjd <ramonopoly@git.wordpress.org>
Co-authored-by: dmsnell <dmsnell@git.wordpress.org>
  • Loading branch information
4 people committed Jun 19, 2024
1 parent 6d52495 commit 9e53779
Show file tree
Hide file tree
Showing 2 changed files with 247 additions and 18 deletions.
86 changes: 68 additions & 18 deletions packages/block-library/src/media-text/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,28 +29,78 @@ function render_block_core_media_text( $attributes, $content ) {
return $content;
}

$image_tag = '<figure class="wp-block-media-text__media"><img>';
$content = preg_replace( '/<figure\s+class="wp-block-media-text__media">/', $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 = '<img class="wp-block-media-text__featured_image">';
$content = preg_replace(
'/(<figure\s+id="' . preg_quote( $unique_id, '/' ) . '"\s+class="wp-block-media-text__media"\s*>)/',
'$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;
}
Expand Down
179 changes: 179 additions & 0 deletions phpunit/blocks/render-block-media-text-test.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
<?php
/**
* Media & Text block rendering tests.
*
* @package WordPress
* @subpackage Blocks
*/

/**
* Tests for the Media & Text block.
*
* @group blocks
*
* @covers ::render_block_core_media_text
*/
class Render_Block_MediaText_Test extends WP_UnitTestCase {

/**
* Post object.
*
* @var WP_Post
*/
protected static $post;

/**
* Attachment id.
*
* @var int
*/
protected static $attachment_id;

/**
* Setup method.
*/
public static function wpSetUpBeforeClass() {
self::$post = self::factory()->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 = '<div class="wp-block-media-text is-stacked-on-mobile"><figure class="wp-block-media-text__media"></figure><div class="wp-block-media-text__content"><p></p></div></div>';

// Assert that the rendered block contains the featured image.
$attributes = array(
'useFeaturedImage' => true,
);
$rendered = gutenberg_render_block_core_media_text( $attributes, $content );
$this->assertStringContainsString( '<img alt="" src="' . wp_get_attachment_image_url( self::$attachment_id, 'full' ) . '"', $rendered );

// Assert that the rendered block contains the featured image as the background-image url,
// and not the image element, when image fill is true.
$attributes = array(
'useFeaturedImage' => 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( '<img', $rendered );
}

/**
* Test gutenberg_render_block_core_media_text with the featured image on the left,
* and a second media & text block nested inside the content area.
*/
public function test_render_block_core_media_text_featured_image_nested() {
$this->setup_query();
$content = '<div class="wp-block-media-text is-stacked-on-mobile"><figure class="wp-block-media-text__media"></figure><div class="wp-block-media-text__content"><div class="wp-block-media-text is-stacked-on-mobile"><figure class="wp-block-media-text__media"></figure><div class="wp-block-media-text__content"><p></p></div></div></div></div>';

// Assert that the rendered block contains the featured image.
$attributes = array(
'useFeaturedImage' => true,
);
$rendered = gutenberg_render_block_core_media_text( $attributes, $content );
$this->assertStringContainsString( '<img alt="" src="' . wp_get_attachment_image_url( self::$attachment_id, 'full' ) . '"', $rendered );

// Assert that the rendered block contains the featured image as the background-image url,
// and not the image element, when image fill is true.
$attributes = array(
'useFeaturedImage' => 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( '<img', $rendered );
}

/**
* Test gutenberg_render_block_core_media_text with the featured image on the right.
*/
public function test_render_block_core_media_text_featured_image_media_on_right() {
$this->setup_query();

$content = '<div class="wp-block-media-text has-media-on-the-right is-stacked-on-mobile"><div class="wp-block-media-text__content"><p></p></div><figure class="wp-block-media-text__media"></figure></div>';

// 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( '<img alt="" src="' . wp_get_attachment_image_url( self::$attachment_id, 'full' ) . '"', $rendered );

// Assert that the rendered block contains the featured image as the background-image url,
// and not the image element, when image fill is true and the media is on the right.
$attributes = array(
'useFeaturedImage' => 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( '<img', $rendered );
}

/**
* Test gutenberg_render_block_core_media_text with the featured image on the right,
* and a second media & text block nested inside the content area.
*/
public function test_render_block_core_media_text_featured_image_media_on_right_nested() {
$this->setup_query();

$content = '<div class="wp-block-media-text has-media-on-the-right is-stacked-on-mobile"><div class="wp-block-media-text__content"><div class="wp-block-media-text is-stacked-on-mobile"><div class="wp-block-media-text__content"><p></p></div><figure class="wp-block-media-text__media"></figure></div></div><figure class="wp-block-media-text__media"></figure></div>';

// 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( '<img alt="" src="' . wp_get_attachment_image_url( self::$attachment_id, 'full' ) . '"', $rendered );

// Assert that the rendered block contains the featured image as the background-image url,
// and not the image element, when image fill is true and the media is on the right.
$attributes = array(
'useFeaturedImage' => 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( '<img', $rendered );
}
}

0 comments on commit 9e53779

Please sign in to comment.