diff --git a/src/wp-includes/media.php b/src/wp-includes/media.php
index 6e7f66760f608..9832c8a2cf005 100644
--- a/src/wp-includes/media.php
+++ b/src/wp-includes/media.php
@@ -4711,7 +4711,7 @@ function get_post_galleries( $post, $html = true ) {
return array();
}
- if ( ! has_shortcode( $post->post_content, 'gallery' ) ) {
+ if ( ! has_shortcode( $post->post_content, 'gallery' ) && ! has_block( 'gallery', $post->post_content ) ) {
return array();
}
@@ -4753,6 +4753,76 @@ function get_post_galleries( $post, $html = true ) {
}
}
+ if ( has_block( 'gallery', $post->post_content ) ) {
+ $post_blocks = parse_blocks( $post->post_content );
+ // Use while/array_shift instead of foreach so we can modify the array from within the loop
+ while ( $block = array_shift( $post_blocks ) ) {
+ if ( 'core/gallery' === $block['blockName'] ) {
+ // If a Gallery block has innerBlocks it is the new format and needs to be handled separately to the old
+ // format with nested
tags.
+ if ( ! empty( $block['innerBlocks'] ) ) {
+ $gallery_srcs = array();
+ $ids = array();
+ $block_html = array();
+ foreach ( $block['innerBlocks'] as $image ) {
+ if ( $html ) {
+ $block_html[] = $image['innerHTML'];
+ } else {
+ $gallery_srcs[] = wp_get_attachment_url( $image ['attrs']['id'] );
+ $ids[] = $image['attrs']['id'];
+ }
+ }
+ if ( $html ) {
+ $galleries[] = '' . implode( ' ', $block_html ) . '';
+ } else {
+ $galleries[] = array(
+ // array_filter will eliminate any empty entries that came from unknown or invalid IDs
+ 'src' => array_values( array_filter( array_unique( $gallery_srcs ) ) ),
+ // Only explicitly include the ids attribute. In future this could be changed to include all attributes, similar to $shortcode_attrs above.
+ 'ids' => implode( ',', $ids ),
+ );
+ }
+ } else {
+ // Now handle the v1 gallery block format.
+ if ( $html ) {
+ $galleries[] = $block['innerHTML'];
+ } elseif ( ! empty( $block['attrs']['ids'] ) ) {
+ // Use the image IDs from the json blob as canonical if present
+ $gallery_srcs = array();
+ foreach ( $block['attrs']['ids'] as $gallery_img_id ) {
+ $gallery_srcs[] = wp_get_attachment_url( $gallery_img_id );
+ }
+ $galleries[] = array(
+ // array_filter will eliminate any empty entries that came from unknown or invalid IDs
+ 'src' => array_values( array_filter( array_unique( $gallery_srcs ) ) ),
+ // Only explicitly include the ids attribute. In future this could be changed to include all attributes, similar to $shortcode_attrs above.
+ 'ids' => implode( ',', $block['attrs']['ids'] ),
+ );
+ } else {
+ // Otherwise extract srcs from the innerHTML
+ $srcs = array();
+ preg_match_all( '#src=([\'"])(.+?)\1#is', $block['innerHTML'], $src, PREG_SET_ORDER );
+ if ( ! empty( $src ) ) {
+ foreach ( $src as $s ) {
+ $srcs[] = $s[2];
+ }
+ }
+
+ $galleries[] = array(
+ // Note that unlike shortcodes, all we are returning here is the src list
+ 'src' => array_values( array_unique( $srcs ) ),
+ );
+ }
+ }
+ } elseif ( ! empty( $block['innerBlocks'] ) ) {
+ // If we have nested blocks then gradually flatten it by moving those onto the end of the root array for traversal
+ while ( $inner = array_pop( $block['innerBlocks'] ) ) {
+ array_push( $post_blocks, $inner );
+ }
+ }
+ }
+ }
+
/**
* Filters the list of all found galleries in the given post.
*
diff --git a/tests/phpunit/tests/media.php b/tests/phpunit/tests/media.php
index 0483f0c0845d5..013e74851776d 100644
--- a/tests/phpunit/tests/media.php
+++ b/tests/phpunit/tests/media.php
@@ -510,9 +510,9 @@ public function test_get_attached_images() {
* @ticket 22960
*/
public function test_post_galleries_images() {
- $ids1 = array();
- $ids1_srcs = array();
- foreach ( range( 1, 3 ) as $i ) {
+ $ids = array();
+ $ids_srcs = array();
+ foreach ( range( 1, 6 ) as $i ) {
$attachment_id = self::factory()->attachment->create_object(
"image$i.jpg",
0,
@@ -540,12 +540,12 @@ public function test_post_galleries_images() {
);
$metadata = array_merge( array( 'file' => "image$i.jpg" ), $this->img_meta );
wp_update_attachment_metadata( $attachment_id, $metadata );
- $ids2[] = $attachment_id;
- $ids2_srcs[] = 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . "image$i.jpg";
+ $ids[] = $attachment_id;
+ $ids_srcs[] = 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . "image$i.jpg";
}
- $ids1_joined = implode( ',', $ids1 );
- $ids2_joined = implode( ',', $ids2 );
+ $ids1_joined = join( ',', array_slice( $ids, 0, 3 ) );
+ $ids2_joined = join( ',', array_slice( $ids, 3, 3 ) );
$blob = <<post->create( array( 'post_content' => $blob ) );
$srcs = get_post_galleries_images( $post_id );
- $this->assertSame( $srcs, array( $ids1_srcs, $ids2_srcs ) );
+ $this->assertEquals( $srcs, array( array_slice( $ids_srcs, 0, 3 ), array_slice( $ids_srcs, 3, 3 ) ) );
}
/**
@@ -707,6 +707,354 @@ public function test_post_gallery_images() {
$this->assertSame( $srcs, $ids1_srcs );
}
+ /**
+ * @ticket 43826
+ * @group blocks
+ */
+ public function test_block_post_galleries() {
+ // Set up an unattached image.
+ $this->factory->attachment->create_object(
+ array(
+ 'file' => 'test.jpg',
+ 'post_parent' => 0,
+ 'post_mime_type' => 'image/jpeg',
+ 'post_type' => 'attachment',
+ )
+ );
+
+ $post_id = $this->factory->post->create(
+ array(
+ 'post_content' => '',
+ )
+ );
+
+ $galleries = get_post_galleries( $post_id, false );
+
+ $this->assertTrue( is_array( $galleries ) );
+ $this->assertEmpty( $galleries[0]['src'] );
+ }
+
+ /**
+ * @ticket 43826
+ * @group blocks
+ */
+ public function test_block_post_gallery_images() {
+ // Similar to test_post_gallery_images but with blocks instead of shortcodes
+ $ids = array();
+ $imgs = array();
+ $ids_srcs = array();
+ foreach ( range( 1, 6 ) as $i ) {
+ $attachment_id = self::factory()->attachment->create_object(
+ "image$i.jpg",
+ 0
+ );
+ $metadata = array_merge( array( 'file' => "image$i.jpg" ), $this->img_meta );
+ wp_update_attachment_metadata( $attachment_id, $metadata );
+ $ids1[] = $attachment_id;
+ $ids1_srcs[] = 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . "image$i.jpg";
+ $ids[] = $attachment_id;
+ $url = 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . "image$i.jpg";
+ $ids_srcs[] = $url;
+ $imgs[] = '
';
+
+ }
+
+ foreach ( range( 4, 6 ) as $i ) {
+ $imgs1_joined = join( "\n", array_slice( $imgs, 0, 3 ) );
+ $imgs2_joined = join( "\n", array_slice( $imgs, 3, 3 ) );
+ }
+ $blob = <<
+$imgs1_joined
+
+
+$imgs2_joined
+
+BLOB;
+ $post_id = self::factory()->post->create( array( 'post_content' => $blob ) );
+ $srcs = get_post_gallery_images( $post_id );
+ $this->assertEquals( $srcs, array_slice( $ids_srcs, 0, 3 ) );
+ }
+
+ /**
+ * @ticket 43826
+ * @group blocks
+ */
+ public function test_block_post_gallery_images_json() {
+ // Similar to test_block_post_gallery_images, with IDs in the json blob
+ $ids = array();
+ $imgs = array();
+ $ids_srcs = array();
+ foreach ( range( 1, 6 ) as $i ) {
+ $attachment_id = self::factory()->attachment->create_object(
+ "image$i.jpg",
+ 0
+ );
+ $metadata = array_merge( array( 'file' => "image$i.jpg" ), $this->img_meta );
+ wp_update_attachment_metadata( $attachment_id, $metadata );
+ $ids[] = $attachment_id;
+ $url = 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . "image$i.jpg";
+ $ids_srcs[] = $url;
+ $imgs[] = '
';
+
+ }
+
+ $ids1_joined = join( ',', array_slice( $ids, 0, 3 ) );
+ $ids2_joined = join( ',', array_slice( $ids, 3, 3 ) );
+
+ $blob = <<
+
+
+
+
+BLOB;
+ $post_id = self::factory()->post->create( array( 'post_content' => $blob ) );
+ $srcs = get_post_gallery_images( $post_id );
+ $this->assertEquals( $srcs, array_slice( $ids_srcs, 0, 3 ) );
+ }
+
+ /**
+ * @ticket 43826
+ * @group blocks
+ */
+ public function test_mixed_post_gallery_images() {
+ // Similar to test_post_gallery_images but with a shortcode and a block in the same post
+ $ids = array();
+ $imgs = array();
+ $ids_srcs = array();
+ foreach ( range( 1, 6 ) as $i ) {
+ $attachment_id = self::factory()->attachment->create_object(
+ "image$i.jpg",
+ 0,
+ array(
+ 'post_mime_type' => 'image/jpeg',
+ 'post_type' => 'attachment',
+ )
+ );
+ $metadata = array_merge( array( 'file' => "image$i.jpg" ), $this->img_meta );
+ wp_update_attachment_metadata( $attachment_id, $metadata );
+ $ids[] = $attachment_id;
+ $url = 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . "image$i.jpg";
+ $ids_srcs[] = $url;
+ $imgs[] = '
';
+ }
+
+ $ids1_joined = join( "\n", array_slice( $ids, 0, 3 ) );
+ $ids2_joined = join( "\n", array_slice( $ids, 3, 3 ) );
+ $imgs2_joined = join( "\n", array_slice( $imgs, 3, 3 ) );
+
+ $blob = <<
+$imgs2_joined
+
+BLOB;
+ $post_id = self::factory()->post->create( array( 'post_content' => $blob ) );
+ $srcs = get_post_gallery_images( $post_id );
+ $this->assertEquals( $srcs, array_slice( $ids_srcs, 0, 3 ) );
+ }
+
+ /**
+ * @ticket 43826
+ * @group blocks
+ */
+ public function test_mixed_post_galleries() {
+ // Test the get_post_galleries() function in $html=false mode, with both shortcode and block galleries
+ $ids = array();
+ $imgs = array();
+ $ids_srcs = array();
+ foreach ( range( 1, 6 ) as $i ) {
+ $attachment_id = self::factory()->attachment->create_object(
+ "image$i.jpg",
+ 0,
+ array(
+ 'post_mime_type' => 'image/jpeg',
+ 'post_type' => 'attachment',
+ )
+ );
+ $metadata = array_merge( array( 'file' => "image$i.jpg" ), $this->img_meta );
+ wp_update_attachment_metadata( $attachment_id, $metadata );
+ $ids[] = $attachment_id;
+ $url = 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . "image$i.jpg";
+ $ids_srcs[] = $url;
+ $imgs[] = '
';
+
+ }
+
+ $ids1_joined = join( ',', array_slice( $ids, 0, 3 ) );
+ $ids2_joined = join( ',', array_slice( $ids, 3, 3 ) );
+
+ $blob = <<
+
+BLOB;
+
+ $post_id = self::factory()->post->create( array( 'post_content' => $blob ) );
+
+ $galleries = get_post_galleries( $post_id, false );
+ $this->assertEquals(
+ $galleries,
+ array(
+ array(
+ 'ids' => $ids1_joined,
+ 'src' => array_slice( $ids_srcs, 0, 3 ),
+ ),
+ array(
+ 'ids' => $ids2_joined,
+ 'src' => array_slice( $ids_srcs, 3, 3 ),
+ ),
+ )
+ );
+
+ }
+
+ /**
+ * @ticket 43826
+ * @group blocks
+ */
+ public function test_mixed_post_galleries_data() {
+ // Test attributes returned by get_post_galleries() function in $html=false mode, with both shortcode and block galleries
+ $ids = array();
+ $imgs = array();
+ $ids_srcs = array();
+ foreach ( range( 1, 6 ) as $i ) {
+ $attachment_id = self::factory()->attachment->create_object(
+ "image$i.jpg",
+ 0,
+ array(
+ 'post_mime_type' => 'image/jpeg',
+ 'post_type' => 'attachment',
+ )
+ );
+ $metadata = array_merge( array( 'file' => "image$i.jpg" ), $this->img_meta );
+ wp_update_attachment_metadata( $attachment_id, $metadata );
+ $ids[] = $attachment_id;
+ $url = 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . "image$i.jpg";
+ $ids_srcs[] = $url;
+ $imgs[] = '
';
+
+ }
+
+ $ids1_joined = join( ',', array_slice( $ids, 0, 3 ) );
+ $ids2_joined = join( ',', array_slice( $ids, 3, 3 ) );
+ $blob = <<
+
+BLOB;
+
+ $post_id = self::factory()->post->create( array( 'post_content' => $blob ) );
+
+ $galleries = get_post_galleries( $post_id, false );
+ $this->assertEquals(
+ $galleries,
+ array(
+ array(
+ 'ids' => $ids1_joined,
+ 'src' => array_slice( $ids_srcs, 0, 3 ),
+ 'type' => 'type',
+ 'foo' => 'bar', // The shortcode code passes arbitrary attributes
+ ),
+ array(
+ 'ids' => $ids2_joined,
+ 'src' => array_slice( $ids_srcs, 3, 3 ),
+ // The block only passes ids, no other attributes
+ ),
+ )
+ );
+
+ }
+
+ /**
+ * @ticket 43826
+ * @group blocks
+ */
+ public function test_block_inner_post_gallery_images() {
+ // Make sure get_post_gallery_images() works with gallery blocks that are nested inside something else
+ $ids = array();
+ $imgs = array();
+ $ids_srcs = array();
+ foreach ( range( 1, 3 ) as $i ) {
+ $attachment_id = self::factory()->attachment->create_object(
+ "image$i.jpg",
+ 0,
+ array(
+ 'post_mime_type' => 'image/jpeg',
+ 'post_type' => 'attachment',
+ )
+ );
+ $metadata = array_merge( array( 'file' => "image$i.jpg" ), $this->img_meta );
+ wp_update_attachment_metadata( $attachment_id, $metadata );
+ $ids[] = $attachment_id;
+ $url = 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . "image$i.jpg";
+ $ids_srcs[] = $url;
+ $imgs[] = '
';
+
+ }
+
+ $imgs_joined = join( "\n", $imgs );
+
+ $blob = <<
+
+
+$imgs_joined
+
+
+
+BLOB;
+ $post_id = self::factory()->post->create( array( 'post_content' => $blob ) );
+ $srcs = get_post_gallery_images( $post_id );
+ $this->assertEquals( $srcs, $ids_srcs );
+ }
+
+ /**
+ * @ticket 43826
+ * @group blocks
+ */
+ public function test_block_post_gallery_innerblock_images() {
+ // Make sure get_post_gallery_images() works with new version of gallery block with nested image blocks.
+ $ids = array();
+ $imgs = array();
+ $ids_srcs = array();
+ foreach ( range( 1, 3 ) as $i ) {
+ $attachment_id = self::factory()->attachment->create_object(
+ "image$i.jpg",
+ 0,
+ array(
+ 'post_mime_type' => 'image/jpeg',
+ 'post_type' => 'attachment',
+ )
+ );
+ $metadata = array_merge( array( 'file' => "image$i.jpg" ), $this->img_meta );
+ wp_update_attachment_metadata( $attachment_id, $metadata );
+ $ids[] = $attachment_id;
+ $url = 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . "image$i.jpg";
+ $ids_srcs[] = $url;
+ $imgs[] = '
';
+
+ }
+
+ $imgs_joined = join( "\n", $imgs );
+
+ $blob = <<
+
+$imgs_joined
+
+
+BLOB;
+ $post_id = self::factory()->post->create( array( 'post_content' => $blob ) );
+ $srcs = get_post_gallery_images( $post_id );
+ $this->assertEquals( $srcs, $ids_srcs );
+ }
+
public function test_get_media_embedded_in_content() {
$object = <<