Make WordPress Core

Changeset 54670 for trunk


Ignore:
Timestamp:
10/24/2022 02:14:25 PM (4 years ago)
Author:
Bernhard Reiter
Message:

Blocks: Allow arrays for deprecated asset types in block registration.

In register_block_type, continue to allow passing arrays as the editor_script, script, view_script, editor_style, and style arguments. Note that those fields were soft-deprecated in favor of their _handles counterparts in [54155], which would allow specifying multiple items. At the same time, the deprecated fields were limited to string or null.

However, this broke existing code that passed an array as one of those arguments. For backwards compatibility, this change thus restores the previous behavior. It is implemented in WP_Block_Type as a pair of __get() and __set() methods that wrap around the corresponding _handles members, which are arrays of strings.

It also affects the REST API endpoint for block types. The latter’s schema has never allowed for anything other than string or null for any of those fields. For this reason, it now returns the first element of the array stored in the corresponding _handles member in WP_Block_Type.

Follow-up [54155].
Props nendeb55, costdev, gziolo, spacedmonkey, mukesh27, sergeybiryukov, audrasjb.
Fixes #56707.

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/class-wp-block-type.php

    r54210 r54670  
    296296         * @param string $name Deprecated property name.
    297297         *
    298          * @return string|null|void The value read from the new property if the first item in the array provided,
    299          *                          null when value not found, or void when unknown property name provided.
     298         * @return string|string[]|null|void The value read from the new property if the first item in the array provided,
     299         *                                   null when value not found, or void when unknown property name provided.
    300300         */
    301301        public function __get( $name ) {
     
    305305
    306306                $new_name = $name . '_handles';
     307
     308                if ( ! property_exists( $this, $new_name ) || ! is_array( $this->{$new_name} ) ) {
     309                        return null;
     310                }
     311
     312                if ( count( $this->{$new_name} ) > 1 ) {
     313                        return $this->{$new_name};
     314                }
    307315                return isset( $this->{$new_name}[0] ) ? $this->{$new_name}[0] : null;
    308316        }
     
    344352                }
    345353
     354                $new_name = $name . '_handles';
     355
     356                if ( is_array( $value ) ) {
     357                        $filtered = array_filter( $value, 'is_string' );
     358
     359                        if ( count( $filtered ) !== count( $value ) ) {
     360                                        _doing_it_wrong(
     361                                                __METHOD__,
     362                                                sprintf(
     363                                                        /* translators: %s: The '$value' argument. */
     364                                                        __( 'The %s argument must be a string or a string array.' ),
     365                                                        '<code>$value</code>'
     366                                                ),
     367                                                '6.1.0'
     368                                        );
     369                        }
     370
     371                        $this->{$new_name} = array_values( $filtered );
     372                        return;
     373                }
     374
    346375                if ( ! is_string( $value ) ) {
    347376                        return;
    348377                }
    349378
    350                 $new_name             = $name . '_handles';
    351                 $this->{$new_name}[0] = $value;
     379                $this->{$new_name} = array( $value );
    352380        }
    353381
  • trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-block-types-controller.php

    r54210 r54670  
    296296                                if ( isset( $block_type->$extra_field ) ) {
    297297                                        $field = $block_type->$extra_field;
     298                                        if ( in_array( $extra_field, $deprecated_fields, true ) && is_array( $field ) ) {
     299                                                // Since the schema only allows strings or null (but no arrays), we return the first array item.
     300                                                $field = ! empty( $field ) ? array_shift( $field ) : '';
     301                                        }
    298302                                } elseif ( array_key_exists( 'default', $schema['properties'][ $extra_field ] ) ) {
    299303                                        $field = $schema['properties'][ $extra_field ]['default'];
  • trunk/tests/phpunit/tests/blocks/register.php

    r54472 r54670  
    554554
    555555        /**
     556         * Tests that an array value for 'editor_script' is correctly set and retrieved.
     557         *
     558         * As 'editor_script' is now a deprecated property, this should also set
     559         * the value for the 'editor_script_handles' property.
     560         *
     561         * @ticket 56707
     562         *
     563         * @covers ::register_block_type
     564         * @covers WP_Block_Type::__set
     565         * @covers WP_Block_Type::__get
     566         *
     567         * @dataProvider data_register_block_type_accepts_editor_script_array
     568         *
     569         * @param array $editor_script The editor script array to register.
     570         * @param array $expected      The expected registered editor script.
     571         */
     572        public function test_register_block_type_accepts_editor_script_array( $editor_script, $expected ) {
     573                $settings = array( 'editor_script' => $editor_script );
     574                register_block_type( 'core/test-static', $settings );
     575
     576                $registry   = WP_Block_Type_Registry::get_instance();
     577                $block_type = $registry->get_registered( 'core/test-static' );
     578                $this->assertObjectHasAttribute( 'editor_script_handles', $block_type );
     579                $actual_script         = $block_type->editor_script;
     580                $actual_script_handles = $block_type->editor_script_handles;
     581
     582                $this->assertSame(
     583                        $expected,
     584                        $actual_script,
     585                        'editor_script was not set to the correct value.'
     586                );
     587
     588                $this->assertSame(
     589                        (array) $expected,
     590                        $actual_script_handles,
     591                        'editor_script_handles was not set to the correct value.'
     592                );
     593        }
     594
     595        /**
     596         * Data provider for test_register_block_type_accepts_editor_script_array().
     597         *
     598         * @return array
     599         */
     600        public function data_register_block_type_accepts_editor_script_array() {
     601                return array(
     602                        'an empty array'      => array(
     603                                'editor_script' => array(),
     604                                'expected'      => null,
     605                        ),
     606                        'a single item array' => array(
     607                                'editor_script' => array( 'hello' ),
     608                                'expected'      => 'hello',
     609                        ),
     610                        'a multi-item array'  => array(
     611                                'editor_script' => array( 'hello', 'world' ),
     612                                'expected'      => array( 'hello', 'world' ),
     613                        ),
     614                );
     615        }
     616
     617        /**
     618         * Tests that an array value for 'editor_script' containing invalid values
     619         * correctly triggers _doing_it_wrong(), filters the value, and sets the
     620         * property to the result.
     621         *
     622         * As 'editor_script' is now a deprecated property, this should also set
     623         * the value for the 'editor_script_handles' property.
     624         *
     625         * @ticket 56707
     626         *
     627         * @covers ::register_block_type
     628         * @covers WP_Block_Type::__set
     629         * @covers WP_Block_Type::__get
     630         *
     631         * @dataProvider data_register_block_type_throws_doing_it_wrong
     632         *
     633         * @expectedIncorrectUsage WP_Block_Type::__set
     634         *
     635         * @param array $editor_script The editor script array to register.
     636         * @param array $expected      The expected registered editor script.
     637         */
     638        public function test_register_block_type_throws_doing_it_wrong( $editor_script, $expected ) {
     639                $settings = array( 'editor_script' => $editor_script );
     640                register_block_type( 'core/test-static', $settings );
     641
     642                $registry   = WP_Block_Type_Registry::get_instance();
     643                $block_type = $registry->get_registered( 'core/test-static' );
     644                $this->assertObjectHasAttribute( 'editor_script_handles', $block_type );
     645                $actual_script         = $block_type->editor_script;
     646                $actual_script_handles = $block_type->editor_script_handles;
     647
     648                $this->assertSame(
     649                        $expected,
     650                        $actual_script,
     651                        'editor_script was not set to the correct value.'
     652                );
     653
     654                $this->assertSame(
     655                        (array) $expected,
     656                        $actual_script_handles,
     657                        'editor_script_handles was not set to the correct value.'
     658                );
     659        }
     660
     661        /**
     662         * Data provider for test_register_block_type_throws_doing_it_wrong().
     663         *
     664         * @return array
     665         */
     666        public function data_register_block_type_throws_doing_it_wrong() {
     667                return array(
     668                        'a non-string array'     => array(
     669                                'editor_script' => array( null, false, true, -1, 0, 1, -1.0, 0.0, 1.0, INF, NAN, new stdClass() ),
     670                                'expected'      => null,
     671                        ),
     672                        'a partial string array' => array(
     673                                'editor_script' => array( null, false, 'script.js', true, 0, 'actions.js', 1, INF ),
     674                                'expected'      => array( 'script.js', 'actions.js' ),
     675                        ),
     676                        'a partial string array that results in one item with non-zero index' => array(
     677                                'editor_script' => array( null, false, 'script.js' ),
     678                                'expected'      => 'script.js',
     679                        ),
     680                );
     681        }
     682
     683        /**
    556684         * @ticket 52301
    557685         */
  • trunk/tests/phpunit/tests/rest-api/rest-block-type-controller.php

    r54155 r54670  
    337337                $this->assertNull( $data['editor_style'] );
    338338                $this->assertNull( $data['style'] );
     339        }
     340
     341        /**
     342         * @ticket 56733
     343         */
     344        public function test_get_item_deprecated() {
     345                $block_type = 'fake/deprecated';
     346                $settings   = array(
     347                        'editor_script' => 'hello_world',
     348                        'script'        => 'gutenberg',
     349                        'view_script'   => 'foo_bar',
     350                        'editor_style'  => 'guten_tag',
     351                        'style'         => 'out_of_style',
     352                );
     353                register_block_type( $block_type, $settings );
     354                wp_set_current_user( self::$admin_id );
     355                $request  = new WP_REST_Request( 'GET', '/wp/v2/block-types/' . $block_type );
     356                $response = rest_get_server()->dispatch( $request );
     357                $data     = $response->get_data();
     358                $this->assertSameSets(
     359                        array( 'hello_world' ),
     360                        $data['editor_script_handles'],
     361                        "Endpoint doesn't return correct array for editor_script_handles."
     362                );
     363                $this->assertSameSets(
     364                        array( 'gutenberg' ),
     365                        $data['script_handles'],
     366                        "Endpoint doesn't return correct array for script_handles."
     367                );
     368                $this->assertSameSets(
     369                        array( 'foo_bar' ),
     370                        $data['view_script_handles'],
     371                        "Endpoint doesn't return correct array for view_script_handles."
     372                );
     373                $this->assertSameSets(
     374                        array( 'guten_tag' ),
     375                        $data['editor_style_handles'],
     376                        "Endpoint doesn't return correct array for editor_style_handles."
     377                );
     378                $this->assertSameSets(
     379                        array( 'out_of_style' ),
     380                        $data['style_handles'],
     381                        "Endpoint doesn't return correct array for style_handles."
     382                );
     383                // Deprecated properties.
     384                $this->assertSame(
     385                        'hello_world',
     386                        $data['editor_script'],
     387                        "Endpoint doesn't return correct string for editor_script."
     388                );
     389                $this->assertSame(
     390                        'gutenberg',
     391                        $data['script'],
     392                        "Endpoint doesn't return correct string for script."
     393                );
     394                $this->assertSame(
     395                        'foo_bar',
     396                        $data['view_script'],
     397                        "Endpoint doesn't return correct string for view_script."
     398                );
     399                $this->assertSame(
     400                        'guten_tag',
     401                        $data['editor_style'],
     402                        "Endpoint doesn't return correct string for editor_style."
     403                );
     404                $this->assertSame(
     405                        'out_of_style',
     406                        $data['style'],
     407                        "Endpoint doesn't return correct string for style."
     408                );
     409        }
     410
     411        /**
     412         * @ticket 56733
     413         */
     414        public function test_get_item_deprecated_with_arrays() {
     415                $block_type = 'fake/deprecated-with-arrays';
     416                $settings   = array(
     417                        'editor_script' => array( 'hello', 'world' ),
     418                        'script'        => array( 'gutenberg' ),
     419                        'view_script'   => array( 'foo', 'bar' ),
     420                        'editor_style'  => array( 'guten', 'tag' ),
     421                        'style'         => array( 'out', 'of', 'style' ),
     422                );
     423                register_block_type( $block_type, $settings );
     424                wp_set_current_user( self::$admin_id );
     425                $request  = new WP_REST_Request( 'GET', '/wp/v2/block-types/' . $block_type );
     426                $response = rest_get_server()->dispatch( $request );
     427                $data     = $response->get_data();
     428                $this->assertSameSets(
     429                        $settings['editor_script'],
     430                        $data['editor_script_handles'],
     431                        "Endpoint doesn't return correct array for editor_script_handles."
     432                );
     433                $this->assertSameSets(
     434                        $settings['script'],
     435                        $data['script_handles'],
     436                        "Endpoint doesn't return correct array for script_handles."
     437                );
     438                $this->assertSameSets(
     439                        $settings['view_script'],
     440                        $data['view_script_handles'],
     441                        "Endpoint doesn't return correct array for view_script_handles."
     442                );
     443                $this->assertSameSets(
     444                        $settings['editor_style'],
     445                        $data['editor_style_handles'],
     446                        "Endpoint doesn't return correct array for editor_style_handles."
     447                );
     448                $this->assertSameSets(
     449                        $settings['style'],
     450                        $data['style_handles'],
     451                        "Endpoint doesn't return correct array for style_handles."
     452                );
     453                // Deprecated properties.
     454                // Since the schema only allows strings or null (but no arrays), we return the first array item.
     455                // Deprecated properties.
     456                $this->assertSame(
     457                        'hello',
     458                        $data['editor_script'],
     459                        "Endpoint doesn't return first array element for editor_script."
     460                );
     461                $this->assertSame(
     462                        'gutenberg',
     463                        $data['script'],
     464                        "Endpoint doesn't return first array element for script."
     465                );
     466                $this->assertSame(
     467                        'foo',
     468                        $data['view_script'],
     469                        "Endpoint doesn't return first array element for view_script."
     470                );
     471                $this->assertSame(
     472                        'guten',
     473                        $data['editor_style'],
     474                        "Endpoint doesn't return first array element for editor_style."
     475                );
     476                $this->assertSame(
     477                        'out',
     478                        $data['style'],
     479                        "Endpoint doesn't return first array element for style."
     480                );
    339481        }
    340482
Note: See TracChangeset for help on using the changeset viewer.