Make WordPress Core

Changeset 57668


Ignore:
Timestamp:
02/20/2024 03:20:39 PM (3 years ago)
Author:
Bernhard Reiter
Message:

Block Hooks: Allow hooked_block filters to return null.

Allow returning null from the hooked_block and hooked_block_{$hooked_block_type} filters to suppress a hooked block from being inserted. This is required to allow extenders conditionally inserting a hooked block based on e.g. the value of an attribute of the anchor block.

Props swissspidy, gziolo, joshuatf, tomjcafferkey.
Fixes 60580.

Location:
trunk
Files:
3 edited

Legend:

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

    r57660 r57668  
    898898                 * @since 6.5.0
    899899                 *
    900                  * @param array                           $parsed_hooked_block The parsed block array for the given hooked block type.
     900                 * @param array|null                      $parsed_hooked_block The parsed block array for the given hooked block type, or null to suppress the block.
    901901                 * @param string                          $hooked_block_type   The hooked block type name.
    902902                 * @param string                          $relative_position   The relative position of the hooked block.
    … …  
    914914                 * @since 6.5.0
    915915                 *
    916                  * @param array                           $parsed_hooked_block The parsed block array for the given hooked block type.
     916                 * @param array|null                      $parsed_hooked_block The parsed block array for the given hooked block type, or null to suppress the block.
    917917                 * @param string                          $hooked_block_type   The hooked block type name.
    918918                 * @param string                          $relative_position   The relative position of the hooked block.
    … …  
    923923                $parsed_hooked_block = apply_filters( "hooked_block_{$hooked_block_type}", $parsed_hooked_block, $hooked_block_type, $relative_position, $parsed_anchor_block, $context );
    924924
     925                if ( null === $parsed_hooked_block ) {
     926                        continue;
     927                }
     928
    925929                // It's possible that the filter returned a block of a different type, so we explicitly
    926930                // look for the original `$hooked_block_type` in the `ignoredHookedBlocks` metadata.
    … …  
    961965        if ( empty( $hooked_block_types ) ) {
    962966                return '';
     967        }
     968
     969        foreach ( $hooked_block_types as $index => $hooked_block_type ) {
     970                $parsed_hooked_block = array(
     971                        'blockName'    => $hooked_block_type,
     972                        'attrs'        => array(),
     973                        'innerBlocks'  => array(),
     974                        'innerContent' => array(),
     975                );
     976
     977                /** This filter is documented in wp-includes/blocks.php */
     978                $parsed_hooked_block = apply_filters( 'hooked_block', $parsed_hooked_block, $hooked_block_type, $relative_position, $parsed_anchor_block, $context );
     979
     980                /** This filter is documented in wp-includes/blocks.php */
     981                $parsed_hooked_block = apply_filters( "hooked_block_{$hooked_block_type}", $parsed_hooked_block, $hooked_block_type, $relative_position, $parsed_anchor_block, $context );
     982
     983                if ( null === $parsed_hooked_block ) {
     984                        unset( $hooked_block_types[ $index ] );
     985                }
    963986        }
    964987
  • trunk/tests/phpunit/tests/blocks/insertHookedBlocks.php

    r57660 r57668  
    181181                );
    182182        }
     183
     184        /**
     185         * @ticket 60580
     186         *
     187         * @covers ::insert_hooked_blocks
     188         */
     189        public function test_insert_hooked_blocks_filter_can_suppress_hooked_block() {
     190                $anchor_block = array(
     191                        'blockName'    => self::ANCHOR_BLOCK_TYPE,
     192                        'attrs'        => array(
     193                                'layout' => array(
     194                                        'type' => 'flex',
     195                                ),
     196                        ),
     197                        'innerContent' => array(),
     198                );
     199
     200                $filter = function ( $parsed_hooked_block, $hooked_block_type, $relative_position, $parsed_anchor_block ) {
     201                        // Is the hooked block adjacent to the anchor block?
     202                        if ( 'before' !== $relative_position && 'after' !== $relative_position ) {
     203                                return $parsed_hooked_block;
     204                        }
     205
     206                        if (
     207                                isset( $parsed_anchor_block['attrs']['layout']['type'] ) &&
     208                                'flex' === $parsed_anchor_block['attrs']['layout']['type']
     209                        ) {
     210                                return null;
     211                        }
     212
     213                        return $parsed_hooked_block;
     214                };
     215                add_filter( 'hooked_block_' . self::HOOKED_BLOCK_TYPE, $filter, 10, 4 );
     216                $actual = insert_hooked_blocks( $anchor_block, 'after', self::HOOKED_BLOCKS, array() );
     217                remove_filter( 'hooked_block_' . self::HOOKED_BLOCK_TYPE, $filter );
     218
     219                $this->assertSame( '', $actual, "No markup should've been generated for hooked block suppressed by filter." );
     220        }
    183221}
  • trunk/tests/phpunit/tests/blocks/setIgnoredHookedBlocksMetadata.php

    r57666 r57668  
    145145                );
    146146        }
     147
     148        /**
     149         * @ticket 60580
     150         *
     151         * @covers ::set_ignored_hooked_blocks_metadata
     152         */
     153        public function test_set_ignored_hooked_blocks_metadata_for_block_suppressed_by_filter() {
     154                $anchor_block = array(
     155                        'blockName' => 'tests/anchor-block',
     156                        'attrs'     => array(),
     157                );
     158
     159                $hooked_blocks = array(
     160                        'tests/anchor-block' => array(
     161                                'after' => array( 'tests/hooked-block', 'tests/hooked-block-suppressed-by-filter' ),
     162                        ),
     163                );
     164
     165                $filter = function ( $parsed_hooked_block, $hooked_block_type, $relative_position, $parsed_anchor_block ) {
     166                        if ( 'tests/anchor-block' === $parsed_anchor_block['blockName'] && 'after' === $relative_position ) {
     167                                return null;
     168                        }
     169
     170                        return $parsed_hooked_block;
     171                };
     172
     173                add_filter( 'hooked_block_tests/hooked-block-suppressed-by-filter', $filter, 10, 4 );
     174                set_ignored_hooked_blocks_metadata( $anchor_block, 'after', $hooked_blocks, null );
     175                remove_filter( 'hooked_block_tests/hooked-block-suppressed-by-filter', $filter );
     176
     177                $this->assertSame( array( 'tests/hooked-block' ), $anchor_block['attrs']['metadata']['ignoredHookedBlocks'] );
     178        }
    147179}
Note: See TracChangeset for help on using the changeset viewer.