Make WordPress Core

Changeset 55231


Ignore:
Timestamp:
02/06/2023 03:31:50 PM (14 months ago)
Author:
jorgefilipecosta
Message:

Block editor: Update WP_Theme_JSON_Resolver and improve its performance.

This commit includes the latest updates WP_Theme_JSON_Resolver class made in the block editor. Some of these updates improve the performance of the class.

Props Mamaduka, hellofromTonya, flixos90, jorgefilipecosta, oandregal, spacedmonkey, audrasjb, costdev, scruffian.
Closes #57545.

Location:
trunk
Files:
3 added
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/class-wp-theme-json-resolver.php

    r55146 r55231  
    428428        $stylesheet       = $theme->get_stylesheet();
    429429        $args             = array(
    430             'posts_per_page'      => 1,
    431             'orderby'             => 'date',
    432             'order'               => 'desc',
    433             'post_type'           => $post_type_filter,
    434             'post_status'         => $post_status_filter,
    435             'ignore_sticky_posts' => true,
    436             'no_found_rows'       => true,
    437             'tax_query'           => array(
     430            'posts_per_page'         => 1,
     431            'orderby'                => 'date',
     432            'order'                  => 'desc',
     433            'post_type'              => $post_type_filter,
     434            'post_status'            => $post_status_filter,
     435            'ignore_sticky_posts'    => true,
     436            'no_found_rows'          => true,
     437            'update_post_meta_cache' => false,
     438            'update_post_term_cache' => false,
     439            'tax_query'              => array(
    438440                array(
    439441                    'taxonomy' => 'wp_theme',
     
    447449        $recent_posts       = $global_style_query->query( $args );
    448450        if ( count( $recent_posts ) === 1 ) {
    449             $user_cpt = get_post( $recent_posts[0], ARRAY_A );
     451            $user_cpt = get_object_vars( $recent_posts[0] );
    450452        } elseif ( $create_post ) {
    451453            $cpt_post_id = wp_insert_post(
     
    463465            );
    464466            if ( ! is_wp_error( $cpt_post_id ) ) {
    465                 $user_cpt = get_post( $cpt_post_id, ARRAY_A );
     467                $user_cpt = get_object_vars( get_post( $cpt_post_id ) );
    466468            }
    467469        }
     
    526528     * Returns the data merged from multiple origins.
    527529     *
    528      * There are three sources of data (origins) for a site:
    529      * default, theme, and custom. The custom's has higher priority
    530      * than the theme's, and the theme's higher than default's.
     530     * There are four sources of data (origins) for a site:
     531     *
     532     * - default => WordPress
     533     * - blocks  => each one of the blocks provides data for itself
     534     * - theme   => the active theme
     535     * - custom  => data provided by the user
     536     *
     537     * The custom's has higher priority than the theme's, the theme's higher than blocks',
     538     * and block's higher than default's.
    531539     *
    532540     * Unlike the getters
     
    536544     * this method returns data after it has been merged with the previous origins.
    537545     * This means that if the same piece of data is declared in different origins
    538      * (user, theme, and core), the last origin overrides the previous.
     546     * (default, blocks, theme, custom), the last origin overrides the previous.
    539547     *
    540548     * For example, if the user has set a background color
     
    546554     *              added the `$origin` parameter.
    547555     * @since 6.1.0 Added block data and generation of spacingSizes array.
    548      *
    549      * @param string $origin Optional. To what level should we merge data.
    550      *                       Valid values are 'theme' or 'custom'. Default 'custom'.
     556     * @since 6.2.0 Changed ' $origin' parameter values to 'default', 'blocks', 'theme' or 'custom'.
     557     *
     558     * @param string $origin Optional. To what level should we merge data: 'default', 'blocks', 'theme' or 'custom'.
     559     *                       'custom' is used as default value as well as fallback value if the origin is unknown.
    551560     * @return WP_Theme_JSON
    552561     */
     
    557566
    558567        $result = static::get_core_data();
     568        if ( 'default' === $origin ) {
     569            $result->set_spacing_sizes();
     570            return $result;
     571        }
     572
    559573        $result->merge( static::get_block_data() );
     574        if ( 'blocks' === $origin ) {
     575            return $result;
     576        }
     577
    560578        $result->merge( static::get_theme_data() );
    561 
    562         if ( 'custom' === $origin ) {
    563             $result->merge( static::get_user_data() );
    564         }
    565 
    566         // Generate the default spacingSizes array based on the merged spacingScale settings.
     579        if ( 'theme' === $origin ) {
     580            $result->set_spacing_sizes();
     581            return $result;
     582        }
     583
     584        $result->merge( static::get_user_data() );
    567585        $result->set_spacing_sizes();
    568586
     
    651669
    652670    /**
     671     * Returns an array of all nested JSON files within a given directory.
     672     *
     673     * @since 6.2.0
     674     *
     675     * @param string $dir The directory to recursively iterate and list files of.
     676     * @return array The merged array.
     677     */
     678    private static function recursively_iterate_json( $dir ) {
     679        $nested_files      = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $dir ) );
     680        $nested_json_files = iterator_to_array( new RegexIterator( $nested_files, '/^.+\.json$/i', RecursiveRegexIterator::GET_MATCH ) );
     681        return $nested_json_files;
     682    }
     683
     684
     685    /**
    653686     * Returns the style variations defined by the theme.
    654687     *
    655688     * @since 6.0.0
     689     * @since 6.2.0 Returns parent theme variations if theme is a child.
    656690     *
    657691     * @return array
    658692     */
    659693    public static function get_style_variations() {
    660         $variations     = array();
    661         $base_directory = get_stylesheet_directory() . '/styles';
     694        $variation_files    = array();
     695        $variations         = array();
     696        $base_directory     = get_stylesheet_directory() . '/styles';
     697        $template_directory = get_template_directory() . '/styles';
    662698        if ( is_dir( $base_directory ) ) {
    663             $nested_files      = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $base_directory ) );
    664             $nested_html_files = iterator_to_array( new RegexIterator( $nested_files, '/^.+\.json$/i', RecursiveRegexIterator::GET_MATCH ) );
    665             ksort( $nested_html_files );
    666             foreach ( $nested_html_files as $path => $file ) {
    667                 $decoded_file = wp_json_file_decode( $path, array( 'associative' => true ) );
    668                 if ( is_array( $decoded_file ) ) {
    669                     $translated = static::translate( $decoded_file, wp_get_theme()->get( 'TextDomain' ) );
    670                     $variation  = ( new WP_Theme_JSON( $translated ) )->get_raw_data();
    671                     if ( empty( $variation['title'] ) ) {
    672                         $variation['title'] = basename( $path, '.json' );
     699            $variation_files = static::recursively_iterate_json( $base_directory );
     700        }
     701        if ( is_dir( $template_directory ) && $template_directory !== $base_directory ) {
     702            $variation_files_parent = static::recursively_iterate_json( $template_directory );
     703            // If the child and parent variation file basename are the same, only include the child theme's.
     704            foreach ( $variation_files_parent as $parent_path => $parent ) {
     705                foreach ( $variation_files as $child_path => $child ) {
     706                    if ( basename( $parent_path ) === basename( $child_path ) ) {
     707                        unset( $variation_files_parent[ $parent_path ] );
    673708                    }
    674                     $variations[] = $variation;
    675709                }
    676710            }
     711            $variation_files = array_merge( $variation_files, $variation_files_parent );
     712        }
     713        ksort( $variation_files );
     714        foreach ( $variation_files as $path => $file ) {
     715            $decoded_file = wp_json_file_decode( $path, array( 'associative' => true ) );
     716            if ( is_array( $decoded_file ) ) {
     717                $translated = static::translate( $decoded_file, wp_get_theme()->get( 'TextDomain' ) );
     718                $variation  = ( new WP_Theme_JSON( $translated ) )->get_raw_data();
     719                if ( empty( $variation['title'] ) ) {
     720                    $variation['title'] = basename( $path, '.json' );
     721                }
     722                $variations[] = $variation;
     723            }
    677724        }
    678725        return $variations;
    679726    }
    680 
    681727}
  • trunk/tests/phpunit/tests/rest-api/rest-global-styles-controller.php

    r55192 r55231  
    485485        $data     = $response->get_data();
    486486        $expected = array(
     487            array(
     488                'version'  => 2,
     489                'title'    => 'variation-b',
     490                'settings' => array(
     491                    'blocks' => array(
     492                        'core/post-title' => array(
     493                            'color' => array(
     494                                'palette' => array(
     495                                    'theme' => array(
     496                                        array(
     497                                            'slug'  => 'light',
     498                                            'name'  => 'Light',
     499                                            'color' => '#f1f1f1',
     500                                        ),
     501                                    ),
     502                                ),
     503                            ),
     504                        ),
     505                    ),
     506                ),
     507            ),
    487508            array(
    488509                'version'  => 2,
     
    512533            ),
    513534        );
    514         $this->assertSameSetsWithIndex( $data, $expected );
     535
     536        wp_recursive_ksort( $data );
     537        wp_recursive_ksort( $expected );
     538
     539        $this->assertSameSets( $data, $expected );
    515540    }
    516541
  • trunk/tests/phpunit/tests/theme/wpThemeJsonResolver.php

    r55118 r55231  
    236236        $this->assertSame(
    237237            'Wariant motywu blokowego',
    238             $style_variations[0]['title']
     238            $style_variations[1]['title']
    239239        );
    240240    }
     
    776776        $this->assertNull( $property->getValue(), 'Theme i18n schema should not have been loaded without theme support.' );
    777777    }
     778
     779    /**
     780     * Tests that get_merged_data returns the data merged up to the proper origin.
     781     *
     782     * @ticket 57545
     783     *
     784     * @covers WP_Theme_JSON_Resolver::get_merged_data
     785     *
     786     * @dataProvider data_get_merged_data_returns_origin
     787     *
     788     * @param string $origin             What origin to get data from.
     789     * @param bool   $core_palette       Whether the core palette is present.
     790     * @param string $core_palette_text  Message.
     791     * @param string $block_styles       Whether the block styles are present.
     792     * @param string $block_styles_text  Message.
     793     * @param bool   $theme_palette      Whether the theme palette is present.
     794     * @param string $theme_palette_text Message.
     795     * @param bool   $user_palette        Whether the user palette is present.
     796     * @param string $user_palette_text   Message.
     797     */
     798    public function test_get_merged_data_returns_origin( $origin, $core_palette, $core_palette_text, $block_styles, $block_styles_text, $theme_palette, $theme_palette_text, $user_palette, $user_palette_text ) {
     799        // Make sure there is data from the blocks origin.
     800        register_block_type(
     801            'my/block-with-styles',
     802            array(
     803                'api_version' => 2,
     804                'attributes'  => array(
     805                    'borderColor' => array(
     806                        'type' => 'string',
     807                    ),
     808                    'style'       => array(
     809                        'type' => 'object',
     810                    ),
     811                ),
     812                'supports'    => array(
     813                    '__experimentalStyle' => array(
     814                        'typography' => array(
     815                            'fontSize' => '42rem',
     816                        ),
     817                    ),
     818                ),
     819            )
     820        );
     821
     822        // Make sure there is data from the theme origin.
     823        switch_theme( 'block-theme' );
     824
     825        // Make sure there is data from the user origin.
     826        wp_set_current_user( self::$administrator_id );
     827        $user_cpt = WP_Theme_JSON_Resolver::get_user_data_from_wp_global_styles( wp_get_theme(), true );
     828        $config   = json_decode( $user_cpt['post_content'], true );
     829        $config['settings']['color']['palette']['custom'] = array(
     830            array(
     831                'color' => 'hotpink',
     832                'name'  => 'My color',
     833                'slug'  => 'my-color',
     834            ),
     835        );
     836        $user_cpt['post_content']                         = wp_json_encode( $config );
     837        wp_update_post( $user_cpt, true, false );
     838
     839        $theme_json = WP_Theme_JSON_Resolver::get_merged_data( $origin );
     840        $settings   = $theme_json->get_settings();
     841        $styles     = $theme_json->get_styles_block_nodes();
     842        $styles     = array_filter(
     843            $styles,
     844            static function( $element ) {
     845                return isset( $element['name'] ) && 'my/block-with-styles' === $element['name'];
     846            }
     847        );
     848        unregister_block_type( 'my/block-with-styles' );
     849
     850        $this->assertSame( $core_palette, isset( $settings['color']['palette']['default'] ), $core_palette_text );
     851        $this->assertSame( $block_styles, count( $styles ) === 1, $block_styles_text );
     852        $this->assertSame( $theme_palette, isset( $settings['color']['palette']['theme'] ), $theme_palette_text );
     853        $this->assertSame( $user_palette, isset( $settings['color']['palette']['custom'] ), $user_palette_text );
     854
     855    }
     856
     857    /**
     858     * Data provider.
     859     *
     860     * @return array[]
     861     */
     862    public function data_get_merged_data_returns_origin() {
     863        return array(
     864            'origin_default' => array(
     865                'origin'             => 'default',
     866                'core_palette'       => true,
     867                'core_palette_text'  => 'Core palette must be present',
     868                'block_styles'       => false,
     869                'block_styles_text'  => 'Block styles should not be present',
     870                'theme_palette'      => false,
     871                'theme_palette_text' => 'Theme palette should not be present',
     872                'user_palette'       => false,
     873                'user_palette_text'  => 'User palette should not be present',
     874            ),
     875            'origin_blocks'  => array(
     876                'origin'             => 'blocks',
     877                'core_palette'       => true,
     878                'core_palette_text'  => 'Core palette must be present',
     879                'block_styles'       => true,
     880                'block_styles_text'  => 'Block styles must be present',
     881                'theme_palette'      => false,
     882                'theme_palette_text' => 'Theme palette should not be present',
     883                'user_palette'       => false,
     884                'user_palette_text'  => 'User palette should not be present',
     885            ),
     886            'origin_theme'   => array(
     887                'origin'             => 'theme',
     888                'core_palette'       => true,
     889                'core_palette_text'  => 'Core palette must be present',
     890                'block_styles'       => true,
     891                'block_styles_text'  => 'Block styles must be present',
     892                'theme_palette'      => true,
     893                'theme_palette_text' => 'Theme palette must be present',
     894                'user_palette'       => false,
     895                'user_palette_text'  => 'User palette should not be present',
     896            ),
     897            'origin_custom'  => array(
     898                'origin'             => 'custom',
     899                'core_palette'       => true,
     900                'core_palette_text'  => 'Core palette must be present',
     901                'block_styles'       => true,
     902                'block_styles_text'  => 'Block styles must be present',
     903                'theme_palette'      => true,
     904                'theme_palette_text' => 'Theme palette must be present',
     905                'user_palette'       => true,
     906                'user_palette_text'  => 'User palette must be present',
     907            ),
     908        );
     909    }
     910
     911    /**
     912     * Tests that get_style_variations returns all variations, including parent theme variations if the theme is a child,
     913     * and that the child variation overwrites the parent variation of the same name.
     914     *
     915     * @ticket 57545
     916     *
     917     * @covers WP_Theme_JSON_Resolver::get_style_variations
     918     **/
     919    public function test_get_style_variations_returns_all_variations() {
     920        // Switch to a child theme.
     921        switch_theme( 'block-theme-child' );
     922        wp_set_current_user( self::$administrator_id );
     923
     924        $actual_settings   = WP_Theme_JSON_Resolver::get_style_variations();
     925        $expected_settings = array(
     926            array(
     927                'version'  => 2,
     928                'title'    => 'variation-b',
     929                'settings' => array(
     930                    'blocks' => array(
     931                        'core/post-title' => array(
     932                            'color' => array(
     933                                'palette' => array(
     934                                    'theme' => array(
     935                                        array(
     936                                            'slug'  => 'dark',
     937                                            'name'  => 'Dark',
     938                                            'color' => '#010101',
     939                                        ),
     940                                    ),
     941                                ),
     942                            ),
     943                        ),
     944                    ),
     945                ),
     946            ),
     947            array(
     948                'version'  => 2,
     949                'title'    => 'Block theme variation',
     950                'settings' => array(
     951                    'color' => array(
     952                        'palette' => array(
     953                            'theme' => array(
     954                                array(
     955                                    'slug'  => 'foreground',
     956                                    'name'  => 'Foreground',
     957                                    'color' => '#3F67C6',
     958                                ),
     959                            ),
     960                        ),
     961                    ),
     962                ),
     963                'styles'   => array(
     964                    'blocks' => array(
     965                        'core/post-title' => array(
     966                            'typography' => array(
     967                                'fontWeight' => '700',
     968                            ),
     969                        ),
     970                    ),
     971                ),
     972            ),
     973        );
     974
     975        wp_recursive_ksort( $actual_settings );
     976        wp_recursive_ksort( $expected_settings );
     977
     978        $this->assertSame(
     979            $expected_settings,
     980            $actual_settings
     981        );
     982    }
    778983}
Note: See TracChangeset for help on using the changeset viewer.