Make WordPress Core

Changeset 41979


Ignore:
Timestamp:
10/23/2017 10:10:48 PM (7 years ago)
Author:
westonruter
Message:

REST API: Allow passing existing template value for posts even when template no longer exists.

Also remove enum for validating allowed templates to allow plugins to dynamically supply their own templates for specific posts, even when they are not in the theme.

Props TimothyBlynJacobs, jnylen0, swissspidy.
Fixes #39996.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php

    r41760 r41979  
    575575
    576576        if ( ! empty( $schema['properties']['template'] ) && isset( $request['template'] ) ) {
    577             $this->handle_template( $request['template'], $post_id );
     577            $this->handle_template( $request['template'], $post_id, true );
    578578        }
    579579
     
    10701070        if ( ! empty( $schema['properties']['ping_status'] ) && ! empty( $request['ping_status'] ) ) {
    10711071            $prepared_post->ping_status = $request['ping_status'];
     1072        }
     1073
     1074        if ( ! empty( $schema['properties']['template'] ) ) {
     1075            // Force template to null so that it can be handled exclusively by the REST controller.
     1076            $prepared_post->page_template = null;
    10721077        }
    10731078
     
    11491154
    11501155    /**
     1156     * Check whether the template is valid for the given post.
     1157     *
     1158     * @since 4.9.0
     1159     *
     1160     * @param string          $template Page template filename.
     1161     * @param WP_REST_Request $request  Request.
     1162     * @return bool|WP_Error True if template is still valid or if the same as existing value, or false if template not supported.
     1163     */
     1164    public function check_template( $template, $request ) {
     1165
     1166        if ( ! $template ) {
     1167            return true;
     1168        }
     1169
     1170        if ( $request['id'] ) {
     1171            $current_template = get_page_template_slug( $request['id'] );
     1172        } else {
     1173            $current_template = '';
     1174        }
     1175
     1176        // Always allow for updating a post to the same template, even if that template is no longer supported.
     1177        if ( $template === $current_template ) {
     1178            return true;
     1179        }
     1180
     1181        // If this is a create request, get_post() will return null and wp theme will fallback to the passed post type.
     1182        $allowed_templates = wp_get_theme()->get_page_templates( get_post( $request['id'] ), $this->post_type );
     1183
     1184        if ( isset( $allowed_templates[ $template ] ) ) {
     1185            return true;
     1186        }
     1187
     1188        /* translators: 1: parameter, 2: list of valid values */
     1189        return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s is not one of %2$s.' ), 'template', implode( ', ', array_keys( $allowed_templates ) ) ) );
     1190    }
     1191
     1192    /**
    11511193     * Sets the template for a post.
    11521194     *
    11531195     * @since 4.7.0
     1196     * @since 4.9.0 Introduced the $validate parameter.
    11541197     *
    11551198     * @param string  $template Page template filename.
    11561199     * @param integer $post_id  Post ID.
    1157      */
    1158     public function handle_template( $template, $post_id ) {
    1159         if ( in_array( $template, array_keys( wp_get_theme()->get_page_templates( get_post( $post_id ) ) ), true ) ) {
    1160             update_post_meta( $post_id, '_wp_page_template', $template );
    1161         } else {
    1162             update_post_meta( $post_id, '_wp_page_template', '' );
    1163         }
     1200     * @param bool    $validate Whether to validate that the template selected is valid.
     1201     */
     1202    public function handle_template( $template, $post_id, $validate = false ) {
     1203
     1204        if ( $validate && ! array_key_exists( $template, wp_get_theme()->get_page_templates( get_post( $post_id ) ) ) ) {
     1205            $template = '';
     1206        }
     1207
     1208        update_post_meta( $post_id, '_wp_page_template', $template );
    11641209    }
    11651210
     
    19972042            'description' => __( 'The theme file to use to display the object.' ),
    19982043            'type'        => 'string',
    1999             'enum'        => array_merge( array_keys( wp_get_theme()->get_page_templates( null, $this->post_type ) ), array( '' ) ),
    20002044            'context'     => array( 'view', 'edit' ),
     2045            'arg_options' => array(
     2046                'validate_callback' => array( $this, 'check_template' ),
     2047            ),
    20012048        );
    20022049
  • trunk/tests/phpunit/tests/rest-api/rest-posts-controller.php

    r41760 r41979  
    26682668    }
    26692669
     2670    /**
     2671     * Test update_item() with same template that no longer exists.
     2672     *
     2673     * @covers WP_REST_Posts_Controller::check_template()
     2674     * @ticket 39996
     2675     */
     2676    public function test_update_item_with_same_template_that_no_longer_exists() {
     2677
     2678        wp_set_current_user( self::$editor_id );
     2679
     2680        update_post_meta( self::$post_id, '_wp_page_template', 'post-my-invalid-template.php' );
     2681
     2682        $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/posts/%d', self::$post_id ) );
     2683        $params = $this->set_post_data( array(
     2684            'template' => 'post-my-invalid-template.php',
     2685        ) );
     2686        $request->set_body_params( $params );
     2687        $response = $this->server->dispatch( $request );
     2688
     2689        $this->assertEquals( 200, $response->get_status() );
     2690
     2691        $data = $response->get_data();
     2692        $post_template = get_page_template_slug( get_post( $data['id'] ) );
     2693
     2694        $this->assertEquals( 'post-my-invalid-template.php', $post_template );
     2695        $this->assertEquals( 'post-my-invalid-template.php', $data['template'] );
     2696    }
    26702697
    26712698    public function verify_post_roundtrip( $input = array(), $expected_output = array() ) {
Note: See TracChangeset for help on using the changeset viewer.