diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php
index 93a2b8d..af5249b 100644
a
|
b
|
class WP_REST_Posts_Controller extends WP_REST_Controller { |
574 | 574 | } |
575 | 575 | |
576 | 576 | 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 ); |
578 | 578 | } |
579 | 579 | |
580 | 580 | $terms_update = $this->handle_terms( $post_id, $request ); |
… |
… |
class WP_REST_Posts_Controller extends WP_REST_Controller { |
1071 | 1071 | $prepared_post->ping_status = $request['ping_status']; |
1072 | 1072 | } |
1073 | 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; |
| 1077 | } |
| 1078 | |
1074 | 1079 | /** |
1075 | 1080 | * Filters a post before it is inserted via the REST API. |
1076 | 1081 | * |
… |
… |
class WP_REST_Posts_Controller extends WP_REST_Controller { |
1148 | 1153 | } |
1149 | 1154 | |
1150 | 1155 | /** |
| 1156 | * Check whether the template is valid for the given post. |
| 1157 | * |
| 1158 | * @since 4.9.0 |
| 1159 | * |
| 1160 | * @param string $template |
| 1161 | * @param WP_REST_Request $request |
| 1162 | * |
| 1163 | * @return bool|WP_Error True if template is still valid or if the same as existing value, or false if template not supported. |
| 1164 | */ |
| 1165 | public function check_template( $template, $request ) { |
| 1166 | |
| 1167 | if ( ! $template ) { |
| 1168 | return true; |
| 1169 | } |
| 1170 | |
| 1171 | if ( $request['id'] ) { |
| 1172 | $current_template = get_page_template_slug( $request['id'] ); |
| 1173 | } else { |
| 1174 | $current_template = ''; |
| 1175 | } |
| 1176 | |
| 1177 | // Always allow for updating a post to the same template, even if that template is no longer supported. |
| 1178 | if ( $template === $current_template ) { |
| 1179 | return true; |
| 1180 | } |
| 1181 | |
| 1182 | // If this is a create request, get_post() will return null and wp theme will fallback to the passed post type. |
| 1183 | $allowed_templates = wp_get_theme()->get_page_templates( get_post( $request['id'] ), $this->post_type ); |
| 1184 | |
| 1185 | if ( isset( $allowed_templates[ $template ] ) ) { |
| 1186 | return true; |
| 1187 | } |
| 1188 | |
| 1189 | /* translators: 1: parameter, 2: list of valid values */ |
| 1190 | return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s is not one of %2$s.' ), 'template', implode( ', ', array_keys( $allowed_templates ) ) ) ); |
| 1191 | } |
| 1192 | |
| 1193 | /** |
1151 | 1194 | * Sets the template for a post. |
1152 | 1195 | * |
1153 | 1196 | * @since 4.7.0 |
| 1197 | * @since 4.9.0 Introduced the $validate parameter. |
1154 | 1198 | * |
1155 | 1199 | * @param string $template Page template filename. |
1156 | 1200 | * @param integer $post_id Post ID. |
| 1201 | * @param bool $validate Whether to validate that the template selected is valid. |
1157 | 1202 | */ |
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', '' ); |
| 1203 | public function handle_template( $template, $post_id, $validate = false ) { |
| 1204 | |
| 1205 | if ( $validate && ! array_key_exists( $template, wp_get_theme()->get_page_templates( get_post( $post_id ) ) ) ) { |
| 1206 | $template = ''; |
1163 | 1207 | } |
| 1208 | |
| 1209 | update_post_meta( $post_id, '_wp_page_template', $template ); |
1164 | 1210 | } |
1165 | 1211 | |
1166 | 1212 | /** |
… |
… |
class WP_REST_Posts_Controller extends WP_REST_Controller { |
1996 | 2042 | $schema['properties']['template'] = array( |
1997 | 2043 | 'description' => __( 'The theme file to use to display the object.' ), |
1998 | 2044 | 'type' => 'string', |
1999 | | 'enum' => array_merge( array_keys( wp_get_theme()->get_page_templates( null, $this->post_type ) ), array( '' ) ), |
2000 | 2045 | 'context' => array( 'view', 'edit' ), |
| 2046 | 'arg_options' => array( |
| 2047 | 'validate_callback' => array( $this, 'check_template' ), |
| 2048 | ), |
2001 | 2049 | ); |
2002 | 2050 | |
2003 | 2051 | $taxonomies = wp_list_filter( get_object_taxonomies( $this->post_type, 'objects' ), array( 'show_in_rest' => true ) ); |
diff --git a/tests/phpunit/tests/rest-api/rest-posts-controller.php b/tests/phpunit/tests/rest-api/rest-posts-controller.php
index cf82fe5..78efaeb 100644
a
|
b
|
class WP_Test_REST_Posts_Controller extends WP_Test_REST_Post_Type_Controller_Te |
2667 | 2667 | $this->assertEquals( '', $post_template ); |
2668 | 2668 | } |
2669 | 2669 | |
| 2670 | /** |
| 2671 | * @ticket 39996 |
| 2672 | */ |
| 2673 | public function test_update_item_with_same_template_that_no_longer_exists() { |
| 2674 | |
| 2675 | wp_set_current_user( self::$editor_id ); |
| 2676 | |
| 2677 | update_post_meta( self::$post_id, '_wp_page_template', 'post-my-invalid-template.php' ); |
| 2678 | |
| 2679 | $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/posts/%d', self::$post_id ) ); |
| 2680 | $params = $this->set_post_data( array( |
| 2681 | 'template' => 'post-my-invalid-template.php', |
| 2682 | ) ); |
| 2683 | $request->set_body_params( $params ); |
| 2684 | $response = $this->server->dispatch( $request ); |
| 2685 | |
| 2686 | $this->assertEquals( 200, $response->get_status() ); |
| 2687 | |
| 2688 | $data = $response->get_data(); |
| 2689 | $post_template = get_page_template_slug( get_post( $data['id'] ) ); |
| 2690 | |
| 2691 | $this->assertEquals( 'post-my-invalid-template.php', $post_template ); |
| 2692 | $this->assertEquals( 'post-my-invalid-template.php', $data['template'] ); |
| 2693 | } |
2670 | 2694 | |
2671 | 2695 | public function verify_post_roundtrip( $input = array(), $expected_output = array() ) { |
2672 | 2696 | // Create the post |