Skip to content

Commit 2b192ca

Browse files
committed
Post Images from blocks: move from parse_blocks to Block_Delimiter
Following #43648, we can start using the new class to parse blocks. Internal reference: p7H4VZ-5l1-p2
1 parent 9830b75 commit 2b192ca

File tree

4 files changed

+150
-100
lines changed

4 files changed

+150
-100
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Significance: patch
2+
Type: enhancement
3+
4+
Sharing: improve the performance of Open Graph Meta Image tags.

projects/plugins/jetpack/class.jetpack-post-images.php

Lines changed: 88 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* @package automattic/jetpack
66
*/
77

8+
use Automattic\Block_Delimiter;
89
use Automattic\Jetpack\Image_CDN\Image_CDN_Core;
910

1011
/**
@@ -421,6 +422,7 @@ public static function from_thumbnail( $post_id, $width = 200, $height = 200 ) {
421422
* Get images from Gutenberg Image blocks.
422423
*
423424
* @since 6.9.0
425+
* @since $$next-version$$ Updated to use Block_Delimiter for improved performance.
424426
*
425427
* @param mixed $html_or_id The HTML string to parse for images, or a post id.
426428
* @param int $width Minimum Image width.
@@ -435,32 +437,36 @@ public static function from_blocks( $html_or_id, $width = 200, $height = 200 ) {
435437
return $images;
436438
}
437439

438-
// Look for block information in the HTML.
439-
$blocks = parse_blocks( $html_info['html'] );
440-
if ( empty( $blocks ) ) {
441-
return $images;
442-
}
443-
444440
/*
445-
* Let's loop through our blocks.
446-
* Some blocks may include some other blocks. Let's go 2 levels deep to look for blocks
447-
* that we support and that may include images (see get_images_from_block)
448-
*
449-
* @to-do: instead of looping manually (that's a lot of if and loops), search recursively instead.
441+
* Use Block_Delimiter to parse our post content HTML,
442+
* and find all the block delimiters for supported blocks,
443+
* whether they're parent or nested blocks.
450444
*/
451-
foreach ( $blocks as $block ) {
452-
if ( ! self::is_nested_block( $block ) || 'core/media-text' === $block['blockName'] ) {
453-
$images = self::get_images_from_block( $images, $block, $html_info, $width, $height );
454-
} else {
455-
foreach ( $block['innerBlocks'] as $inner_block ) {
456-
if ( ! self::is_nested_block( $inner_block ) ) {
457-
$images = self::get_images_from_block( $images, $inner_block, $html_info, $width, $height );
458-
} else {
459-
foreach ( $inner_block['innerBlocks'] as $inner_inner_block ) {
460-
$images = self::get_images_from_block( $images, $inner_inner_block, $html_info, $width, $height );
461-
}
462-
}
463-
}
445+
$supported_blocks = array(
446+
'core/image',
447+
'core/media-text',
448+
'core/gallery',
449+
'jetpack/tiled-gallery',
450+
'jetpack/slideshow',
451+
'jetpack/story',
452+
);
453+
454+
foreach ( Block_Delimiter::scan_delimiters( $html_info['html'] ) as $where => $delimiter ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
455+
// Only process opening delimiters for supported block types.
456+
if ( Block_Delimiter::OPENER !== $delimiter->get_delimiter_type() ) {
457+
continue;
458+
}
459+
460+
$block_type = $delimiter->allocate_and_return_block_type();
461+
if ( ! in_array( $block_type, $supported_blocks, true ) ) {
462+
continue;
463+
}
464+
465+
$attributes = $delimiter->allocate_and_return_parsed_attributes() ?? array();
466+
$block_images = self::get_images_from_block_attributes( $block_type, $attributes, $html_info, $width, $height );
467+
468+
if ( ! empty( $block_images ) ) {
469+
$images = array_merge( $images, $block_images );
464470
}
465471
}
466472

@@ -471,6 +477,64 @@ public static function from_blocks( $html_or_id, $width = 200, $height = 200 ) {
471477
return array_filter( $images );
472478
}
473479

480+
/**
481+
* Extract images from block attributes based on block type.
482+
*
483+
* @since $$next-version$$
484+
*
485+
* @param string $block_type Block type name.
486+
* @param array $attributes Block attributes.
487+
* @param array $html_info Info about the post where the block is found.
488+
* @param int $width Desired image width.
489+
* @param int $height Desired image height.
490+
*
491+
* @return array Array of images found.
492+
*/
493+
private static function get_images_from_block_attributes( $block_type, $attributes, $html_info, $width, $height ) {
494+
$images = array();
495+
496+
switch ( $block_type ) {
497+
case 'core/image':
498+
case 'core/media-text':
499+
$id_key = 'core/image' === $block_type ? 'id' : 'mediaId';
500+
if ( ! empty( $attributes[ $id_key ] ) ) {
501+
$image = self::get_attachment_data( $attributes[ $id_key ], $html_info['post_url'], $width, $height );
502+
if ( false !== $image ) {
503+
$images[] = $image;
504+
}
505+
}
506+
break;
507+
508+
case 'core/gallery':
509+
case 'jetpack/tiled-gallery':
510+
case 'jetpack/slideshow':
511+
if ( ! empty( $attributes['ids'] ) && is_array( $attributes['ids'] ) ) {
512+
foreach ( $attributes['ids'] as $img_id ) {
513+
$image = self::get_attachment_data( $img_id, $html_info['post_url'], $width, $height );
514+
if ( false !== $image ) {
515+
$images[] = $image;
516+
}
517+
}
518+
}
519+
break;
520+
521+
case 'jetpack/story':
522+
if ( ! empty( $attributes['mediaFiles'] ) && is_array( $attributes['mediaFiles'] ) ) {
523+
foreach ( $attributes['mediaFiles'] as $media_file ) {
524+
if ( ! empty( $media_file['id'] ) ) {
525+
$image = self::get_attachment_data( $media_file['id'], $html_info['post_url'], $width, $height );
526+
if ( false !== $image ) {
527+
$images[] = $image;
528+
}
529+
}
530+
}
531+
}
532+
break;
533+
}
534+
535+
return $images;
536+
}
537+
474538
/**
475539
* Very raw -- just parse the HTML and pull out any/all img tags and return their src
476540
*
@@ -1028,81 +1092,6 @@ public static function get_alt_text( $attachment_id ) {
10281092
return (string) get_post_meta( $attachment_id, '_wp_attachment_image_alt', true );
10291093
}
10301094

1031-
/**
1032-
* Get an image from a block.
1033-
*
1034-
* @since 7.8.0
1035-
*
1036-
* @param array $images Images found.
1037-
* @param array $block Block and its attributes.
1038-
* @param array $html_info Info about the post where the block is found.
1039-
* @param int $width Desired image width.
1040-
* @param int $height Desired image height.
1041-
*
1042-
* @return array Array of images found.
1043-
*/
1044-
private static function get_images_from_block( $images, $block, $html_info, $width, $height ) {
1045-
/**
1046-
* Parse content from Core Image blocks.
1047-
* If it is an image block for an image hosted on our site, it will have an ID.
1048-
* If it does not have an ID, let `from_html` parse that content later,
1049-
* and extract an image if it has size parameters.
1050-
*/
1051-
if (
1052-
'core/image' === $block['blockName']
1053-
&& ! empty( $block['attrs']['id'] )
1054-
) {
1055-
$images[] = self::get_attachment_data( $block['attrs']['id'], $html_info['post_url'], $width, $height );
1056-
} elseif (
1057-
'core/media-text' === $block['blockName']
1058-
&& ! empty( $block['attrs']['mediaId'] )
1059-
) {
1060-
$images[] = self::get_attachment_data( $block['attrs']['mediaId'], $html_info['post_url'], $width, $height );
1061-
} elseif (
1062-
/**
1063-
* Parse content from Core Gallery blocks as well from Jetpack's Tiled Gallery and Slideshow blocks.
1064-
* Gallery blocks include the ID of each one of the images in the gallery.
1065-
*/
1066-
in_array( $block['blockName'], array( 'core/gallery', 'jetpack/tiled-gallery', 'jetpack/slideshow' ), true )
1067-
&& ! empty( $block['attrs']['ids'] )
1068-
) {
1069-
foreach ( $block['attrs']['ids'] as $img_id ) {
1070-
$images[] = self::get_attachment_data( $img_id, $html_info['post_url'], $width, $height );
1071-
}
1072-
} elseif (
1073-
/**
1074-
* Parse content from Jetpack's Story block.
1075-
*/
1076-
'jetpack/story' === $block['blockName']
1077-
&& ! empty( $block['attrs']['mediaFiles'] )
1078-
) {
1079-
foreach ( $block['attrs']['mediaFiles'] as $media_file ) {
1080-
if ( ! empty( $media_file['id'] ) ) {
1081-
$images[] = self::get_attachment_data( $media_file['id'], $html_info['post_url'], $width, $height );
1082-
}
1083-
}
1084-
}
1085-
1086-
return $images;
1087-
}
1088-
1089-
/**
1090-
* Check if a block has inner blocks.
1091-
*
1092-
* @since 7.8.0
1093-
*
1094-
* @param array $block Block and its attributes.
1095-
*
1096-
* @return bool
1097-
*/
1098-
private static function is_nested_block( $block ) {
1099-
if ( ! empty( $block['innerBlocks'] ) ) {
1100-
return true;
1101-
}
1102-
1103-
return false;
1104-
}
1105-
11061095
/**
11071096
* Determine the size to use with Photon for a thumbnail image.
11081097
* Images larger than the maximum thumbnail dimension in either dimension are resized to maintain aspect ratio.

projects/plugins/jetpack/composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
"automattic/jetpack-backup": "@dev",
2020
"automattic/jetpack-blaze": "@dev",
2121
"automattic/jetpack-blocks": "@dev",
22+
"automattic/block-delimiter": "@dev",
2223
"automattic/jetpack-boost-speed-score": "@dev",
2324
"automattic/jetpack-classic-theme-helper": "@dev",
2425
"automattic/jetpack-compat": "@dev",

projects/plugins/jetpack/composer.lock

Lines changed: 57 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)