Make WordPress Core

Changeset 52190


Ignore:
Timestamp:
11/16/2021 09:23:12 PM (3 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.