Skip to content

Commit dad7f3e

Browse files
committed
Refactor get_post_galleries to use Block_Processor
1 parent 0fb3bb2 commit dad7f3e

1 file changed

Lines changed: 116 additions & 61 deletions

File tree

src/wp-includes/media.php

Lines changed: 116 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -5248,12 +5248,13 @@ function get_media_embedded_in_content( $content, $types = null ) {
52485248
*
52495249
* @since 3.6.0
52505250
*
5251-
* @param int|WP_Post $post Post ID or object.
5252-
* @param bool $html Optional. Whether to return HTML or data in the array. Default true.
5251+
* @param int|WP_Post $post Post ID or object.
5252+
* @param bool $html Optional. Whether to return HTML or data in the array. Default true.
5253+
* @param int $max_galleries Optional. Only collect up to this many galleries. Default unlimited.
52535254
* @return array A list of arrays, each containing gallery data and srcs parsed
52545255
* from the expanded shortcode.
52555256
*/
5256-
function get_post_galleries( $post, $html = true ) {
5257+
function get_post_galleries( $post, $html = true, $max_galleries = PHP_INT_MAX ) {
52575258
$post = get_post( $post );
52585259

52595260
if ( ! $post ) {
@@ -5299,95 +5300,149 @@ function get_post_galleries( $post, $html = true ) {
52995300
}
53005301
}
53015302

5302-
if ( has_block( 'gallery', $post->post_content ) ) {
5303-
$post_blocks = parse_blocks( $post->post_content );
5303+
$processor = new WP_Block_Processor( $post->post_content );
5304+
$found = 0;
53045305

5305-
while ( $block = array_shift( $post_blocks ) ) {
5306-
$has_inner_blocks = ! empty( $block['innerBlocks'] );
5307-
5308-
// Skip blocks with no blockName and no innerHTML.
5309-
if ( ! $block['blockName'] ) {
5310-
continue;
5306+
while ( $processor->next_block( 'gallery' ) ) {
5307+
/*
5308+
* It’s not clear yet whether this will have inner blocks.
5309+
* Until then, start computing for both paths, then bail
5310+
* once the block vintage is known.
5311+
*/
5312+
$gallery_depth = $processor->get_depth();
5313+
$has_inner_blocks = false;
5314+
$gallery_ids = $processor->allocate_and_return_parsed_attributes()['attrs']['ids'] ?? array();
5315+
5316+
$html_chunks = array();
5317+
$top_chunks = array();
5318+
while ( $processor->next_token() && $processor->get_depth() > $gallery_depth ) {
5319+
if ( $processor->is_html() ) {
5320+
$chunk_span = $processor->get_span();
5321+
$chunk = substr( $post->post_content, $chunk_span->start, $chunk_span->length );
5322+
$html_chunks[] = $chunk;
5323+
if ( $gallery_depth === $processor->get_depth() - 1 ) {
5324+
$top_chunks[] = $chunk;
5325+
}
5326+
} else {
5327+
$has_inner_blocks = true;
5328+
break;
53115329
}
5330+
}
53125331

5313-
// Skip non-Gallery blocks.
5314-
if ( 'core/gallery' !== $block['blockName'] ) {
5315-
// Move inner blocks into the root array before skipping.
5316-
if ( $has_inner_blocks ) {
5317-
array_push( $post_blocks, ...$block['innerBlocks'] );
5332+
// New Gallery block format as HTML.
5333+
if ( $has_inner_blocks && $html ) {
5334+
5335+
// Get the rest of the innerHTML of the Gallery’s direct children.
5336+
while ( $processor->next_token() && $processor->get_depth() > $gallery_depth ) {
5337+
if ( $processor->is_html() && $processor->get_depth() === $gallery_depth + 2 ) {
5338+
$chunk_span = $processor->get_span();
5339+
$html_chunks[] = substr( $post->post_content, $chunk_span->start, $chunk_span->length );
53185340
}
5319-
continue;
53205341
}
53215342

5322-
// New Gallery block format as HTML.
5323-
if ( $has_inner_blocks && $html ) {
5324-
$block_html = wp_list_pluck( $block['innerBlocks'], 'innerHTML' );
5325-
$galleries[] = '<figure>' . implode( ' ', $block_html ) . '</figure>';
5343+
$galleries[] = '<figure>' . implode( ' ', $html_chunks ) . '</figure>';
5344+
if ( ++$found >= $max_galleries ) {
5345+
break;
5346+
} else {
53265347
continue;
53275348
}
5349+
}
53285350

5351+
// New Gallery block format as an array.
5352+
if ( $has_inner_blocks ) {
5353+
// There are inner blocks and this is the first one.
5354+
$ids = array();
53295355
$srcs = array();
53305356

5331-
// New Gallery block format as an array.
5332-
if ( $has_inner_blocks ) {
5333-
$attrs = wp_list_pluck( $block['innerBlocks'], 'attrs' );
5334-
$ids = wp_list_pluck( $attrs, 'id' );
5357+
/**
5358+
* @todo Could avoid computation by tracking seen ids and only looking up the
5359+
* attachment url if the id hasn’t already been resolved.
5360+
*/
5361+
5362+
/** @var @todo Perfect use-case for lazy parsing here — only the `id` is wanted. */
5363+
$id = $processor->allocate_and_return_parsed_attributes()['id'] ?? null;
5364+
if ( isset( $id ) ) {
5365+
$ids[] = $id;
5366+
$url = wp_get_attachment_url( $id );
5367+
if ( is_string( $url ) ) {
5368+
$srcs[] = $url;
5369+
}
5370+
}
53355371

5336-
foreach ( $ids as $id ) {
5337-
$url = wp_get_attachment_url( $id );
5372+
while ( $processor->next_block() && $processor->get_depth() > $gallery_depth ) {
5373+
// Examine only the direct children of the gallery block.
5374+
if ( $processor->get_depth() === $gallery_depth + 1 ) {
5375+
$id = $processor->allocate_and_return_parsed_attributes()['id'] ?? null;
5376+
if ( isset( $id ) ) {
5377+
$ids[] = $id;
5378+
$url = wp_get_attachment_url( $id );
53385379

5339-
if ( is_string( $url ) && ! in_array( $url, $srcs, true ) ) {
5340-
$srcs[] = $url;
5380+
if ( is_string( $url ) && ! in_array( $url, $srcs, true ) ) {
5381+
$srcs[] = $url;
5382+
}
53415383
}
53425384
}
5385+
}
53435386

5344-
$galleries[] = array(
5345-
'ids' => implode( ',', $ids ),
5346-
'src' => $srcs,
5347-
);
5387+
$galleries[] = array(
5388+
'ids' => implode( ',', $ids ),
5389+
'src' => $srcs,
5390+
);
53485391

5392+
if ( ++$found >= $max_galleries ) {
5393+
break;
5394+
} else {
53495395
continue;
53505396
}
5397+
}
53515398

5352-
// Old Gallery block format as HTML.
5353-
if ( $html ) {
5354-
$galleries[] = $block['innerHTML'];
5399+
// Old Gallery block format as HTML.
5400+
if ( $html ) {
5401+
$galleries[] = implode( '', $top_chunks );
5402+
if ( ++$found >= $max_galleries ) {
5403+
break;
5404+
} else {
53555405
continue;
53565406
}
5407+
}
53575408

5358-
// Old Gallery block format as an array.
5359-
$ids = ! empty( $block['attrs']['ids'] ) ? $block['attrs']['ids'] : array();
5409+
// Old Gallery block format as an array.
53605410

5361-
// If present, use the image IDs from the JSON blob as canonical.
5362-
if ( ! empty( $ids ) ) {
5363-
foreach ( $ids as $id ) {
5364-
$url = wp_get_attachment_url( $id );
5411+
// If present, use the image IDs from the JSON blob as canonical.
5412+
if ( ! empty( $gallery_ids ) ) {
5413+
foreach ( $ids as $id ) {
5414+
$url = wp_get_attachment_url( $id );
53655415

5366-
if ( is_string( $url ) && ! in_array( $url, $srcs, true ) ) {
5367-
$srcs[] = $url;
5368-
}
5416+
if ( is_string( $url ) && ! in_array( $url, $srcs, true ) ) {
5417+
$srcs[] = $url;
53695418
}
5419+
}
53705420

5371-
$galleries[] = array(
5372-
'ids' => implode( ',', $ids ),
5373-
'src' => $srcs,
5374-
);
5421+
$galleries[] = array(
5422+
'ids' => implode( ',', $ids ),
5423+
'src' => $srcs,
5424+
);
53755425

5426+
if ( ++$found >= $max_galleries ) {
5427+
break;
5428+
} else {
53765429
continue;
53775430
}
5431+
}
53785432

5379-
// Otherwise, extract srcs from the innerHTML.
5380-
preg_match_all( '#src=([\'"])(.+?)\1#is', $block['innerHTML'], $found_srcs, PREG_SET_ORDER );
5381-
5382-
if ( ! empty( $found_srcs[0] ) ) {
5383-
foreach ( $found_srcs as $src ) {
5384-
if ( isset( $src[2] ) && ! in_array( $src[2], $srcs, true ) ) {
5385-
$srcs[] = $src[2];
5386-
}
5387-
}
5433+
// Otherwise, extract srcs from the innerHTML.
5434+
$inner_html = implode( '', $top_chunks );
5435+
$src_finder = new WP_HTML_Tag_Processor( $inner_html );
5436+
while ( $src_finder->next_tag() ) {
5437+
$src = $src_finder->get_attribute( 'src' );
5438+
if ( is_string( $src ) && ! in_array( $src, $srcs, true ) ) {
5439+
$srcs[] = $src;
53885440
}
5441+
}
53895442

5390-
$galleries[] = array( 'src' => $srcs );
5443+
$galleries[] = array( 'src' => $srcs );
5444+
if ( ++$found >= $max_galleries ) {
5445+
break;
53915446
}
53925447
}
53935448

@@ -5412,8 +5467,8 @@ function get_post_galleries( $post, $html = true ) {
54125467
* @return string|array Gallery data and srcs parsed from the expanded shortcode.
54135468
*/
54145469
function get_post_gallery( $post = 0, $html = true ) {
5415-
$galleries = get_post_galleries( $post, $html );
5416-
$gallery = reset( $galleries );
5470+
$galleries = get_post_galleries( $post, $html, 1 );
5471+
$gallery = $galleries[0] ?? false;
54175472

54185473
/**
54195474
* Filters the first-found post gallery.

0 commit comments

Comments
 (0)