diff --git a/src/wp-includes/media.php b/src/wp-includes/media.php
index dd46e4c141..01543b9dcd 100644
--- a/src/wp-includes/media.php
+++ b/src/wp-includes/media.php
@@ -4725,7 +4725,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();
}
@@ -4767,6 +4767,95 @@ function get_post_galleries( $post, $html = true ) {
}
}
+ if ( has_block( 'gallery', $post->post_content ) ) {
+ $post_blocks = parse_blocks( $post->post_content );
+
+ while ( $block = array_shift( $post_blocks ) ) {
+ $has_inner_blocks = ! empty( $block['innerBlocks'] );
+
+ // Skip blocks with no blockName and no innerHTML.
+ if ( ! $block['blockName'] ) {
+ continue;
+ }
+
+ // All blocks nested inside non-Gallery blocks should be in the root array.
+ if ( $has_inner_blocks && 'core/gallery' !== $block['blockName'] ) {
+ array_push( $post_blocks, ...$block['innerBlocks'] );
+ continue;
+ }
+
+ // New Gallery block format as HTML.
+ if ( $has_inner_blocks && $html ) {
+ $block_html = wp_list_pluck( $block['innerBlocks'], 'innerHTML' );
+ $galleries[] = '' . implode( ' ', $block_html ) . '';
+ continue;
+ }
+
+ $srcs = array();
+
+ // New Gallery block format as an array.
+ if ( $has_inner_blocks ) {
+ $attrs = wp_list_pluck( $block['innerBlocks'], 'attrs' );
+ $ids = wp_list_pluck( $attrs, 'id' );
+
+ foreach ( $ids as $id ) {
+ $url = wp_get_attachment_url( $id );
+
+ if ( is_string( $url ) && ! in_array( $url, $srcs, true ) ) {
+ $srcs[] = $url;
+ }
+ }
+
+ $galleries[] = array(
+ 'ids' => implode( ',', $ids ),
+ 'src' => $srcs,
+ );
+
+ continue;
+ }
+
+ // Old Gallery block format as HTML.
+ if ( $html ) {
+ $galleries[] = $block['innerHTML'];
+ continue;
+ }
+
+ // Old Gallery block format as an array.
+ $ids = ! empty( $block['attrs']['ids'] ) ? $block['attrs']['ids'] : array();
+
+ // If present, use the image IDs from the JSON blob as canonical.
+ if ( ! empty( $ids ) ) {
+ foreach ( $ids as $id ) {
+ $url = wp_get_attachment_url( $id );
+
+ if ( is_string( $url ) && ! in_array( $url, $srcs, true ) ) {
+ $srcs[] = $url;
+ }
+ }
+
+ $galleries[] = array(
+ 'ids' => implode( ',', $ids ),
+ 'src' => $srcs,
+ );
+
+ continue;
+ }
+
+ // Otherwise, extract srcs from the innerHTML.
+ preg_match_all( '#src=([\'"])(.+?)\1#is', $block['innerHTML'], $found_srcs, PREG_SET_ORDER );
+
+ if ( ! empty( $found_srcs[0] ) ) {
+ foreach ( $found_srcs as $src ) {
+ if ( isset( $src[2] ) && ! in_array( $src[2], $srcs, true ) ) {
+ $srcs[] = $src[2];
+ }
+ }
+ }
+
+ $galleries[] = array( 'src' => $srcs );
+ }
+ }
+
/**
* 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 c338a2baf7..5d92d9718b 100644
--- a/tests/phpunit/tests/media.php
+++ b/tests/phpunit/tests/media.php
@@ -512,7 +512,7 @@ https://w.org',
public function test_post_galleries_images() {
$ids1 = array();
$ids1_srcs = array();
- foreach ( range( 1, 3 ) as $i ) {
+ foreach ( range( 1, 6 ) as $i ) {
$attachment_id = self::factory()->attachment->create_object(
"image$i.jpg",
0,
@@ -544,8 +544,8 @@ https://w.org',
$ids2_srcs[] = 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . "image$i.jpg";
}
- $ids1_joined = implode( ',', $ids1 );
- $ids2_joined = implode( ',', $ids2 );
+ $ids1_joined = join( ',', array_slice( $ids1, 0, 3 ) );
+ $ids2_joined = join( ',', array_slice( $ids2, 3, 3 ) );
$blob = <<',
BLOB;
$post_id = self::factory()->post->create( array( 'post_content' => $blob ) );
$srcs = get_post_galleries_images( $post_id );
- $this->assertSame( $srcs, array( $ids1_srcs, $ids2_srcs ) );
- }
-
- /**
- * @ticket 39304
- */
- public function test_post_galleries_images_without_global_post() {
- // 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' => '[gallery]',
- )
- );
-
- $galleries = get_post_galleries( $post_id, false );
-
- $this->assertEmpty( $galleries[0]['src'] );
- }
-
- /**
- * @ticket 39304
- */
- public function test_post_galleries_ignores_global_post() {
- $global_post_id = $this->factory->post->create(
- array(
- 'post_content' => 'Global Post',
- )
- );
- $post_id = $this->factory->post->create(
- array(
- 'post_content' => '[gallery]',
- )
- );
- $this->factory->attachment->create_object(
- array(
- 'file' => 'test.jpg',
- 'post_parent' => $post_id,
- 'post_mime_type' => 'image/jpeg',
- 'post_type' => 'attachment',
- )
- );
- $expected_srcs = array(
- 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/test.jpg',
- );
-
- // Set the global $post context to the other post.
- $GLOBALS['post'] = get_post( $global_post_id );
-
- $galleries = get_post_galleries( $post_id, false );
-
- $this->assertNotEmpty( $galleries[0]['src'] );
- $this->assertSame( $galleries[0]['src'], $expected_srcs );
- }
-
- /**
- * @ticket 39304
- */
- public function test_post_galleries_respects_id_attrs() {
- $post_id = $this->factory->post->create(
- array(
- 'post_content' => 'No gallery defined',
- )
- );
- $post_id_two = $this->factory->post->create(
- array(
- 'post_content' => "[gallery id='$post_id']",
- )
- );
- $this->factory->attachment->create_object(
- array(
- 'file' => 'test.jpg',
- 'post_parent' => $post_id,
- 'post_mime_type' => 'image/jpeg',
- 'post_type' => 'attachment',
- )
- );
- $expected_srcs = array(
- 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/test.jpg',
- );
-
- $galleries = get_post_galleries( $post_id_two, false );
-
- // Set the global $post context.
- $GLOBALS['post'] = get_post( $post_id_two );
- $galleries_with_global_context = get_post_galleries( $post_id_two, false );
-
- // Check that the global post state doesn't affect the results.
- $this->assertSame( $galleries, $galleries_with_global_context );
-
- $this->assertNotEmpty( $galleries[0]['src'] );
- $this->assertSame( $galleries[0]['src'], $expected_srcs );
+ $this->assertSameSetsWithIndex( $srcs, array( array_slice( $ids1_srcs, 0, 3 ), array_slice( $ids2_srcs, 3, 3 ) ) );
}
/**
@@ -707,6 +608,209 @@ BLOB;
$this->assertSame( $srcs, $ids1_srcs );
}
+ /**
+ * @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 );
+ $ids[] = $attachment_id;
+ $url = 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . "image$i.jpg";
+ $ids_srcs[] = $url;
+ $imgs[] = '
';
+ }
+
+ $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->assertSameSetsWithIndex( array_slice( $ids_srcs, 0, 3 ), $srcs );
+ }
+
+ /**
+ * @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->assertSameSetsWithIndex( array_slice( $ids_srcs, 0, 3 ), $srcs );
+ }
+
+ /**
+ * @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->assertSameSetsWithIndex( array_slice( $ids_srcs, 0, 3 ), $srcs );
+ }
+
+ /**
+ * @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->assertSameSetsWithIndex( $ids_srcs, $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->assertSameSetsWithIndex( $ids_srcs, $srcs );
+ }
+
public function test_get_media_embedded_in_content() {
$object = <<
diff --git a/tests/phpunit/tests/media/getPostGalleries.php b/tests/phpunit/tests/media/getPostGalleries.php
new file mode 100644
index 0000000000..bd114b899f
--- /dev/null
+++ b/tests/phpunit/tests/media/getPostGalleries.php
@@ -0,0 +1,969 @@
+img_meta = array(
+ 'width' => 100,
+ 'height' => 100,
+ 'sizes' => '',
+ );
+ }
+
+ /**
+ * Test that an empty array is returned for a post that does not exist.
+ *
+ * @ticket 43826
+ */
+ public function test_returns_empty_array_with_non_existent_post() {
+ $galleries = get_post_galleries( 99999, false );
+ $this->assertEmpty( $galleries );
+ }
+
+ /**
+ * Test that an empty array is returned for a post that has no gallery.
+ *
+ * @ticket 43826
+ */
+ public function test_returns_empty_array_with_post_with_no_gallery() {
+ $post_id = $this->factory->post->create(
+ array(
+ 'post_content' => 'A post with no gallery
',
+ )
+ );
+
+ $galleries = get_post_galleries( $post_id, false );
+ $this->assertEmpty( $galleries );
+ }
+
+ /**
+ * Test that no srcs are returned for a shortcode gallery
+ * in a post with no attached images.
+ *
+ * @ticket 39304
+ *
+ * @group shortcode
+ */
+ public function test_returns_no_srcs_with_shortcode_in_post_with_no_attached_images() {
+ // 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' => '[gallery]',
+ )
+ );
+
+ $galleries = get_post_galleries( $post_id, false );
+
+ // The method can return an empty array.
+ $this->assertNotEmpty(
+ $galleries,
+ 'The galleries array is empty.'
+ );
+
+ // This prevents future changes from causing
+ // backwards compatibility breaks.
+ $this->assertArrayHasKey(
+ 'src',
+ $galleries[0],
+ 'A src key does not exist.'
+ );
+
+ $this->assertEmpty(
+ $galleries[0]['src'],
+ 'The src key is not empty.'
+ );
+ }
+
+ /**
+ * Test that no srcs are returned for a gallery block
+ * in a post with no attached images.
+ *
+ * @ticket 43826
+ *
+ * @group blocks
+ */
+ public function test_returns_no_srcs_with_block_in_post_with_no_attached_images() {
+ // 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 );
+
+ // The method can return an empty array.
+ $this->assertNotEmpty(
+ $galleries,
+ 'The galleries array is empty.'
+ );
+
+ // The method can return an array of strings
+ // instead of an array of arrays.
+ $this->assertIsArray(
+ $galleries[0],
+ 'The returned data does not contain an array.'
+ );
+
+ // This prevents future changes from causing
+ // backwards compatibility breaks.
+ $this->assertArrayHasKey(
+ 'src',
+ $galleries[0],
+ 'A src key does not exist.'
+ );
+
+ $this->assertEmpty(
+ $galleries[0]['src'],
+ 'The src key of the first gallery is not empty.'
+ );
+ }
+
+ /**
+ * Test that no srcs are returned for a gallery block v2
+ * in a post with no attached images.
+ *
+ * @ticket 43826
+ *
+ * @group blocks
+ */
+ public function test_returns_no_srcs_with_block_v2_in_post_with_no_attached_images() {
+ // Set up an unattached image.
+ $image_id = $this->factory->attachment->create_object(
+ array(
+ 'file' => 'test.jpg',
+ 'post_parent' => 0,
+ 'post_mime_type' => 'image/jpeg',
+ 'post_type' => 'attachment',
+ )
+ );
+
+ $image_url = 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/test.jpg';
+
+ $blob = <<< BLOB
+
+
+
+
+
+
+
+
+
+BLOB;
+
+ $post_id = $this->factory->post->create(
+ array(
+ 'post_content' => $blob,
+ )
+ );
+
+ $expected_srcs = array( $image_url );
+ $galleries = get_post_galleries( $post_id, false );
+
+ // The method can return an empty array.
+ $this->assertNotEmpty(
+ $galleries,
+ 'The galleries array is empty.'
+ );
+
+ // The method can return an array of strings
+ // instead of an array of arrays.
+ $this->assertIsArray(
+ $galleries[0],
+ 'The returned data does not contain an array.'
+ );
+
+ // This prevents future changes from causing
+ // backwards compatibility breaks.
+ $this->assertArrayHasKey(
+ 'src',
+ $galleries[0],
+ 'A src key does not exist.'
+ );
+
+ $this->assertSameSetsWithIndex(
+ $expected_srcs,
+ $galleries[0]['src'],
+ 'The expected and actual srcs are not the same.'
+ );
+ }
+
+ /**
+ * Test that HTML is returned for a shortcode gallery.
+ *
+ * @ticket 43826
+ *
+ * @group shortcode
+ */
+ public function test_returns_html_with_shortcode_gallery() {
+ $post_id = $this->factory->post->create(
+ array(
+ 'post_content' => 'I have no gallery',
+ )
+ );
+
+ $post_id_two = $this->factory->post->create(
+ array(
+ 'post_content' => "[gallery id='$post_id']",
+ )
+ );
+
+ $this->factory->attachment->create_object(
+ array(
+ 'file' => 'test.jpg',
+ 'post_parent' => $post_id,
+ 'post_mime_type' => 'image/jpeg',
+ 'post_type' => 'attachment',
+ )
+ );
+
+ $expected = 'src="http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/test.jpg"';
+ $galleries = get_post_galleries( $post_id_two );
+
+ // The method can return an empty array.
+ $this->assertNotEmpty(
+ $galleries,
+ 'The galleries array is empty.'
+ );
+
+ // The method can return an array of arrays
+ // instead of an array of strings.
+ $this->assertIsString(
+ $galleries[0],
+ 'Did not return the data as a string.'
+ );
+
+ $this->assertStringContainsString(
+ $expected,
+ $galleries[0],
+ 'The returned data did not contain a src attribute with the expected image URL.'
+ );
+ }
+
+ /**
+ * Test that HTML is returned for a block gallery.
+ *
+ * @ticket 43826
+ *
+ * @group blocks
+ */
+ public function test_returns_html_with_block_gallery() {
+ $post_id = $this->factory->post->create(
+ array(
+ 'post_content' => 'I have no gallery.',
+ )
+ );
+
+ // Set up an unattached image.
+ $image_id = $this->factory->attachment->create(
+ array(
+ 'file' => 'test.jpg',
+ 'post_parent' => $post_id,
+ 'post_mime_type' => 'image/jpeg',
+ 'post_type' => 'attachment',
+ )
+ );
+
+ $image_url = 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/test.jpg';
+
+ $blob = <<< BLOB
+
+
+
+BLOB;
+
+ $post_id_two = $this->factory->post->create(
+ array(
+ 'post_content' => $blob,
+ )
+ );
+
+ $expected = 'src="http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/test.jpg"';
+ $galleries = get_post_galleries( $post_id_two );
+
+ // The method can return an empty array.
+ $this->assertNotEmpty(
+ $galleries,
+ 'The galleries array is empty.'
+ );
+
+ // The method can return an array of arrays
+ // instead of an array of strings.
+ $this->assertIsString(
+ $galleries[0],
+ 'Did not return the data as a string.'
+ );
+
+ $this->assertStringContainsString(
+ $expected,
+ $galleries[0],
+ 'The returned data did not contain a src attribute with the expected image URL.'
+ );
+ }
+
+ /**
+ * Test that HTML is returned for a block gallery v2.
+ *
+ * @ticket 43826
+ *
+ * @group blocks
+ */
+ public function test_returns_html_with_block_gallery_v2() {
+ $image_id = $this->factory->attachment->create_object(
+ array(
+ 'file' => 'test.jpg',
+ 'post_parent' => 0,
+ 'post_mime_type' => 'image/jpeg',
+ 'post_type' => 'attachment',
+ )
+ );
+
+ $image_url = 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/test.jpg';
+
+ $blob = <<< BLOB
+
+
+
+
+
+
+
+
+
+BLOB;
+
+ $post_id = $this->factory->post->create(
+ array(
+ 'post_content' => $blob,
+ )
+ );
+
+ $expected = 'src="http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/test.jpg"';
+ $galleries = get_post_galleries( $post_id );
+
+ // The method can return an empty array.
+ $this->assertNotEmpty(
+ $galleries,
+ 'The galleries array is empty.'
+ );
+
+ // The method can return an array of arrays
+ // instead of an array of strings.
+ $this->assertIsString(
+ $galleries[0],
+ 'Did not return the data as a string.'
+ );
+
+ $this->assertStringContainsString(
+ $expected,
+ $galleries[0],
+ 'The returned data did not contain a src attribute with the expected image URL.'
+ );
+ }
+
+ /**
+ * Test that the global post object does not override
+ * a provided post ID with a shortcode gallery.
+ *
+ * @ticket 39304
+ *
+ * @group shortcode
+ */
+ public function test_respects_post_id_with_shortcode_gallery() {
+ $global_post_id = $this->factory->post->create(
+ array(
+ 'post_content' => 'Global Post',
+ )
+ );
+ $post_id = $this->factory->post->create(
+ array(
+ 'post_content' => '[gallery]',
+ )
+ );
+ $this->factory->attachment->create_object(
+ array(
+ 'file' => 'test.jpg',
+ 'post_parent' => $post_id,
+ 'post_mime_type' => 'image/jpeg',
+ 'post_type' => 'attachment',
+ )
+ );
+ $expected_srcs = array(
+ 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/test.jpg',
+ );
+
+ // Set the global $post context to the other post.
+ $GLOBALS['post'] = get_post( $global_post_id );
+
+ $galleries = get_post_galleries( $post_id, false );
+
+ // The method can return an empty array.
+ $this->assertNotEmpty(
+ $galleries,
+ 'The galleries array is empty.'
+ );
+
+ // This prevents future changes from causing
+ // backwards compatibility breaks.
+ $this->assertArrayHasKey(
+ 'src',
+ $galleries[0],
+ 'A src key does not exist.'
+ );
+
+ $this->assertSameSetsWithIndex(
+ $expected_srcs,
+ $galleries[0]['src'],
+ 'The expected and actual srcs are not the same.'
+ );
+ }
+
+ /**
+ * Test that the global post object does not override
+ * a provided post ID with a block gallery.
+ *
+ * @ticket 43826
+ *
+ * @group block
+ */
+ public function test_respects_post_id_with_block_gallery() {
+ $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[] = '
';
+
+ }
+
+ $ids_joined = join( ',', $ids );
+
+ $global_post_id = $this->factory->post->create(
+ array(
+ 'post_content' => 'Global Post',
+ )
+ );
+
+ $blob = <<< BLOB
+
+
+BLOB;
+
+ $post_id = $this->factory->post->create(
+ array(
+ 'post_content' => $blob,
+ )
+ );
+ $this->factory->attachment->create_object(
+ array(
+ 'file' => 'test.jpg',
+ 'post_parent' => $post_id,
+ 'post_mime_type' => 'image/jpeg',
+ 'post_type' => 'attachment',
+ )
+ );
+ $expected_srcs = array(
+ 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/test.jpg',
+ );
+
+ // Set the global $post context to the other post.
+ $GLOBALS['post'] = get_post( $global_post_id );
+
+ $galleries = get_post_galleries( $post_id, false );
+
+ // The method can return an empty array.
+ $this->assertNotEmpty(
+ $galleries,
+ 'The galleries array is empty.'
+ );
+
+ // This prevents future changes from causing
+ // backwards compatibility breaks.
+ $this->assertArrayHasKey(
+ 'src',
+ $galleries[0],
+ 'A src key does not exist.'
+ );
+
+ $this->assertSameSetsWithIndex(
+ array(
+ array(
+ 'ids' => $ids_joined,
+ 'src' => $ids_srcs,
+ ),
+ ),
+ $galleries,
+ 'The expected and actual srcs are not the same.'
+ );
+ }
+
+ /**
+ * Test that the global post object does not override
+ * a provided post ID with a block gallery v2.
+ *
+ * @ticket 43826
+ *
+ * @group block
+ */
+ public function test_respects_post_id_with_block_gallery_v2() {
+ $attachment_id = self::factory()->attachment->create_object(
+ 'image1.jpg',
+ 0,
+ array(
+ 'post_mime_type' => 'image/jpeg',
+ 'post_type' => 'attachment',
+ )
+ );
+ $metadata = array_merge( array( 'file' => 'image1.jpg' ), $this->img_meta );
+ $url = 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . 'image1.jpg';
+ $global_post_id = $this->factory->post->create(
+ array(
+ 'post_content' => 'Global Post',
+ )
+ );
+
+ wp_update_attachment_metadata( $attachment_id, $metadata );
+
+ $blob = <<< BLOB
+
+
+
+
+
+
+
+
+
+BLOB;
+
+ $post_id = $this->factory->post->create(
+ array(
+ 'post_content' => $blob,
+ )
+ );
+ $this->factory->attachment->create_object(
+ array(
+ 'file' => 'test.jpg',
+ 'post_parent' => $post_id,
+ 'post_mime_type' => 'image/jpeg',
+ 'post_type' => 'attachment',
+ )
+ );
+ $expected_srcs = array(
+ 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/test.jpg',
+ );
+
+ // Set the global $post context to the other post.
+ $GLOBALS['post'] = get_post( $global_post_id );
+
+ $galleries = get_post_galleries( $post_id, false );
+
+ // The method can return an empty array.
+ $this->assertNotEmpty(
+ $galleries,
+ 'The galleries array is empty.'
+ );
+
+ // This prevents future changes from causing
+ // backwards compatibility breaks.
+ $this->assertArrayHasKey(
+ 'src',
+ $galleries[0],
+ 'A src key does not exist.'
+ );
+
+ $this->assertSameSetsWithIndex(
+ array(
+ array(
+ 'ids' => (string) $attachment_id,
+ 'src' => array( $url ),
+ ),
+ ),
+ $galleries,
+ 'The expected and actual srcs are not the same.'
+ );
+ }
+
+ /**
+ * Test that the gallery only contains images specified in
+ * the shortcode's id attribute.
+ *
+ * @ticket 39304
+ *
+ * @group shortcode
+ */
+ public function test_respects_shortcode_id_attribute() {
+ $post_id = $this->factory->post->create(
+ array(
+ 'post_content' => 'No gallery defined',
+ )
+ );
+ $post_id_two = $this->factory->post->create(
+ array(
+ 'post_content' => "[gallery id='$post_id']",
+ )
+ );
+ $this->factory->attachment->create_object(
+ array(
+ 'file' => 'test.jpg',
+ 'post_parent' => $post_id,
+ 'post_mime_type' => 'image/jpeg',
+ 'post_type' => 'attachment',
+ )
+ );
+ $expected_srcs = array(
+ 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/test.jpg',
+ );
+
+ $galleries = get_post_galleries( $post_id_two, false );
+
+ // Set the global $post context.
+ $GLOBALS['post'] = get_post( $post_id_two );
+ $galleries_with_global_context = get_post_galleries( $post_id_two, false );
+
+ // Check that the global post state doesn't affect the results.
+ $this->assertSameSetsWithIndex(
+ $galleries,
+ $galleries_with_global_context,
+ 'The global post state affected the results.'
+ );
+
+ // The method can return an empty array.
+ $this->assertNotEmpty(
+ $galleries,
+ 'The galleries array is empty.'
+ );
+
+ // The method can return an array of strings
+ // instead of an array of arrays.
+ $this->assertIsArray(
+ $galleries[0],
+ 'The returned data does not contain an array.'
+ );
+
+ // This prevents future changes from causing
+ // backwards compatibility breaks.
+ $this->assertArrayHasKey(
+ 'src',
+ $galleries[0],
+ 'A src key does not exist.'
+ );
+
+ $this->assertSameSetsWithIndex(
+ $expected_srcs,
+ $galleries[0]['src'],
+ 'The expected and actual srcs are not the same.'
+ );
+ }
+
+ /**
+ * Test that galleries only contain images specified in the
+ * id attribute of their respective shortcode and block.
+ *
+ * @ticket 43826
+ *
+ * @group blocks
+ * @group shortcode
+ */
+ public function test_respects_shortcode_and_block_id_attributes() {
+ // 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->assertSameSetsWithIndex(
+ array(
+ array(
+ 'ids' => $ids1_joined,
+ 'src' => array_slice( $ids_srcs, 0, 3 ),
+ ),
+ array(
+ 'ids' => $ids2_joined,
+ 'src' => array_slice( $ids_srcs, 3, 3 ),
+ ),
+ ),
+ $galleries
+ );
+
+ }
+
+ /**
+ * Test that galleries contain the additional attributes
+ * specified for their respective shortcode and block.
+ *
+ * @ticket 43826
+ *
+ * @group blocks
+ * @group shortcode
+ */
+ public function test_respects_additional_shortcode_and_block_attributes() {
+ // 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->assertSameSetsWithIndex(
+ array(
+ array(
+ 'ids' => $ids1_joined,
+ // The shortcode code passes arbitrary attributes
+ 'type' => 'type',
+ 'foo' => 'bar',
+ 'src' => array_slice( $ids_srcs, 0, 3 ),
+ ),
+ array(
+ 'ids' => $ids2_joined,
+ // The block only passes ids, no other attributes
+ 'src' => array_slice( $ids_srcs, 3, 3 ),
+ ),
+ ),
+ $galleries
+ );
+
+ }
+
+ /**
+ * Test that srcs are retrieved from the HTML of a block gallery
+ * that has no JSON blob.
+ *
+ * @ticket 43826
+ *
+ * @group blocks
+ */
+ public function test_returns_srcs_from_html_with_block_with_no_json_blob() {
+ // Set up an unattached image.
+ $image_id = $this->factory->attachment->create_object(
+ array(
+ 'file' => 'test.jpg',
+ 'post_parent' => 0,
+ 'post_mime_type' => 'image/jpeg',
+ 'post_type' => 'attachment',
+ )
+ );
+
+ $image_url = 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/test.jpg';
+
+ $blob = <<< BLOB
+
+-
+
+
+
+
+
+
+BLOB;
+
+ $post_id = $this->factory->post->create(
+ array(
+ 'post_content' => $blob,
+ )
+ );
+
+ $expected_srcs = array( $image_url );
+ $galleries = get_post_galleries( $post_id, false );
+
+ // The method can return an empty array.
+ $this->assertNotEmpty(
+ $galleries,
+ 'The galleries array is empty.'
+ );
+
+ // The method can return an array of strings
+ // instead of an array of arrays.
+ $this->assertIsArray(
+ $galleries[0],
+ 'The returned data does not contain an array.'
+ );
+
+ // This prevents future changes from causing
+ // backwards compatibility breaks.
+ $this->assertArrayHasKey(
+ 'src',
+ $galleries[0],
+ 'A src key does not exist.'
+ );
+
+ $this->assertSameSetsWithIndex(
+ $expected_srcs,
+ $galleries[0]['src'],
+ 'The expected and actual srcs are not the same.'
+ );
+ }
+
+ /**
+ * Test that srcs are returned for a block gallery nested within
+ * other blocks.
+ *
+ * @ticket 43826
+ *
+ * @group blocks
+ */
+ public function test_returns_srcs_with_nested_block_gallery() {
+ $post_id = $this->factory->post->create(
+ array(
+ 'post_content' => 'I have no gallery.',
+ )
+ );
+ $image_id = $this->factory->attachment->create_object(
+ array(
+ 'file' => 'test.jpg',
+ 'post_parent' => $post_id,
+ 'post_mime_type' => 'image/jpeg',
+ 'post_type' => 'attachment',
+ )
+ );
+
+ $blob = <<
+
+
+
+
+
+BLOB;
+
+ $post_id_two = $this->factory->post->create( array( 'post_content' => $blob ) );
+
+ $galleries = get_post_galleries( $post_id_two, false );
+
+ // The method can return an empty array.
+ $this->assertNotEmpty(
+ $galleries,
+ 'The galleries array is empty.'
+ );
+
+ // The method can return an array of strings
+ // instead of an array of arrays.
+ $this->assertIsArray(
+ $galleries[0],
+ 'The returned data does not contain an array.'
+ );
+
+ // This prevents future changes from causing
+ // backwards compatibility breaks.
+ $this->assertArrayHasKey(
+ 'src',
+ $galleries[0],
+ 'A src key does not exist.'
+ );
+
+ $this->assertNotEmpty(
+ $galleries[0]['src'],
+ 'The src key of the first gallery is empty.'
+ );
+ }
+}