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 018b66e..e791cd6 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 { |
1070 | 1070 | $prepared_post->ping_status = $request['ping_status']; |
1071 | 1071 | } |
1072 | 1072 | |
| 1073 | if ( ! empty( $schema['properties']['template'] ) ) { |
| 1074 | // Force template to null so that it can be handled exclusively by the REST controller. |
| 1075 | $prepared_post->page_template = null; |
| 1076 | } |
| 1077 | |
1073 | 1078 | /** |
1074 | 1079 | * Filters a post before it is inserted via the REST API. |
1075 | 1080 | * |
… |
… |
class WP_REST_Posts_Controller extends WP_REST_Controller { |
1147 | 1152 | } |
1148 | 1153 | |
1149 | 1154 | /** |
| 1155 | * Check whether the template is valid for the given post. |
| 1156 | * |
| 1157 | * @since 4.9.0 |
| 1158 | * |
| 1159 | * @param string $template |
| 1160 | * @param WP_REST_Request $request |
| 1161 | * |
| 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 | /** |
1150 | 1193 | * Sets the template for a post. |
1151 | 1194 | * |
1152 | 1195 | * @since 4.7.0 |
| 1196 | * @since 4.9.0 Introduced the $validate parameter. |
1153 | 1197 | * |
1154 | 1198 | * @param string $template Page template filename. |
1155 | 1199 | * @param integer $post_id Post ID. |
| 1200 | * @param bool $validate Whether to validate that the template selected is valid. |
1156 | 1201 | */ |
1157 | | public function handle_template( $template, $post_id ) { |
1158 | | if ( in_array( $template, array_keys( wp_get_theme()->get_page_templates( get_post( $post_id ) ) ), true ) ) { |
1159 | | update_post_meta( $post_id, '_wp_page_template', $template ); |
1160 | | } else { |
1161 | | update_post_meta( $post_id, '_wp_page_template', '' ); |
| 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 = ''; |
1162 | 1206 | } |
| 1207 | |
| 1208 | update_post_meta( $post_id, '_wp_page_template', $template ); |
1163 | 1209 | } |
1164 | 1210 | |
1165 | 1211 | /** |
… |
… |
class WP_REST_Posts_Controller extends WP_REST_Controller { |
1994 | 2040 | 'type' => 'string', |
1995 | 2041 | 'enum' => array_merge( array_keys( wp_get_theme()->get_page_templates( null, $this->post_type ) ), array( '' ) ), |
1996 | 2042 | 'context' => array( 'view', 'edit' ), |
| 2043 | 'arg_options' => array( |
| 2044 | 'validate_callback' => array( $this, 'check_template' ), |
| 2045 | ), |
1997 | 2046 | ); |
1998 | 2047 | |
1999 | 2048 | $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 c86879c..b769003 100644
a
|
b
|
class WP_Test_REST_Posts_Controller extends WP_Test_REST_Post_Type_Controller_Te |
2649 | 2649 | $this->assertEquals( '', $post_template ); |
2650 | 2650 | } |
2651 | 2651 | |
| 2652 | /** |
| 2653 | * @ticket 39996 |
| 2654 | */ |
| 2655 | public function test_update_item_with_same_template_that_no_longer_exists() { |
| 2656 | |
| 2657 | wp_set_current_user( self::$editor_id ); |
| 2658 | |
| 2659 | update_post_meta( self::$post_id, '_wp_page_template', 'post-my-invalid-template.php' ); |
| 2660 | |
| 2661 | $request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/posts/%d', self::$post_id ) ); |
| 2662 | $params = $this->set_post_data( array( |
| 2663 | 'template' => 'post-my-invalid-template.php', |
| 2664 | ) ); |
| 2665 | $request->set_body_params( $params ); |
| 2666 | $response = $this->server->dispatch( $request ); |
| 2667 | |
| 2668 | $this->assertEquals( 200, $response->get_status() ); |
| 2669 | |
| 2670 | $data = $response->get_data(); |
| 2671 | $post_template = get_page_template_slug( get_post( $data['id'] ) ); |
| 2672 | |
| 2673 | $this->assertEquals( 'post-my-invalid-template.php', $post_template ); |
| 2674 | $this->assertEquals( 'post-my-invalid-template.php', $data['template'] ); |
| 2675 | } |
2652 | 2676 | |
2653 | 2677 | public function verify_post_roundtrip( $input = array(), $expected_output = array() ) { |
2654 | 2678 | // Create the post |