Make WordPress Core

Changeset 52190


Ignore:
Timestamp:
11/16/2021 09:23:12 PM (5 years ago)
Author:
hellofromTonya
Message:

Media: Add support for v1 and v2 gallery block in get_post_galleries().

The get_post_galleries() function only handled galleries from the [gallery] shortcode. It did not process gallery blocks.

Introducing v1 and v2 gallery block support in get_post_galleries() including support for innerblock nesting.

There are no changes to how the function is called. It detects if the post content has one or more gallery blocks. If detected, it parses the blocks and then processes to add each gallery block's HTML to the array of galleries before being passed through the filter and returned.

Includes integration tests.

Follow-up to [24682], [43309], [48262], [52042].

Props glendaviesnz, costdev, antpb, audrasjb, birgire, celloexpressions, desrosj, hellofromTonya, jeffpaul, lynk, pento, ramonopoly, russhylov, takahashi_fumiki, tellyworth.
Fixes #43826.

Location:
trunk
Files:
1 added
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/media.php

    r52065 r52190  
    47264726        }
    47274727
    4728         if ( ! has_shortcode( $post->post_content, 'gallery' ) ) {
     4728        if ( ! has_shortcode( $post->post_content, 'gallery' ) && ! has_block( 'gallery', $post->post_content ) ) {
    47294729                return array();
    47304730        }
     
    47654765                                }
    47664766                        }
     4767                }
     4768        }
     4769
     4770        if ( has_block( 'gallery', $post->post_content ) ) {
     4771                $post_blocks = parse_blocks( $post->post_content );
     4772
     4773                while ( $block = array_shift( $post_blocks ) ) {
     4774                        $has_inner_blocks = ! empty( $block['innerBlocks'] );
     4775
     4776                        // Skip blocks with no blockName and no innerHTML.
     4777                        if ( ! $block['blockName'] ) {
     4778                                continue;
     4779                        }
     4780
     4781                        // All blocks nested inside non-Gallery blocks should be in the root array.
     4782                        if ( $has_inner_blocks && 'core/gallery' !== $block['blockName'] ) {
     4783                                array_push( $post_blocks, ...$block['innerBlocks'] );
     4784                                continue;
     4785                        }
     4786
     4787                        // New Gallery block format as HTML.
     4788                        if ( $has_inner_blocks && $html ) {
     4789                                $block_html  = wp_list_pluck( $block['innerBlocks'], 'innerHTML' );
     4790                                $galleries[] = '<figure>' . implode( ' ', $block_html ) . '</figure>';
     4791                                continue;
     4792                        }
     4793
     4794                        $srcs = array();
     4795
     4796                        // New Gallery block format as an array.
     4797                        if ( $has_inner_blocks ) {
     4798                                $attrs = wp_list_pluck( $block['innerBlocks'], 'attrs' );
     4799                                $ids   = wp_list_pluck( $attrs, 'id' );
     4800
     4801                                foreach ( $ids as $id ) {
     4802                                        $url = wp_get_attachment_url( $id );
     4803
     4804                                        if ( is_string( $url ) && ! in_array( $url, $srcs, true ) ) {
     4805                                                $srcs[] = $url;
     4806                                        }
     4807                                }
     4808
     4809                                $galleries[] = array(
     4810                                        'ids' => implode( ',', $ids ),
     4811                                        'src' => $srcs,
     4812                                );
     4813
     4814                                continue;
     4815                        }
     4816
     4817                        // Old Gallery block format as HTML.
     4818                        if ( $html ) {
     4819                                $galleries[] = $block['innerHTML'];
     4820                                continue;
     4821                        }
     4822
     4823                        // Old Gallery block format as an array.
     4824                        $ids = ! empty( $block['attrs']['ids'] ) ? $block['attrs']['ids'] : array();
     4825
     4826                        // If present, use the image IDs from the JSON blob as canonical.
     4827                        if ( ! empty( $ids ) ) {
     4828                                foreach ( $ids as $id ) {
     4829                                        $url = wp_get_attachment_url( $id );
     4830
     4831                                        if ( is_string( $url ) && ! in_array( $url, $srcs, true ) ) {
     4832                                                $srcs[] = $url;
     4833                                        }
     4834                                }
     4835
     4836                                $galleries[] = array(
     4837                                        'ids' => implode( ',', $ids ),
     4838                                        'src' => $srcs,
     4839                                );
     4840
     4841                                continue;
     4842                        }
     4843
     4844                        // Otherwise, extract srcs from the innerHTML.
     4845                        preg_match_all( '#src=([\'"])(.+?)\1#is', $block['innerHTML'], $found_srcs, PREG_SET_ORDER );
     4846
     4847                        if ( ! empty( $found_srcs[0] ) ) {
     4848                                foreach ( $found_srcs as $src ) {
     4849                                        if ( isset( $src[2] ) && ! in_array( $src[2], $srcs, true ) ) {
     4850                                                $srcs[] = $src[2];
     4851                                        }
     4852                                }
     4853                        }
     4854
     4855                        $galleries[] = array( 'src' => $srcs );
    47674856                }
    47684857        }
  • trunk/tests/phpunit/tests/media.php

    r52065 r52190  
    513513                $ids1      = array();
    514514                $ids1_srcs = array();
    515                 foreach ( range( 1, 3 ) as $i ) {
     515                foreach ( range( 1, 6 ) as $i ) {
    516516                        $attachment_id = self::factory()->attachment->create_object(
    517517                                "image$i.jpg",
     
    545545                }
    546546
    547                 $ids1_joined = implode( ',', $ids1 );
    548                 $ids2_joined = implode( ',', $ids2 );
     547                $ids1_joined = join( ',', array_slice( $ids1, 0, 3 ) );
     548                $ids2_joined = join( ',', array_slice( $ids2, 3, 3 ) );
    549549
    550550                $blob    = <<<BLOB
     
    555555                $post_id = self::factory()->post->create( array( 'post_content' => $blob ) );
    556556                $srcs    = get_post_galleries_images( $post_id );
    557                 $this->assertSame( $srcs, array( $ids1_srcs, $ids2_srcs ) );
    558         }
    559 
    560         /**
    561          * @ticket 39304
    562          */
    563         public function test_post_galleries_images_without_global_post() {
    564                 // Set up an unattached image.
    565                 $this->factory->attachment->create_object(
    566                         array(
    567                                 'file'           => 'test.jpg',
    568                                 'post_parent'    => 0,
    569                                 'post_mime_type' => 'image/jpeg',
    570                                 'post_type'      => 'attachment',
    571                         )
    572                 );
    573 
    574                 $post_id = $this->factory->post->create(
    575                         array(
    576                                 'post_content' => '[gallery]',
    577                         )
    578                 );
    579 
    580                 $galleries = get_post_galleries( $post_id, false );
    581 
    582                 $this->assertEmpty( $galleries[0]['src'] );
    583         }
    584 
    585         /**
    586          * @ticket 39304
    587          */
    588         public function test_post_galleries_ignores_global_post() {
    589                 $global_post_id = $this->factory->post->create(
    590                         array(
    591                                 'post_content' => 'Global Post',
    592                         )
    593                 );
    594                 $post_id        = $this->factory->post->create(
    595                         array(
    596                                 'post_content' => '[gallery]',
    597                         )
    598                 );
    599                 $this->factory->attachment->create_object(
    600                         array(
    601                                 'file'           => 'test.jpg',
    602                                 'post_parent'    => $post_id,
    603                                 'post_mime_type' => 'image/jpeg',
    604                                 'post_type'      => 'attachment',
    605                         )
    606                 );
    607                 $expected_srcs = array(
    608                         'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/test.jpg',
    609                 );
    610 
    611                 // Set the global $post context to the other post.
    612                 $GLOBALS['post'] = get_post( $global_post_id );
    613 
    614                 $galleries = get_post_galleries( $post_id, false );
    615 
    616                 $this->assertNotEmpty( $galleries[0]['src'] );
    617                 $this->assertSame( $galleries[0]['src'], $expected_srcs );
    618         }
    619 
    620         /**
    621          * @ticket 39304
    622          */
    623         public function test_post_galleries_respects_id_attrs() {
    624                 $post_id     = $this->factory->post->create(
    625                         array(
    626                                 'post_content' => 'No gallery defined',
    627                         )
    628                 );
    629                 $post_id_two = $this->factory->post->create(
    630                         array(
    631                                 'post_content' => "[gallery id='$post_id']",
    632                         )
    633                 );
    634                 $this->factory->attachment->create_object(
    635                         array(
    636                                 'file'           => 'test.jpg',
    637                                 'post_parent'    => $post_id,
    638                                 'post_mime_type' => 'image/jpeg',
    639                                 'post_type'      => 'attachment',
    640                         )
    641                 );
    642                 $expected_srcs = array(
    643                         'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/test.jpg',
    644                 );
    645 
    646                 $galleries = get_post_galleries( $post_id_two, false );
    647 
    648                 // Set the global $post context.
    649                 $GLOBALS['post']               = get_post( $post_id_two );
    650                 $galleries_with_global_context = get_post_galleries( $post_id_two, false );
    651 
    652                 // Check that the global post state doesn't affect the results.
    653                 $this->assertSame( $galleries, $galleries_with_global_context );
    654 
    655                 $this->assertNotEmpty( $galleries[0]['src'] );
    656                 $this->assertSame( $galleries[0]['src'], $expected_srcs );
     557                $this->assertSameSetsWithIndex( $srcs, array( array_slice( $ids1_srcs, 0, 3 ), array_slice( $ids2_srcs, 3, 3 ) ) );
    657558        }
    658559
     
    706607                $srcs    = get_post_gallery_images( $post_id );
    707608                $this->assertSame( $srcs, $ids1_srcs );
     609        }
     610
     611        /**
     612         * @ticket 43826
     613         * @group blocks
     614         */
     615        public function test_block_post_gallery_images() {
     616                // Similar to test_post_gallery_images but with blocks instead of shortcodes
     617                $ids      = array();
     618                $imgs     = array();
     619                $ids_srcs = array();
     620                foreach ( range( 1, 6 ) as $i ) {
     621                        $attachment_id = self::factory()->attachment->create_object(
     622                                "image$i.jpg",
     623                                0
     624                        );
     625                        $metadata      = array_merge( array( 'file' => "image$i.jpg" ), $this->img_meta );
     626                        wp_update_attachment_metadata( $attachment_id, $metadata );
     627                        $ids[]      = $attachment_id;
     628                        $url        = 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . "image$i.jpg";
     629                        $ids_srcs[] = $url;
     630                        $imgs[]     = '<figure><img src="' . $url . '" data-id="' . $i . '" /></figure>';
     631                }
     632
     633                $imgs1_joined = join( "\n", array_slice( $imgs, 0, 3 ) );
     634                $imgs2_joined = join( "\n", array_slice( $imgs, 3, 3 ) );
     635
     636                $blob    = <<<BLOB
     637<!-- wp:gallery -->
     638$imgs1_joined
     639<!-- /wp:gallery -->
     640<!-- wp:gallery -->
     641$imgs2_joined
     642<!-- /wp:gallery -->
     643BLOB;
     644                $post_id = self::factory()->post->create( array( 'post_content' => $blob ) );
     645                $srcs    = get_post_gallery_images( $post_id );
     646                $this->assertSameSetsWithIndex( array_slice( $ids_srcs, 0, 3 ), $srcs );
     647        }
     648
     649        /**
     650         * @ticket 43826
     651         * @group blocks
     652         */
     653        public function test_block_post_gallery_images_json() {
     654                // Similar to test_block_post_gallery_images, with IDs in the json blob
     655                $ids      = array();
     656                $imgs     = array();
     657                $ids_srcs = array();
     658                foreach ( range( 1, 6 ) as $i ) {
     659                        $attachment_id = self::factory()->attachment->create_object(
     660                                "image$i.jpg",
     661                                0
     662                        );
     663                        $metadata      = array_merge( array( 'file' => "image$i.jpg" ), $this->img_meta );
     664                        wp_update_attachment_metadata( $attachment_id, $metadata );
     665                        $ids[]      = $attachment_id;
     666                        $url        = 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . "image$i.jpg";
     667                        $ids_srcs[] = $url;
     668                        $imgs[]     = '<figure><img src="' . $url . '" data-id="' . $i . '" /></figure>';
     669
     670                }
     671
     672                $ids1_joined = join( ',', array_slice( $ids, 0, 3 ) );
     673                $ids2_joined = join( ',', array_slice( $ids, 3, 3 ) );
     674
     675                $blob    = <<<BLOB
     676<!-- wp:gallery {"ids":[$ids1_joined]} -->
     677<!-- /wp:gallery -->
     678
     679<!-- wp:gallery {"ids":[$ids2_joined]} -->
     680<!-- /wp:gallery -->
     681BLOB;
     682                $post_id = self::factory()->post->create( array( 'post_content' => $blob ) );
     683                $srcs    = get_post_gallery_images( $post_id );
     684                $this->assertSameSetsWithIndex( array_slice( $ids_srcs, 0, 3 ), $srcs );
     685        }
     686
     687        /**
     688         * @ticket 43826
     689         * @group blocks
     690         */
     691        public function test_mixed_post_gallery_images() {
     692                // Similar to test_post_gallery_images but with a shortcode and a block in the same post
     693                $ids      = array();
     694                $imgs     = array();
     695                $ids_srcs = array();
     696                foreach ( range( 1, 6 ) as $i ) {
     697                        $attachment_id = self::factory()->attachment->create_object(
     698                                "image$i.jpg",
     699                                0,
     700                                array(
     701                                        'post_mime_type' => 'image/jpeg',
     702                                        'post_type'      => 'attachment',
     703                                )
     704                        );
     705                        $metadata      = array_merge( array( 'file' => "image$i.jpg" ), $this->img_meta );
     706                        wp_update_attachment_metadata( $attachment_id, $metadata );
     707                        $ids[]      = $attachment_id;
     708                        $url        = 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . "image$i.jpg";
     709                        $ids_srcs[] = $url;
     710                        $imgs[]     = '<figure><img src="' . $url . '" data-id="' . $i . '" /></figure>';
     711                }
     712
     713                $ids1_joined  = join( "\n", array_slice( $ids, 0, 3 ) );
     714                $ids2_joined  = join( "\n", array_slice( $ids, 3, 3 ) );
     715                $imgs2_joined = join( "\n", array_slice( $imgs, 3, 3 ) );
     716
     717                $blob    = <<<BLOB
     718[gallery ids="$ids1_joined"]
     719
     720[gallery ids="$ids2_joined"]
     721<!-- wp:gallery -->
     722$imgs2_joined
     723<!-- /wp:gallery -->
     724BLOB;
     725                $post_id = self::factory()->post->create( array( 'post_content' => $blob ) );
     726                $srcs    = get_post_gallery_images( $post_id );
     727                $this->assertSameSetsWithIndex( array_slice( $ids_srcs, 0, 3 ), $srcs );
     728        }
     729
     730        /**
     731         * @ticket 43826
     732         * @group blocks
     733         */
     734        public function test_block_inner_post_gallery_images() {
     735                // Make sure get_post_gallery_images() works with gallery blocks that are nested inside something else
     736                $ids      = array();
     737                $imgs     = array();
     738                $ids_srcs = array();
     739                foreach ( range( 1, 3 ) as $i ) {
     740                        $attachment_id = self::factory()->attachment->create_object(
     741                                "image$i.jpg",
     742                                0,
     743                                array(
     744                                        'post_mime_type' => 'image/jpeg',
     745                                        'post_type'      => 'attachment',
     746                                )
     747                        );
     748                        $metadata      = array_merge( array( 'file' => "image$i.jpg" ), $this->img_meta );
     749                        wp_update_attachment_metadata( $attachment_id, $metadata );
     750                        $ids[]      = $attachment_id;
     751                        $url        = 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . "image$i.jpg";
     752                        $ids_srcs[] = $url;
     753                        $imgs[]     = '<figure><img src="' . $url . '" data-id="' . $i . '" /></figure>';
     754
     755                }
     756
     757                $imgs_joined = join( "\n", $imgs );
     758
     759                $blob    = <<<BLOB
     760<!-- wp:columns -->
     761<!-- wp:column -->
     762<!-- wp:gallery -->
     763$imgs_joined
     764<!-- /wp:gallery -->
     765<!-- /wp:column -->
     766<!-- /wp:columns -->
     767BLOB;
     768                $post_id = self::factory()->post->create( array( 'post_content' => $blob ) );
     769                $srcs    = get_post_gallery_images( $post_id );
     770                $this->assertSameSetsWithIndex( $ids_srcs, $srcs );
     771        }
     772
     773        /**
     774         * @ticket 43826
     775         * @group blocks
     776         */
     777        public function test_block_post_gallery_innerblock_images() {
     778                // Make sure get_post_gallery_images() works with new version of gallery block with nested image blocks.
     779                $ids      = array();
     780                $imgs     = array();
     781                $ids_srcs = array();
     782                foreach ( range( 1, 3 ) as $i ) {
     783                        $attachment_id = self::factory()->attachment->create_object(
     784                                "image$i.jpg",
     785                                0,
     786                                array(
     787                                        'post_mime_type' => 'image/jpeg',
     788                                        'post_type'      => 'attachment',
     789                                )
     790                        );
     791                        $metadata      = array_merge( array( 'file' => "image$i.jpg" ), $this->img_meta );
     792                        wp_update_attachment_metadata( $attachment_id, $metadata );
     793                        $ids[]      = $attachment_id;
     794                        $url        = 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . "image$i.jpg";
     795                        $ids_srcs[] = $url;
     796                        $imgs[]     = '<!-- wp:image {"id":' . $attachment_id . ',"sizeSlug":"large","linkDestination":"none"} --><figure class="wp-block-image size-large"><img src="' . $url . '" /></figure><!-- /wp:image -->';
     797
     798                }
     799
     800                $imgs_joined = join( "\n", $imgs );
     801
     802                $blob    = <<<BLOB
     803<!-- wp:gallery -->
     804<figure class="wp-block-gallery has-nested-images columns-default is-cropped">
     805$imgs_joined
     806</figure>
     807<!-- /wp:gallery -->
     808BLOB;
     809                $post_id = self::factory()->post->create( array( 'post_content' => $blob ) );
     810                $srcs    = get_post_gallery_images( $post_id );
     811                $this->assertSameSetsWithIndex( $ids_srcs, $srcs );
    708812        }
    709813
Note: See TracChangeset for help on using the changeset viewer.