Make WordPress Core


Ignore:
Timestamp:
12/21/2021 04:12:06 AM (2 years ago)
Author:
hellofromTonya
Message:

REST API: Support . in theme directory names in WP_REST_Global_Styles_Controller, WP_REST_Templates_Controller, and WP_REST_Themes_Controller.

Regex changes from [52376] are reverted to restore the original regex patterns. Why? [52376] used an include characters pattern, which was too limiting. It did not account for localized characters, such as é, or other valid directory name characters.

The original theme directory regex pattern, i.e. [^.\/]+(?:\/[^.\/]+)? excluded the period . character. Removing the . character resolves the reported issue by allowing matching for themes/theme-dirname-1.0/ or themes/<subdirname>/theme-dirname-1.0/.

As the pattern used an exclude approach, all characters are valid for matching except for /. However, not all characters are cross-platform valid for directory names. For example, the characters /:<>*?"| are not valid on Windows OS. The pattern now excludes those characters.

The theme's directory (or subdirectory) name pattern matching is now used in WP_REST_Global_Styles_Controller, WP_REST_Templates_Controller, and WP_REST_Themes_Controller.

Follow-up to [51003], [52051], [52275], [52376].

Props costdev, hellofromTonya, spacedmonkey, TimothyBlynJacobs, bijayyadav, kafleg.
Fixes #54596.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tests/phpunit/tests/rest-api/wpRestTemplatesController.php

    r52376 r52399  
    6666        );
    6767        $this->assertArrayHasKey(
    68             '/wp/v2/templates/(?P<id>[\/\s%\w\.\(\)\[\]\@_\-]+)',
     68            '/wp/v2/templates/(?P<id>([^\/:<>\*\?"\|]+(?:\/[^\/:<>\*\?"\|]+)?)[\/\w-]+)',
    6969            $routes,
    7070            'Single template based on the given ID route does not exist'
     
    206206            array( '/wp/v2/templates/default/my_template' ),
    207207            array( '/wp/v2/templates/default//my_template' ),
     208        );
     209    }
     210
     211    /**
     212     * @dataProvider data_get_item_with_valid_theme_dirname
     213     * @covers WP_REST_Templates_Controller::get_item
     214     * @ticket 54596
     215     *
     216     * @param string $theme_dir Theme directory to test.
     217     * @param string $template  Template to test.
     218     * @param array  $args      Arguments to create the 'wp_template" post.
     219     */
     220    public function test_get_item_with_valid_theme_dirname( $theme_dir, $template, array $args ) {
     221        wp_set_current_user( self::$admin_id );
     222        switch_theme( $theme_dir );
     223
     224        // Set up template post.
     225        $args['post_type'] = 'wp_template';
     226        $args['tax_input'] = array(
     227            'wp_theme' => array(
     228                get_stylesheet(),
     229            ),
     230        );
     231        $post              = self::factory()->post->create_and_get( $args );
     232        wp_set_post_terms( $post->ID, get_stylesheet(), 'wp_theme' );
     233
     234        $request  = new WP_REST_Request( 'GET', "/wp/v2/templates/{$theme_dir}//{$template}" );
     235        $response = rest_get_server()->dispatch( $request );
     236        $data     = $response->get_data();
     237        unset( $data['content'] );
     238        unset( $data['_links'] );
     239
     240        $this->assertSameSetsWithIndex(
     241            array(
     242                'id'             => "{$theme_dir}//{$template}",
     243                'theme'          => $theme_dir,
     244                'slug'           => $template,
     245                'source'         => 'custom',
     246                'origin'         => null,
     247                'type'           => 'wp_template',
     248                'description'    => $args['post_excerpt'],
     249                'title'          => array(
     250                    'raw'      => $args['post_title'],
     251                    'rendered' => $args['post_title'],
     252                ),
     253                'status'         => 'publish',
     254                'wp_id'          => $post->ID,
     255                'has_theme_file' => false,
     256                'is_custom'      => true,
     257                'author'         => self::$admin_id,
     258            ),
     259            $data
     260        );
     261    }
     262
     263    /**
     264     * Data provider.
     265     *
     266     * @return array
     267     */
     268    public function data_get_item_with_valid_theme_dirname() {
     269        $theme_root_dir = DIR_TESTDATA . '/themedir1/';
     270        return array(
     271            'template parts: parent theme'                => array(
     272                'theme_dir' => 'themedir1/block-theme',
     273                'template'  => 'small-header',
     274                'args'      => array(
     275                    'post_name'    => 'small-header',
     276                    'post_title'   => 'Small Header Template',
     277                    'post_content' => file_get_contents( $theme_root_dir . '/block-theme/parts/small-header.html' ),
     278                    'post_excerpt' => 'Description of small header template.',
     279                ),
     280            ),
     281            'template: parent theme'                      => array(
     282                'theme_dir' => 'themedir1/block-theme',
     283                'template'  => 'page-home',
     284                'args'      => array(
     285                    'post_name'    => 'page-home',
     286                    'post_title'   => 'Home Page Template',
     287                    'post_content' => file_get_contents( $theme_root_dir . 'block-theme/templates/page-home.html' ),
     288                    'post_excerpt' => 'Description of page home template.',
     289                ),
     290            ),
     291            'template: child theme'                       => array(
     292                'theme_dir' => 'themedir1/block-theme-child',
     293                'template'  => 'page-1',
     294                'args'      => array(
     295                    'post_name'    => 'page-1',
     296                    'post_title'   => 'Page 1 Template',
     297                    'post_content' => file_get_contents( $theme_root_dir . 'block-theme-child/templates/page-1.html' ),
     298                    'post_excerpt' => 'Description of page 1 template.',
     299                ),
     300            ),
     301            'template part: subdir with _-[]. characters' => array(
     302                'theme_dir' => 'themedir1/block_theme-[0.4.0]',
     303                'template'  => 'large-header',
     304                'args'      => array(
     305                    'post_name'    => 'large-header',
     306                    'post_title'   => 'Large Header Template Part',
     307                    'post_content' => file_get_contents( $theme_root_dir . 'block_theme-[0.4.0]/parts/large-header.html' ),
     308                    'post_excerpt' => 'Description of large header template.',
     309                ),
     310            ),
     311            'template: subdir with _-[]. characters'      => array(
     312                'theme_dir' => 'themedir1/block_theme-[0.4.0]',
     313                'template'  => 'page-large-header',
     314                'args'      => array(
     315                    'post_name'    => 'page-large-header',
     316                    'post_title'   => 'Page Large Template',
     317                    'post_content' => file_get_contents( $theme_root_dir . 'block_theme-[0.4.0]/templates/page-large-header.html' ),
     318                    'post_excerpt' => 'Description of page large template.',
     319                ),
     320            ),
    208321        );
    209322    }
Note: See TracChangeset for help on using the changeset viewer.