Skip to content

Commit

Permalink
[REST] Restore the missing double slash in the ID received by /templa…
Browse files Browse the repository at this point in the history
…tes (#36881)

* Fall back to a double-slashed template name if a single-slashed one is missing

* Add a unit test

* Use $_SERVER['REQUEST_URI'] as a fallback instead of simply replacing all slashes with a double slash.

* Fallback to parsing the query string instead of doing it by default

* Code style

* Update docstring

* Try doubling the last slash instead of parsing REQUEST_URI

* Use sanitize_callback

* Lint

* Test for both single and double slash

* Add unit tests for _sanitize_template_id

* Update phpunit/class-gutenberg-rest-template-controller-test.php

* Update phpunit/class-gutenberg-rest-template-controller-test.php
  • Loading branch information
adamziel authored Nov 26, 2021
1 parent 37a4113 commit 7676a59
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,9 @@ public function register_routes() {
'permission_callback' => array( $this, 'get_item_permissions_check' ),
'args' => array(
'id' => array(
'description' => __( 'The id of a template', 'gutenberg' ),
'type' => 'string',
'description' => __( 'The id of a template', 'gutenberg' ),
'type' => 'string',
'sanitize_callback' => array( $this, '_sanitize_template_id' ),
),
),
),
Expand Down Expand Up @@ -116,6 +117,36 @@ protected function permissions_check() {
return true;
}

/**
* Requesting this endpoint for a template like "twentytwentytwo//home" requires using
* a path like /wp/v2/templates/twentytwentytwo//home. There are special cases when
* WordPress routing corrects the name to contain only a single slash like "twentytwentytwo/home".
*
* This method doubles the last slash if it's not already doubled. It relies on the template
* ID format {theme_name}//{template_slug} and the fact that slugs cannot contain slashes.
*
* See https://core.trac.wordpress.org/ticket/54507 for more context
*
* @param string $id Template ID.
* @return string Sanitized template ID.
*/
public function _sanitize_template_id( $id ) {
$last_slash_pos = strrpos( $id, '/' );
if ( false === $last_slash_pos ) {
return $id;
}

$is_double_slashed = substr( $id, $last_slash_pos - 1, 1 ) === '/';
if ( $is_double_slashed ) {
return $id;
}
return (
substr( $id, 0, $last_slash_pos )
. '/'
. substr( $id, $last_slash_pos )
);
}

/**
* Checks if a given request has access to read templates.
*
Expand Down
70 changes: 70 additions & 0 deletions phpunit/class-gutenberg-rest-template-controller-test.php
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,76 @@ public function test_get_item() {
);
}

/**
* Ticket 54507
*
* @dataProvider get_template_endpoint_urls
*/
public function test_get_item_works_with_a_single_slash( $endpoint_url ) {
wp_set_current_user( self::$admin_id );
$request = new WP_REST_Request( 'GET', $endpoint_url );
$response = rest_get_server()->dispatch( $request );

$data = $response->get_data();
unset( $data['content'] );
unset( $data['_links'] );

$this->assertEquals(
array(
'id' => 'tt1-blocks//index',
'theme' => 'tt1-blocks',
'slug' => 'index',
'title' => array(
'raw' => 'Index',
'rendered' => 'Index',
),
'description' => 'The default template used when no other template is available. This is a required template in WordPress.',
'status' => 'publish',
'source' => 'theme',
'type' => 'wp_template',
'wp_id' => null,
'has_theme_file' => true,
),
$data
);
}

/**
*
*/
public function get_template_endpoint_urls() {
return array(
array( '/wp/v2/templates/tt1-blocks/index' ),
array( '/wp/v2/templates/tt1-blocks//index' ),
);
}

/**
* Ticket 54507
*
* @dataProvider get_template_ids_to_sanitize
*/
public function test_sanitize_template_id( $input_id, $sanitized_id ) {
$endpoint = new Gutenberg_REST_Templates_Controller( 'wp_template' );
$this->assertEquals(
$sanitized_id,
$endpoint->_sanitize_template_id( $input_id )
);
}

/**
*
*/
public function get_template_ids_to_sanitize() {
return array(
array( 'tt1-blocks/index', 'tt1-blocks//index' ),
array( 'tt1-blocks//index', 'tt1-blocks//index' ),

array( 'theme-experiments/tt1-blocks/index', 'theme-experiments/tt1-blocks//index' ),
array( 'theme-experiments/tt1-blocks//index', 'theme-experiments/tt1-blocks//index' ),
);
}

public function test_create_item() {
wp_set_current_user( self::$admin_id );
$request = new WP_REST_Request( 'POST', '/wp/v2/templates' );
Expand Down

0 comments on commit 7676a59

Please sign in to comment.