Make WordPress Core


Ignore:
Timestamp:
06/25/2020 10:11:09 PM (4 years ago)
Author:
TimothyBlynJacobs
Message:

Themes: Introduce register_theme_feature API.

Currently themes can declare support for a given feature by using add_theme_support(). This commit adds a register_theme_feature() API that allows plugins and WordPress Core to declare a list of available features that themes can support.

The REST API uses this to expose a theme's supported features if the feature has been registered with "show_in_rest" set to true.

Props kadamwhite, spacedmonkey, williampatton, desrosj, TimothyBlynJacobs.
Fixes #49406.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tests/phpunit/tests/theme.php

    r47122 r48171  
    416416        $this->assertEquals( 'private', get_post_status( $nav_created_post_ids[1] ) );
    417417    }
     418
     419    /**
     420     * @ticket 49406
     421     */
     422    public function test_register_theme_support_defaults() {
     423        $registered = register_theme_feature( 'test-feature' );
     424        $this->assertTrue( $registered );
     425
     426        $expected = array(
     427            'type'         => 'boolean',
     428            'variadic'     => false,
     429            'description'  => '',
     430            'show_in_rest' => false,
     431        );
     432        $this->assertEqualSets( $expected, get_registered_theme_feature( 'test-feature' ) );
     433    }
     434
     435    /**
     436     * @ticket 49406
     437     */
     438    public function test_register_theme_support_explicit() {
     439        $args = array(
     440            'type'         => 'array',
     441            'variadic'     => true,
     442            'description'  => 'My Feature',
     443            'show_in_rest' => array(
     444                'schema' => array(
     445                    'items' => array(
     446                        'type' => 'string',
     447                    ),
     448                ),
     449            ),
     450        );
     451
     452        register_theme_feature( 'test-feature', $args );
     453        $actual = get_registered_theme_feature( 'test-feature' );
     454
     455        $this->assertEquals( 'array', $actual['type'] );
     456        $this->assertTrue( $actual['variadic'] );
     457        $this->assertEquals( 'My Feature', $actual['description'] );
     458        $this->assertEquals( array( 'type' => 'string' ), $actual['show_in_rest']['schema']['items'] );
     459    }
     460
     461    /**
     462     * @ticket 49406
     463     */
     464    public function test_register_theme_support_upgrades_show_in_rest() {
     465        register_theme_feature( 'test-feature', array( 'show_in_rest' => true ) );
     466
     467        $expected = array(
     468            'schema'           => array(
     469                'type'        => 'boolean',
     470                'description' => '',
     471                'default'     => false,
     472            ),
     473            'name'             => 'test-feature',
     474            'prepare_callback' => null,
     475        );
     476        $actual   = get_registered_theme_feature( 'test-feature' )['show_in_rest'];
     477
     478        $this->assertEqualSets( $expected, $actual );
     479    }
     480
     481    /**
     482     * @ticket 49406
     483     */
     484    public function test_register_theme_support_fills_schema() {
     485        register_theme_feature(
     486            'test-feature',
     487            array(
     488                'type'         => 'array',
     489                'description'  => 'Cool Feature',
     490                'show_in_rest' => array(
     491                    'schema' => array(
     492                        'items'    => array(
     493                            'type' => 'string',
     494                        ),
     495                        'minItems' => 1,
     496                    ),
     497                ),
     498            )
     499        );
     500
     501        $expected = array(
     502            'description' => 'Cool Feature',
     503            'type'        => array( 'boolean', 'array' ),
     504            'items'       => array(
     505                'type' => 'string',
     506            ),
     507            'minItems'    => 1,
     508            'default'     => false,
     509        );
     510        $actual   = get_registered_theme_feature( 'test-feature' )['show_in_rest']['schema'];
     511
     512        $this->assertEqualSets( $expected, $actual );
     513    }
     514
     515    /**
     516     * @ticket 49406
     517     */
     518    public function test_register_theme_support_does_not_add_boolean_type_if_non_bool_default() {
     519        register_theme_feature(
     520            'test-feature',
     521            array(
     522                'type'         => 'array',
     523                'show_in_rest' => array(
     524                    'schema' => array(
     525                        'items'   => array(
     526                            'type' => 'string',
     527                        ),
     528                        'default' => array( 'standard' ),
     529                    ),
     530                ),
     531            )
     532        );
     533
     534        $actual = get_registered_theme_feature( 'test-feature' )['show_in_rest']['schema']['type'];
     535        $this->assertEquals( 'array', $actual );
     536    }
     537
     538    /**
     539     * @ticket 49406
     540     */
     541    public function test_register_theme_support_defaults_additional_properties_to_false() {
     542        register_theme_feature(
     543            'test-feature',
     544            array(
     545                'type'         => 'object',
     546                'description'  => 'Cool Feature',
     547                'show_in_rest' => array(
     548                    'schema' => array(
     549                        'properties' => array(
     550                            'a' => array(
     551                                'type' => 'string',
     552                            ),
     553                        ),
     554                    ),
     555                ),
     556            )
     557        );
     558
     559        $actual = get_registered_theme_feature( 'test-feature' )['show_in_rest']['schema'];
     560
     561        $this->assertArrayHasKey( 'additionalProperties', $actual );
     562        $this->assertFalse( $actual['additionalProperties'] );
     563    }
     564
     565    /**
     566     * @ticket 49406
     567     */
     568    public function test_register_theme_support_with_additional_properties() {
     569        register_theme_feature(
     570            'test-feature',
     571            array(
     572                'type'         => 'object',
     573                'description'  => 'Cool Feature',
     574                'show_in_rest' => array(
     575                    'schema' => array(
     576                        'properties'           => array(),
     577                        'additionalProperties' => array(
     578                            'type' => 'string',
     579                        ),
     580                    ),
     581                ),
     582            )
     583        );
     584
     585        $expected = array(
     586            'type' => 'string',
     587        );
     588        $actual   = get_registered_theme_feature( 'test-feature' )['show_in_rest']['schema']['additionalProperties'];
     589
     590        $this->assertEqualSets( $expected, $actual );
     591    }
     592
     593    /**
     594     * @ticket 49406
     595     */
     596    public function test_register_theme_support_defaults_additional_properties_to_false_in_array() {
     597        register_theme_feature(
     598            'test-feature',
     599            array(
     600                'type'         => 'array',
     601                'description'  => 'Cool Feature',
     602                'show_in_rest' => array(
     603                    'schema' => array(
     604                        'items' => array(
     605                            'type'       => 'object',
     606                            'properties' => array(
     607                                'a' => array(
     608                                    'type' => 'string',
     609                                ),
     610                            ),
     611                        ),
     612                    ),
     613                ),
     614            )
     615        );
     616
     617        $actual = get_registered_theme_feature( 'test-feature' )['show_in_rest']['schema']['items'];
     618
     619        $this->assertArrayHasKey( 'additionalProperties', $actual );
     620        $this->assertFalse( $actual['additionalProperties'] );
     621    }
     622
     623    /**
     624     * @ticket       49406
     625     * @dataProvider _dp_register_theme_support_validation
     626     * @param string $error_code The error code expected.
     627     * @param array  $args       The args to register.
     628     */
     629    public function test_register_theme_support_validation( $error_code, $args ) {
     630        $registered = register_theme_feature( 'test-feature', $args );
     631
     632        $this->assertWPError( $registered );
     633        $this->assertEquals( $error_code, $registered->get_error_code() );
     634    }
     635
     636    public function _dp_register_theme_support_validation() {
     637        return array(
     638            array(
     639                'invalid_type',
     640                array(
     641                    'type' => 'float',
     642                ),
     643            ),
     644            array(
     645                'invalid_type',
     646                array(
     647                    'type' => array( 'string' ),
     648                ),
     649            ),
     650            array(
     651                'variadic_must_be_array',
     652                array(
     653                    'variadic' => true,
     654                ),
     655            ),
     656            array(
     657                'missing_schema',
     658                array(
     659                    'type'         => 'object',
     660                    'show_in_rest' => true,
     661                ),
     662            ),
     663            array(
     664                'missing_schema',
     665                array(
     666                    'type'         => 'array',
     667                    'show_in_rest' => true,
     668                ),
     669            ),
     670            array(
     671                'missing_schema_items',
     672                array(
     673                    'type'         => 'array',
     674                    'show_in_rest' => array(
     675                        'schema' => array(
     676                            'type' => 'array',
     677                        ),
     678                    ),
     679                ),
     680            ),
     681            array(
     682                'missing_schema_properties',
     683                array(
     684                    'type'         => 'object',
     685                    'show_in_rest' => array(
     686                        'schema' => array(
     687                            'type' => 'object',
     688                        ),
     689                    ),
     690                ),
     691            ),
     692            array(
     693                'invalid_rest_prepare_callback',
     694                array(
     695                    'show_in_rest' => array(
     696                        'prepare_callback' => 'this is not a valid function',
     697                    ),
     698                ),
     699            ),
     700        );
     701    }
    418702}
Note: See TracChangeset for help on using the changeset viewer.