diff -r 3d4e9c994f10 -r a86126ab1dd4 wp/wp-includes/rest-api/endpoints/class-wp-rest-terms-controller.php --- a/wp/wp-includes/rest-api/endpoints/class-wp-rest-terms-controller.php Tue Oct 22 16:11:46 2019 +0200 +++ b/wp/wp-includes/rest-api/endpoints/class-wp-rest-terms-controller.php Tue Dec 15 13:49:49 2020 +0100 @@ -144,12 +144,19 @@ */ public function get_items_permissions_check( $request ) { $tax_obj = get_taxonomy( $this->taxonomy ); + if ( ! $tax_obj || ! $this->check_is_taxonomy_allowed( $this->taxonomy ) ) { return false; } + if ( 'edit' === $request['context'] && ! current_user_can( $tax_obj->cap->edit_terms ) ) { - return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you are not allowed to edit terms in this taxonomy.' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( + 'rest_forbidden_context', + __( 'Sorry, you are not allowed to edit terms in this taxonomy.' ), + array( 'status' => rest_authorization_required_code() ) + ); } + return true; } @@ -184,7 +191,7 @@ 'slug' => 'slug', ); - $prepared_args = array(); + $prepared_args = array( 'taxonomy' => $this->taxonomy ); /* * For each known parameter which is both registered and present in the request, @@ -249,7 +256,7 @@ // Used when calling wp_count_terms() below. $prepared_args['object_ids'] = $prepared_args['post']; } else { - $query_result = get_terms( $this->taxonomy, $prepared_args ); + $query_result = get_terms( $prepared_args ); } $count_args = $prepared_args; @@ -258,7 +265,7 @@ $total_terms = wp_count_terms( $this->taxonomy, $count_args ); - // wp_count_terms can return a falsy value when the term has no children. + // wp_count_terms() can return a falsey value when the term has no children. if ( ! $total_terms ) { $total_terms = 0; } @@ -312,7 +319,11 @@ * @return WP_Term|WP_Error Term object if ID is valid, WP_Error otherwise. */ protected function get_term( $id ) { - $error = new WP_Error( 'rest_term_invalid', __( 'Term does not exist.' ), array( 'status' => 404 ) ); + $error = new WP_Error( + 'rest_term_invalid', + __( 'Term does not exist.' ), + array( 'status' => 404 ) + ); if ( ! $this->check_is_taxonomy_allowed( $this->taxonomy ) ) { return $error; @@ -340,13 +351,19 @@ */ public function get_item_permissions_check( $request ) { $term = $this->get_term( $request['id'] ); + if ( is_wp_error( $term ) ) { return $term; } if ( 'edit' === $request['context'] && ! current_user_can( 'edit_term', $term->term_id ) ) { - return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you are not allowed to edit this term.' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( + 'rest_forbidden_context', + __( 'Sorry, you are not allowed to edit this term.' ), + array( 'status' => rest_authorization_required_code() ) + ); } + return true; } @@ -384,11 +401,16 @@ } $taxonomy_obj = get_taxonomy( $this->taxonomy ); + if ( ( is_taxonomy_hierarchical( $this->taxonomy ) && ! current_user_can( $taxonomy_obj->cap->edit_terms ) ) || ( ! is_taxonomy_hierarchical( $this->taxonomy ) && ! current_user_can( $taxonomy_obj->cap->assign_terms ) ) ) { - return new WP_Error( 'rest_cannot_create', __( 'Sorry, you are not allowed to create new terms.' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( + 'rest_cannot_create', + __( 'Sorry, you are not allowed to create terms in this taxonomy.' ), + array( 'status' => rest_authorization_required_code() ) + ); } return true; @@ -405,13 +427,21 @@ public function create_item( $request ) { if ( isset( $request['parent'] ) ) { if ( ! is_taxonomy_hierarchical( $this->taxonomy ) ) { - return new WP_Error( 'rest_taxonomy_not_hierarchical', __( 'Cannot set parent term, taxonomy is not hierarchical.' ), array( 'status' => 400 ) ); + return new WP_Error( + 'rest_taxonomy_not_hierarchical', + __( 'Cannot set parent term, taxonomy is not hierarchical.' ), + array( 'status' => 400 ) + ); } $parent = get_term( (int) $request['parent'], $this->taxonomy ); if ( ! $parent ) { - return new WP_Error( 'rest_term_invalid', __( 'Parent term does not exist.' ), array( 'status' => 400 ) ); + return new WP_Error( + 'rest_term_invalid', + __( 'Parent term does not exist.' ), + array( 'status' => 400 ) + ); } } @@ -423,7 +453,8 @@ * If we're going to inform the client that the term already exists, * give them the identifier for future use. */ - if ( $term_id = $term->get_error_data( 'term_exists' ) ) { + $term_id = $term->get_error_data( 'term_exists' ); + if ( $term_id ) { $existing_term = get_term( $term_id, $this->taxonomy ); $term->add_data( $existing_term->term_id, 'term_exists' ); $term->add_data( @@ -467,7 +498,7 @@ return $fields_update; } - $request->set_param( 'context', 'view' ); + $request->set_param( 'context', 'edit' ); /** * Fires after a single term is completely created or updated via the REST API. @@ -501,12 +532,17 @@ */ public function update_item_permissions_check( $request ) { $term = $this->get_term( $request['id'] ); + if ( is_wp_error( $term ) ) { return $term; } if ( ! current_user_can( 'edit_term', $term->term_id ) ) { - return new WP_Error( 'rest_cannot_update', __( 'Sorry, you are not allowed to edit this term.' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( + 'rest_cannot_update', + __( 'Sorry, you are not allowed to edit this term.' ), + array( 'status' => rest_authorization_required_code() ) + ); } return true; @@ -528,19 +564,27 @@ if ( isset( $request['parent'] ) ) { if ( ! is_taxonomy_hierarchical( $this->taxonomy ) ) { - return new WP_Error( 'rest_taxonomy_not_hierarchical', __( 'Cannot set parent term, taxonomy is not hierarchical.' ), array( 'status' => 400 ) ); + return new WP_Error( + 'rest_taxonomy_not_hierarchical', + __( 'Cannot set parent term, taxonomy is not hierarchical.' ), + array( 'status' => 400 ) + ); } $parent = get_term( (int) $request['parent'], $this->taxonomy ); if ( ! $parent ) { - return new WP_Error( 'rest_term_invalid', __( 'Parent term does not exist.' ), array( 'status' => 400 ) ); + return new WP_Error( + 'rest_term_invalid', + __( 'Parent term does not exist.' ), + array( 'status' => 400 ) + ); } } $prepared_term = $this->prepare_item_for_database( $request ); - // Only update the term if we haz something to update. + // Only update the term if we have something to update. if ( ! empty( $prepared_term ) ) { $update = wp_update_term( $term->term_id, $term->taxonomy, wp_slash( (array) $prepared_term ) ); @@ -569,7 +613,7 @@ return $fields_update; } - $request->set_param( 'context', 'view' ); + $request->set_param( 'context', 'edit' ); /** This action is documented in wp-includes/rest-api/endpoints/class-wp-rest-terms-controller.php */ do_action( "rest_after_insert_{$this->taxonomy}", $term, $request, false ); @@ -589,12 +633,17 @@ */ public function delete_item_permissions_check( $request ) { $term = $this->get_term( $request['id'] ); + if ( is_wp_error( $term ) ) { return $term; } if ( ! current_user_can( 'delete_term', $term->term_id ) ) { - return new WP_Error( 'rest_cannot_delete', __( 'Sorry, you are not allowed to delete this term.' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( + 'rest_cannot_delete', + __( 'Sorry, you are not allowed to delete this term.' ), + array( 'status' => rest_authorization_required_code() ) + ); } return true; @@ -618,8 +667,12 @@ // We don't support trashing for terms. if ( ! $force ) { - /* translators: %s: force=true */ - return new WP_Error( 'rest_trash_not_supported', sprintf( __( "Terms do not support trashing. Set '%s' to delete." ), 'force=true' ), array( 'status' => 501 ) ); + return new WP_Error( + 'rest_trash_not_supported', + /* translators: %s: force=true */ + sprintf( __( "Terms do not support trashing. Set '%s' to delete." ), 'force=true' ), + array( 'status' => 501 ) + ); } $request->set_param( 'context', 'view' ); @@ -629,7 +682,11 @@ $retval = wp_delete_term( $term->term_id, $term->taxonomy ); if ( ! $retval ) { - return new WP_Error( 'rest_cannot_delete', __( 'The term cannot be deleted.' ), array( 'status' => 500 ) ); + return new WP_Error( + 'rest_cannot_delete', + __( 'The term cannot be deleted.' ), + array( 'status' => 500 ) + ); } $response = new WP_REST_Response(); @@ -662,7 +719,7 @@ * @since 4.7.0 * * @param WP_REST_Request $request Request object. - * @return object $prepared_term Term object. + * @return object Term object. */ public function prepare_item_for_database( $request ) { $prepared_term = new stdClass; @@ -717,9 +774,9 @@ * * @since 4.7.0 * - * @param obj $item Term object. + * @param WP_Term $item Term object. * @param WP_REST_Request $request Request object. - * @return WP_REST_Response $response Response object. + * @return WP_REST_Response Response object. */ public function prepare_item_for_response( $item, $request ) { @@ -780,7 +837,7 @@ * @since 4.7.0 * * @param WP_REST_Response $response The response object. - * @param object $item The original term object. + * @param WP_Term $item The original term object. * @param WP_REST_Request $request Request used to generate the response. */ return apply_filters( "rest_prepare_{$this->taxonomy}", $response, $item, $request ); @@ -791,7 +848,7 @@ * * @since 4.7.0 * - * @param object $term Term object. + * @param WP_Term $term Term object. * @return array Links for the given term. */ protected function prepare_links( $term ) { @@ -855,6 +912,10 @@ * @return array Item schema data. */ public function get_item_schema() { + if ( $this->schema ) { + return $this->add_additional_fields_schema( $this->schema ); + } + $schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => 'post_tag' === $this->taxonomy ? 'tag' : $this->taxonomy, @@ -923,7 +984,9 @@ $schema['properties']['meta'] = $this->meta->get_field_schema(); - return $this->add_additional_fields_schema( $schema ); + $this->schema = $schema; + + return $this->add_additional_fields_schema( $this->schema ); } /**