Changeset 48171
- Timestamp:
- 06/25/2020 10:11:09 PM (4 years ago)
- Location:
- trunk
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/default-filters.php
r48121 r48171 471 471 add_action( 'delete_attachment', '_delete_attachment_theme_mod' ); 472 472 add_action( 'transition_post_status', '_wp_keep_alive_customize_changeset_dependent_auto_drafts', 20, 3 ); 473 add_action( 'setup_theme', 'create_initial_theme_features', 0 ); 473 474 474 475 // Calendar widget cache. -
trunk/src/wp-includes/rest-api.php
r48150 r48171 1780 1780 return $data; 1781 1781 } 1782 1783 /** 1784 * Sets the "additionalProperties" to false by default for all object definitions in the schema. 1785 * 1786 * @since 5.5.0 1787 * 1788 * @param array $schema The schema to modify. 1789 * @return array The modified schema. 1790 */ 1791 function rest_default_additional_properties_to_false( $schema ) { 1792 $type = (array) $schema['type']; 1793 1794 if ( in_array( 'object', $type, true ) ) { 1795 if ( isset( $schema['properties'] ) ) { 1796 foreach ( $schema['properties'] as $key => $child_schema ) { 1797 $schema['properties'][ $key ] = rest_default_additional_properties_to_false( $child_schema ); 1798 } 1799 } 1800 1801 if ( ! isset( $schema['additionalProperties'] ) ) { 1802 $schema['additionalProperties'] = false; 1803 } 1804 } 1805 1806 if ( in_array( 'array', $type, true ) ) { 1807 if ( isset( $schema['items'] ) ) { 1808 $schema['items'] = rest_default_additional_properties_to_false( $schema['items'] ); 1809 } 1810 } 1811 1812 return $schema; 1813 } -
trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-themes-controller.php
r47929 r48171 168 168 169 169 if ( rest_is_field_included( 'theme_supports', $fields ) ) { 170 $item_schemas = $this->get_item_schema(); 171 $theme_supports = $item_schemas['properties']['theme_supports']['properties']; 172 foreach ( $theme_supports as $name => $schema ) { 170 foreach ( get_registered_theme_features() as $feature => $config ) { 171 if ( ! is_array( $config['show_in_rest'] ) ) { 172 continue; 173 } 174 175 $name = $config['show_in_rest']['name']; 176 173 177 if ( ! rest_is_field_included( "theme_supports.{$name}", $fields ) ) { 174 178 continue; 175 179 } 176 180 177 if ( 'formats' === $name ) { 181 if ( ! current_theme_supports( $feature ) ) { 182 $data['theme_supports'][ $name ] = $config['show_in_rest']['schema']['default']; 178 183 continue; 179 184 } 180 185 181 if ( ! current_theme_supports( $name ) ) { 182 $data['theme_supports'][ $name ] = false; 186 $support = get_theme_support( $feature ); 187 188 if ( isset( $config['show_in_rest']['prepare_callback'] ) ) { 189 $prepare = $config['show_in_rest']['prepare_callback']; 190 } else { 191 $prepare = array( $this, 'prepare_theme_support' ); 192 } 193 194 $prepared = $prepare( $support, $config, $feature, $request ); 195 196 if ( is_wp_error( $prepared ) ) { 183 197 continue; 184 198 } 185 199 186 if ( 'boolean' === $schema['type'] ) { 187 $data['theme_supports'][ $name ] = true; 188 continue; 189 } 190 191 $support = get_theme_support( $name ); 192 193 if ( is_array( $support ) ) { 194 // None of the Core theme supports have variadic args. 195 $support = $support[0]; 196 197 // Core multi-type theme-support schema definitions always list boolean first. 198 if ( is_array( $schema['type'] ) && 'boolean' === $schema['type'][0] ) { 199 // Pass the non-boolean type through to the sanitizer, which cannot itself 200 // determine the intended type if the value is invalid (for example if an 201 // object includes non-safelisted properties). 202 $schema['type'] = $schema['type'][1]; 203 } 204 } 205 206 $data['theme_supports'][ $name ] = rest_sanitize_value_from_schema( $support, $schema ); 207 } 208 209 $formats = get_theme_support( 'post-formats' ); 210 $formats = is_array( $formats ) ? array_values( $formats[0] ) : array(); 211 $formats = array_merge( array( 'standard' ), $formats ); 212 213 $data['theme_supports']['formats'] = $formats; 200 $data['theme_supports'][ $name ] = $prepared; 201 } 214 202 } 215 203 … … 232 220 233 221 /** 222 * Prepares the theme support value for inclusion in the REST API response. 223 * 224 * @since 5.5.0 225 * 226 * @param mixed $support The raw value from {@see get_theme_support()} 227 * @param array $args The feature's registration args. 228 * @param string $feature The feature name. 229 * @param WP_REST_Request $request The request object. 230 * @return mixed The prepared support value. 231 */ 232 protected function prepare_theme_support( $support, $args, $feature, $request ) { 233 $schema = $args['show_in_rest']['schema']; 234 235 if ( 'boolean' === $schema['type'] ) { 236 return true; 237 } 238 239 if ( is_array( $support ) ) { 240 if ( ! $args['variadic'] ) { 241 $support = $support[0]; 242 } 243 244 // Multi-type theme-support schema definitions always list boolean first. 245 if ( is_array( $schema['type'] ) && 'boolean' === $schema['type'][0] ) { 246 // Pass the non-boolean type through to the sanitizer, which cannot itself 247 // determine the intended type if the value is invalid (for example if an 248 // object includes non-safelisted properties). See #50300. 249 $schema['type'] = $schema['type'][1]; 250 } 251 } 252 253 return rest_sanitize_value_from_schema( $support, $schema ); 254 } 255 256 /** 234 257 * Retrieves the theme's schema, conforming to JSON Schema. 235 258 * … … 363 386 'type' => 'object', 364 387 'readonly' => true, 365 'properties' => array( 366 'align-wide' => array( 367 'description' => __( 'Whether theme opts in to wide alignment CSS class.' ), 368 'type' => 'boolean', 369 ), 370 'automatic-feed-links' => array( 371 'description' => __( 'Whether posts and comments RSS feed links are added to head.' ), 372 'type' => 'boolean', 373 ), 374 'custom-header' => array( 375 'description' => __( 'Custom header if defined by the theme.' ), 376 'type' => array( 'boolean', 'object' ), 377 'properties' => array( 378 'default-image' => array( 379 'type' => 'string', 380 'format' => 'uri', 381 ), 382 'random-default' => array( 383 'type' => 'boolean', 384 ), 385 'width' => array( 386 'type' => 'integer', 387 ), 388 'height' => array( 389 'type' => 'integer', 390 ), 391 'flex-height' => array( 392 'type' => 'boolean', 393 ), 394 'flex-width' => array( 395 'type' => 'boolean', 396 ), 397 'default-text-color' => array( 398 'type' => 'string', 399 ), 400 'header-text' => array( 401 'type' => 'boolean', 402 ), 403 'uploads' => array( 404 'type' => 'boolean', 405 ), 406 'video' => array( 407 'type' => 'boolean', 408 ), 409 ), 410 'additionalProperties' => false, 411 ), 412 'custom-background' => array( 413 'description' => __( 'Custom background if defined by the theme.' ), 414 'type' => array( 'boolean', 'object' ), 415 'properties' => array( 416 'default-image' => array( 417 'type' => 'string', 418 'format' => 'uri', 419 ), 420 'default-preset' => array( 421 'type' => 'string', 422 'enum' => array( 423 'default', 424 'fill', 425 'fit', 426 'repeat', 427 'custom', 428 ), 429 ), 430 'default-position-x' => array( 431 'type' => 'string', 432 'enum' => array( 433 'left', 434 'center', 435 'right', 436 ), 437 ), 438 'default-position-y' => array( 439 'type' => 'string', 440 'enum' => array( 441 'left', 442 'center', 443 'right', 444 ), 445 ), 446 'default-size' => array( 447 'type' => 'string', 448 'enum' => array( 449 'auto', 450 'contain', 451 'cover', 452 ), 453 ), 454 'default-repeat' => array( 455 'type' => 'string', 456 'enum' => array( 457 'repeat-x', 458 'repeat-y', 459 'repeat', 460 'no-repeat', 461 ), 462 ), 463 'default-attachment' => array( 464 'type' => 'string', 465 'enum' => array( 466 'scroll', 467 'fixed', 468 ), 469 ), 470 'default-color' => array( 471 'type' => 'string', 472 ), 473 ), 474 'additionalProperties' => false, 475 ), 476 'custom-logo' => array( 477 'description' => __( 'Custom logo if defined by the theme.' ), 478 'type' => array( 'boolean', 'object' ), 479 'properties' => array( 480 'width' => array( 481 'type' => 'integer', 482 ), 483 'height' => array( 484 'type' => 'integer', 485 ), 486 'flex-width' => array( 487 'type' => 'boolean', 488 ), 489 'flex-height' => array( 490 'type' => 'boolean', 491 ), 492 'header-text' => array( 493 'type' => 'array', 494 'items' => array( 495 'type' => 'string', 496 ), 497 ), 498 ), 499 'additionalProperties' => false, 500 ), 501 'customize-selective-refresh-widgets' => array( 502 'description' => __( 'Whether the theme enables Selective Refresh for Widgets being managed with the Customizer.' ), 503 'type' => 'boolean', 504 ), 505 'dark-editor-style' => array( 506 'description' => __( 'Whether theme opts in to the dark editor style UI.' ), 507 'type' => 'boolean', 508 ), 509 'disable-custom-colors' => array( 510 'description' => __( 'Whether the theme disables custom colors.' ), 511 'type' => 'boolean', 512 ), 513 'disable-custom-font-sizes' => array( 514 'description' => __( 'Whether the theme disables custom font sizes.' ), 515 'type' => 'boolean', 516 ), 517 'disable-custom-gradients' => array( 518 'description' => __( 'Whether the theme disables custom gradients.' ), 519 'type' => 'boolean', 520 ), 521 'editor-color-palette' => array( 522 'description' => __( 'Custom color palette if defined by the theme.' ), 523 'type' => array( 'boolean', 'array' ), 524 'items' => array( 525 'type' => 'object', 526 'properties' => array( 527 'name' => array( 528 'type' => 'string', 529 ), 530 'slug' => array( 531 'type' => 'string', 532 ), 533 'color' => array( 534 'type' => 'string', 535 ), 536 ), 537 'additionalProperties' => false, 538 ), 539 ), 540 'editor-font-sizes' => array( 541 'description' => __( 'Custom font sizes if defined by the theme.' ), 542 'type' => array( 'boolean', 'array' ), 543 'items' => array( 544 'type' => 'object', 545 'properties' => array( 546 'name' => array( 547 'type' => 'string', 548 ), 549 'size' => array( 550 'type' => 'number', 551 ), 552 'slug' => array( 553 'type' => 'string', 554 ), 555 ), 556 'additionalProperties' => false, 557 ), 558 ), 559 'editor-gradient-presets' => array( 560 'description' => __( 'Custom gradient presets if defined by the theme.' ), 561 'type' => array( 'boolean', 'array' ), 562 'items' => array( 563 'type' => 'object', 564 'properties' => array( 565 'name' => array( 566 'type' => 'string', 567 ), 568 'gradient' => array( 569 'type' => 'string', 570 ), 571 'slug' => array( 572 'type' => 'string', 573 ), 574 ), 575 'additionalProperties' => false, 576 ), 577 ), 578 'editor-styles' => array( 579 'description' => __( 'Whether theme opts in to the editor styles CSS wrapper.' ), 580 'type' => 'boolean', 581 ), 582 'formats' => array( 583 'description' => __( 'Post formats supported.' ), 584 'type' => 'array', 585 'items' => array( 586 'type' => 'string', 587 'enum' => get_post_format_slugs(), 588 ), 589 ), 590 'html5' => array( 591 'description' => __( 'Allows use of html5 markup for search forms, comment forms, comment lists, gallery, and caption.' ), 592 'type' => array( 'boolean', 'array' ), 593 'items' => array( 594 'type' => 'string', 595 'enum' => array( 596 'search-form', 597 'comment-form', 598 'comment-list', 599 'gallery', 600 'caption', 601 'script', 602 'style', 603 ), 604 ), 605 ), 606 'post-thumbnails' => array( 607 'description' => __( 'Whether the theme supports post thumbnails.' ), 608 'type' => array( 'boolean', 'array' ), 609 'items' => array( 610 'type' => 'string', 611 ), 612 ), 613 'responsive-embeds' => array( 614 'description' => __( 'Whether the theme supports responsive embedded content.' ), 615 'type' => 'boolean', 616 ), 617 'title-tag' => array( 618 'description' => __( 'Whether the theme can manage the document title tag.' ), 619 'type' => 'boolean', 620 ), 621 'wp-block-styles' => array( 622 'description' => __( 'Whether theme opts in to default WordPress block styles for viewing.' ), 623 'type' => 'boolean', 624 ), 625 ), 388 'properties' => array(), 626 389 ), 627 390 'theme_uri' => array( … … 649 412 ), 650 413 ); 414 415 foreach ( get_registered_theme_features() as $feature => $config ) { 416 if ( ! is_array( $config['show_in_rest'] ) ) { 417 continue; 418 } 419 420 $name = $config['show_in_rest']['name']; 421 422 $schema['properties']['theme_supports']['properties'][ $name ] = $config['show_in_rest']['schema']; 423 } 651 424 652 425 $this->schema = $schema; -
trunk/src/wp-includes/theme.php
r48169 r48171 2995 2995 2996 2996 /** 2997 * Registers a theme feature for use in {@see add_theme_support}. 2998 * 2999 * This does not indicate that the current theme supports the feature, it only describes the feature's supported options. 3000 * 3001 * @since 5.5.0 3002 * 3003 * @global $_wp_registered_theme_features 3004 * 3005 * @param string $feature The name uniquely identifying the feature. 3006 * @param array $args { 3007 * Data used to describe the theme 3008 * 3009 * @type string $type The type of data associated with this feature. Defaults to 'boolean'. 3010 * Valid values are 'string', 'boolean', 'integer', 'number', 'array', and 'object'. 3011 * @type boolean $variadic Does this feature utilize the variadic support of {@see add_theme_support()}, 3012 * or are all arguments specified as the second parameter. Must be used with the "array" type. 3013 * @type string $description A short description of the feature. Included in the Themes REST API schema. Intended for developers. 3014 * @type bool|array $show_in_rest { 3015 * Whether this feature should be included in the Themes REST API endpoint. Defaults to not being included. 3016 * When registering an 'array' or 'object' type, this argument must be an array with the 'schema' key. 3017 * 3018 * @type array $schema Specifies the JSON Schema definition describing the feature. If any objects in the schema 3019 * do not include the 'additionalProperties' keyword, it is set to false. 3020 * @type string $name An alternate name to be use as the property name in the REST API. 3021 * @type callable $prepare_callback A function used to format the theme support in the REST API. Receives the raw theme support value. 3022 * } 3023 * } 3024 * @return true|WP_Error True if the theme feature was successfully registered, a WP_Error object if not. 3025 */ 3026 function register_theme_feature( $feature, $args = array() ) { 3027 global $_wp_registered_theme_features; 3028 3029 if ( ! is_array( $_wp_registered_theme_features ) ) { 3030 $_wp_registered_theme_features = array(); 3031 } 3032 3033 $defaults = array( 3034 'type' => 'boolean', 3035 'variadic' => false, 3036 'description' => '', 3037 'show_in_rest' => false, 3038 ); 3039 3040 $args = wp_parse_args( $args, $defaults ); 3041 3042 if ( true === $args['show_in_rest'] ) { 3043 $args['show_in_rest'] = array(); 3044 } 3045 3046 if ( is_array( $args['show_in_rest'] ) ) { 3047 $args['show_in_rest'] = wp_parse_args( 3048 $args['show_in_rest'], 3049 array( 3050 'schema' => array(), 3051 'name' => $feature, 3052 'prepare_callback' => null, 3053 ) 3054 ); 3055 } 3056 3057 if ( ! in_array( $args['type'], array( 'string', 'boolean', 'integer', 'number', 'array', 'object' ), true ) ) { 3058 return new WP_Error( 'invalid_type', __( 'The feature "type" is not valid JSON Schema type.' ) ); 3059 } 3060 3061 if ( true === $args['variadic'] && 'array' !== $args['type'] ) { 3062 return new WP_Error( 'variadic_must_be_array', __( 'When registering a "variadic" theme feature, the "type" must be an "array".' ) ); 3063 } 3064 3065 if ( false !== $args['show_in_rest'] && in_array( $args['type'], array( 'array', 'object' ), true ) ) { 3066 if ( ! is_array( $args['show_in_rest'] ) || empty( $args['show_in_rest']['schema'] ) ) { 3067 return new WP_Error( 'missing_schema', __( 'When registering an "array" or "object" feature to show in the REST API, the feature\'s schema must also be defined.' ) ); 3068 } 3069 3070 if ( 'array' === $args['type'] && ! isset( $args['show_in_rest']['schema']['items'] ) ) { 3071 return new WP_Error( 'missing_schema_items', __( 'When registering an "array" feature, the feature\'s schema must include the "items" keyword.' ) ); 3072 } 3073 3074 if ( 'object' === $args['type'] && ! isset( $args['show_in_rest']['schema']['properties'] ) ) { 3075 return new WP_Error( 'missing_schema_properties', __( 'When registering an "object" feature, the feature\'s schema must include the "properties" keyword.' ) ); 3076 } 3077 } 3078 3079 if ( is_array( $args['show_in_rest'] ) ) { 3080 if ( isset( $args['show_in_rest']['prepare_callback'] ) && ! is_callable( $args['show_in_rest']['prepare_callback'] ) ) { 3081 return new WP_Error( 'invalid_rest_prepare_callback', __( 'The prepare_callback must be a callable function.' ) ); 3082 } 3083 3084 $args['show_in_rest']['schema'] = wp_parse_args( 3085 $args['show_in_rest']['schema'], 3086 array( 3087 'description' => $args['description'], 3088 'type' => $args['type'], 3089 'default' => false, 3090 ) 3091 ); 3092 3093 if ( is_bool( $args['show_in_rest']['schema']['default'] ) && ! in_array( 'boolean', (array) $args['show_in_rest']['schema']['type'], true ) ) { 3094 // Automatically include the "boolean" type when the default value is a boolean. 3095 $args['show_in_rest']['schema']['type'] = (array) $args['show_in_rest']['schema']['type']; 3096 array_unshift( $args['show_in_rest']['schema']['type'], 'boolean' ); 3097 } 3098 3099 $args['show_in_rest']['schema'] = rest_default_additional_properties_to_false( $args['show_in_rest']['schema'] ); 3100 } 3101 3102 $_wp_registered_theme_features[ $feature ] = $args; 3103 3104 return true; 3105 } 3106 3107 /** 3108 * Gets the list of registered theme features. 3109 * 3110 * @since 5.5.0 3111 * 3112 * @global $_wp_registered_theme_features 3113 * 3114 * @return array[] List of theme features, keyed by their name. 3115 */ 3116 function get_registered_theme_features() { 3117 global $_wp_registered_theme_features; 3118 3119 if ( ! is_array( $_wp_registered_theme_features ) ) { 3120 return array(); 3121 } 3122 3123 return $_wp_registered_theme_features; 3124 } 3125 3126 /** 3127 * Gets the registration config for a theme feature. 3128 * 3129 * @since 5.5.0 3130 * 3131 * @global $_wp_registered_theme_features 3132 * 3133 * @param string $feature The feature name. 3134 * @return array|null The registration args, or null if the feature was not registered. 3135 */ 3136 function get_registered_theme_feature( $feature ) { 3137 global $_wp_registered_theme_features; 3138 3139 if ( ! is_array( $_wp_registered_theme_features ) ) { 3140 return null; 3141 } 3142 3143 return isset( $_wp_registered_theme_features[ $feature ] ) ? $_wp_registered_theme_features[ $feature ] : null; 3144 } 3145 3146 /** 2997 3147 * Checks an attachment being deleted to see if it's a header or background image. 2998 3148 * … … 3463 3613 } 3464 3614 } 3615 3616 /** 3617 * Creates the initial theme features when the 'setup_theme' action is fired. 3618 * 3619 * See {@see 'setup_theme'}. 3620 * 3621 * @since 5.5.0 3622 */ 3623 function create_initial_theme_features() { 3624 register_theme_feature( 3625 'align-wide', 3626 array( 3627 'description' => __( 'Whether theme opts in to wide alignment CSS class.' ), 3628 'show_in_rest' => true, 3629 ) 3630 ); 3631 register_theme_feature( 3632 'automatic-feed-links', 3633 array( 3634 'description' => __( 'Whether posts and comments RSS feed links are added to head.' ), 3635 'show_in_rest' => true, 3636 ) 3637 ); 3638 register_theme_feature( 3639 'custom-background', 3640 array( 3641 'description' => __( 'Custom background if defined by the theme.' ), 3642 'type' => 'object', 3643 'show_in_rest' => array( 3644 'schema' => array( 3645 'properties' => array( 3646 'default-image' => array( 3647 'type' => 'string', 3648 'format' => 'uri', 3649 ), 3650 'default-preset' => array( 3651 'type' => 'string', 3652 'enum' => array( 3653 'default', 3654 'fill', 3655 'fit', 3656 'repeat', 3657 'custom', 3658 ), 3659 ), 3660 'default-position-x' => array( 3661 'type' => 'string', 3662 'enum' => array( 3663 'left', 3664 'center', 3665 'right', 3666 ), 3667 ), 3668 'default-position-y' => array( 3669 'type' => 'string', 3670 'enum' => array( 3671 'left', 3672 'center', 3673 'right', 3674 ), 3675 ), 3676 'default-size' => array( 3677 'type' => 'string', 3678 'enum' => array( 3679 'auto', 3680 'contain', 3681 'cover', 3682 ), 3683 ), 3684 'default-repeat' => array( 3685 'type' => 'string', 3686 'enum' => array( 3687 'repeat-x', 3688 'repeat-y', 3689 'repeat', 3690 'no-repeat', 3691 ), 3692 ), 3693 'default-attachment' => array( 3694 'type' => 'string', 3695 'enum' => array( 3696 'scroll', 3697 'fixed', 3698 ), 3699 ), 3700 'default-color' => array( 3701 'type' => 'string', 3702 ), 3703 ), 3704 ), 3705 ), 3706 ) 3707 ); 3708 register_theme_feature( 3709 'custom-header', 3710 array( 3711 'description' => __( 'Custom header if defined by the theme.' ), 3712 'type' => 'object', 3713 'show_in_rest' => array( 3714 'schema' => array( 3715 'properties' => array( 3716 'default-image' => array( 3717 'type' => 'string', 3718 'format' => 'uri', 3719 ), 3720 'random-default' => array( 3721 'type' => 'boolean', 3722 ), 3723 'width' => array( 3724 'type' => 'integer', 3725 ), 3726 'height' => array( 3727 'type' => 'integer', 3728 ), 3729 'flex-height' => array( 3730 'type' => 'boolean', 3731 ), 3732 'flex-width' => array( 3733 'type' => 'boolean', 3734 ), 3735 'default-text-color' => array( 3736 'type' => 'string', 3737 ), 3738 'header-text' => array( 3739 'type' => 'boolean', 3740 ), 3741 'uploads' => array( 3742 'type' => 'boolean', 3743 ), 3744 'video' => array( 3745 'type' => 'boolean', 3746 ), 3747 ), 3748 ), 3749 ), 3750 ) 3751 ); 3752 register_theme_feature( 3753 'custom-logo', 3754 array( 3755 'type' => 'object', 3756 'description' => __( 'Custom logo if defined by the theme.' ), 3757 'show_in_rest' => array( 3758 'schema' => array( 3759 'properties' => array( 3760 'width' => array( 3761 'type' => 'integer', 3762 ), 3763 'height' => array( 3764 'type' => 'integer', 3765 ), 3766 'flex-width' => array( 3767 'type' => 'boolean', 3768 ), 3769 'flex-height' => array( 3770 'type' => 'boolean', 3771 ), 3772 'header-text' => array( 3773 'type' => 'array', 3774 'items' => array( 3775 'type' => 'string', 3776 ), 3777 ), 3778 ), 3779 ), 3780 ), 3781 ) 3782 ); 3783 register_theme_feature( 3784 'customize-selective-refresh-widgets', 3785 array( 3786 'description' => __( 'Whether the theme enables Selective Refresh for Widgets being managed with the Customizer.' ), 3787 'show_in_rest' => true, 3788 ) 3789 ); 3790 register_theme_feature( 3791 'dark-editor-style', 3792 array( 3793 'description' => __( 'Whether theme opts in to the dark editor style UI.' ), 3794 'show_in_rest' => true, 3795 ) 3796 ); 3797 register_theme_feature( 3798 'disable-custom-colors', 3799 array( 3800 'description' => __( 'Whether the theme disables custom colors.' ), 3801 'show_in_rest' => true, 3802 ) 3803 ); 3804 register_theme_feature( 3805 'disable-custom-font-sizes', 3806 array( 3807 'description' => __( 'Whether the theme disables custom font sizes.' ), 3808 'show_in_rest' => true, 3809 ) 3810 ); 3811 register_theme_feature( 3812 'disable-custom-gradients', 3813 array( 3814 'description' => __( 'Whether the theme disables custom gradients.' ), 3815 'show_in_rest' => true, 3816 ) 3817 ); 3818 register_theme_feature( 3819 'editor-color-palette', 3820 array( 3821 'type' => 'array', 3822 'description' => __( 'Custom color palette if defined by the theme.' ), 3823 'show_in_rest' => array( 3824 'schema' => array( 3825 'items' => array( 3826 'type' => 'object', 3827 'properties' => array( 3828 'name' => array( 3829 'type' => 'string', 3830 ), 3831 'slug' => array( 3832 'type' => 'string', 3833 ), 3834 'color' => array( 3835 'type' => 'string', 3836 ), 3837 ), 3838 ), 3839 ), 3840 ), 3841 ) 3842 ); 3843 register_theme_feature( 3844 'editor-font-sizes', 3845 array( 3846 'type' => 'array', 3847 'description' => __( 'Custom font sizes if defined by the theme.' ), 3848 'show_in_rest' => array( 3849 'schema' => array( 3850 'items' => array( 3851 'type' => 'object', 3852 'properties' => array( 3853 'name' => array( 3854 'type' => 'string', 3855 ), 3856 'size' => array( 3857 'type' => 'number', 3858 ), 3859 'slug' => array( 3860 'type' => 'string', 3861 ), 3862 ), 3863 ), 3864 ), 3865 ), 3866 ) 3867 ); 3868 register_theme_feature( 3869 'editor-gradient-presets', 3870 array( 3871 'type' => 'array', 3872 'description' => __( 'Custom gradient presets if defined by the theme.' ), 3873 'show_in_rest' => array( 3874 'schema' => array( 3875 'items' => array( 3876 'type' => 'object', 3877 'properties' => array( 3878 'name' => array( 3879 'type' => 'string', 3880 ), 3881 'gradient' => array( 3882 'type' => 'string', 3883 ), 3884 'slug' => array( 3885 'type' => 'string', 3886 ), 3887 ), 3888 ), 3889 ), 3890 ), 3891 ) 3892 ); 3893 register_theme_feature( 3894 'editor-styles', 3895 array( 3896 'description' => __( 'Whether theme opts in to the editor styles CSS wrapper.' ), 3897 'show_in_rest' => true, 3898 ) 3899 ); 3900 register_theme_feature( 3901 'html5', 3902 array( 3903 'type' => 'array', 3904 'description' => __( 'Allows use of HTML5 markup for search forms, comment forms, comment lists, gallery, and caption.' ), 3905 'show_in_rest' => array( 3906 'schema' => array( 3907 'items' => array( 3908 'type' => 'string', 3909 'enum' => array( 3910 'search-form', 3911 'comment-form', 3912 'comment-list', 3913 'gallery', 3914 'caption', 3915 'script', 3916 'style', 3917 ), 3918 ), 3919 ), 3920 ), 3921 ) 3922 ); 3923 register_theme_feature( 3924 'post-formats', 3925 array( 3926 'type' => 'array', 3927 'description' => __( 'Post formats supported.' ), 3928 'show_in_rest' => array( 3929 'name' => 'formats', 3930 'schema' => array( 3931 'items' => array( 3932 'type' => 'string', 3933 'enum' => get_post_format_slugs(), 3934 ), 3935 'default' => array( 'standard' ), 3936 ), 3937 'prepare_callback' => static function ( $formats ) { 3938 $formats = is_array( $formats ) ? array_values( $formats[0] ) : array(); 3939 $formats = array_merge( array( 'standard' ), $formats ); 3940 3941 return $formats; 3942 }, 3943 ), 3944 ) 3945 ); 3946 register_theme_feature( 3947 'post-thumbnails', 3948 array( 3949 'type' => 'array', 3950 'description' => __( 'The post types that support thumbnails or true if all post types are supported.' ), 3951 'show_in_rest' => array( 3952 'type' => array( 'boolean', 'array' ), 3953 'schema' => array( 3954 'items' => array( 3955 'type' => 'string', 3956 ), 3957 ), 3958 ), 3959 ) 3960 ); 3961 register_theme_feature( 3962 'responsive-embeds', 3963 array( 3964 'description' => __( 'Whether the theme supports responsive embedded content.' ), 3965 'show_in_rest' => true, 3966 ) 3967 ); 3968 register_theme_feature( 3969 'title-tag', 3970 array( 3971 'description' => __( 'Whether the theme can manage the document title tag.' ), 3972 'show_in_rest' => true, 3973 ) 3974 ); 3975 register_theme_feature( 3976 'wp-block-styles', 3977 array( 3978 'description' => __( 'Whether theme opts in to default WordPress block styles for viewing.' ), 3979 'show_in_rest' => true, 3980 ) 3981 ); 3982 } -
trunk/tests/phpunit/tests/rest-api/rest-themes-controller.php
r47921 r48171 261 261 262 262 $theme_supports = $properties['theme_supports']['properties']; 263 $this->assertEquals( 20, count( $theme_supports ) );264 263 $this->assertArrayHasKey( 'align-wide', $theme_supports ); 265 264 $this->assertArrayHasKey( 'automatic-feed-links', $theme_supports ); … … 282 281 $this->assertArrayHasKey( 'title-tag', $theme_supports ); 283 282 $this->assertArrayHasKey( 'wp-block-styles', $theme_supports ); 283 $this->assertCount( 20, $theme_supports ); 284 284 } 285 285 … … 999 999 1000 1000 /** 1001 * @ticket 49406 1002 */ 1003 public function test_variadic_theme_support() { 1004 register_theme_feature( 1005 'test-feature', 1006 array( 1007 'type' => 'array', 1008 'variadic' => true, 1009 'show_in_rest' => array( 1010 'schema' => array( 1011 'items' => array( 1012 'type' => 'string', 1013 ), 1014 ), 1015 ), 1016 ) 1017 ); 1018 add_theme_support( 'test-feature', 'a', 'b', 'c' ); 1019 1020 $response = self::perform_active_theme_request(); 1021 $result = $response->get_data(); 1022 $this->assertTrue( isset( $result[0]['theme_supports'] ) ); 1023 $this->assertEquals( array( 'a', 'b', 'c' ), $result[0]['theme_supports']['test-feature'] ); 1024 } 1025 1026 /** 1001 1027 * It should be possible to register custom fields to the endpoint. 1002 1028 * -
trunk/tests/phpunit/tests/theme.php
r47122 r48171 416 416 $this->assertEquals( 'private', get_post_status( $nav_created_post_ids[1] ) ); 417 417 } 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 } 418 702 }
Note: See TracChangeset
for help on using the changeset viewer.