Make WordPress Core

Ticket #51417: class-wp-rest-taxonomies-controller.php

File class-wp-rest-taxonomies-controller.php, 9.7 KB (added by paypressprinter, 4 years ago)
Line 
1<?php
2/**
3 * REST API: WP_REST_Taxonomies_Controller class
4 *
5 * @package WordPress
6 * @subpackage REST_API
7 * @since 4.7.0
8 */
9
10/**
11 * Core class used to manage taxonomies via the REST API.
12 *
13 * @since 4.7.0
14 *
15 * @see WP_REST_Controller
16 */
17class WP_REST_Taxonomies_Controller extends WP_REST_Controller {
18
19        /**
20         * Constructor.
21         *
22         * @since 4.7.0
23         * @access public
24         */
25        public function __construct() {
26                $this->namespace = 'wp/v2';
27                $this->rest_base = 'taxonomies';
28        }
29
30        /**
31         * Registers the routes for the objects of the controller.
32         *
33         * @since 4.7.0
34         * @access public
35         *
36         * @see register_rest_route()
37         */
38        public function register_routes() {
39
40                register_rest_route( $this->namespace, '/' . $this->rest_base, array(
41                        array(
42                                'methods'         => WP_REST_Server::READABLE,
43                                'callback'        => array( $this, 'get_items' ),
44                                'permission_callback' => array( $this, 'get_items_permissions_check' ),
45                                'args'            => $this->get_collection_params(),
46                        ),
47                        'schema' => array( $this, 'get_public_item_schema' ),
48                ) );
49
50                register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<taxonomy>[\w-]+)', array(
51                        array(
52                                'methods'         => WP_REST_Server::READABLE,
53                                'callback'        => array( $this, 'get_item' ),
54                                'permission_callback' => array( $this, 'get_item_permissions_check' ),
55                                'args'            => array(
56                                        'context'     => $this->get_context_param( array( 'default' => 'view' ) ),
57                                ),
58                        ),
59                        'schema' => array( $this, 'get_public_item_schema' ),
60                ) );
61        }
62
63        /**
64         * Checks whether a given request has permission to read taxonomies.
65         *
66         * @since 4.7.0
67         * @access public
68         *
69         * @param WP_REST_Request $request Full details about the request.
70         * @return true|WP_Error True if the request has read access, WP_Error object otherwise.
71         */
72        public function get_items_permissions_check( $request ) {
73                if ( 'edit' === $request['context'] ) {
74                        if ( ! empty( $request['type'] ) ) {
75                                $taxonomies = get_object_taxonomies( $request['type'], 'objects' );
76                        } else {
77                                $taxonomies = get_taxonomies( '', 'objects' );
78                        }
79                        foreach ( $taxonomies as $taxonomy ) {
80                                if ( ! empty( $taxonomy->show_in_rest ) && current_user_can( $taxonomy->cap->manage_terms ) ) {
81                                        return true;
82                                }
83                        }
84                        return new WP_Error( 'rest_cannot_view', __( 'Sorry, you are not allowed to manage terms in this taxonomy.' ), array( 'status' => rest_authorization_required_code() ) );
85                }
86                return true;
87        }
88
89        /**
90         * Retrieves all public taxonomies.
91         *
92         * @since 4.7.0
93         * @access public
94         *
95         * @param WP_REST_Request $request Full details about the request.
96         * @return WP_REST_Response Response object on success, or WP_Error object on failure.
97         */
98        public function get_items( $request ) {
99
100                // Retrieve the list of registered collection query parameters.
101                $registered = $this->get_collection_params();
102
103                if ( isset( $registered['type'] ) && ! empty( $request['type'] ) ) {
104                        $taxonomies = get_object_taxonomies( $request['type'], 'objects' );
105                } else {
106                        $taxonomies = get_taxonomies( '', 'objects' );
107                }
108                $data = array();
109                foreach ( $taxonomies as $tax_type => $value ) {
110                        if ( empty( $value->show_in_rest ) || ( 'edit' === $request['context'] && ! current_user_can( $value->cap->manage_terms ) ) ) {
111                                continue;
112                        }
113                        $tax = $this->prepare_item_for_response( $value, $request );
114                        $tax = $this->prepare_response_for_collection( $tax );
115                        $data[ $tax_type ] = $tax;
116                }
117
118                if ( empty( $data ) ) {
119                        // Response should still be returned as a JSON object when it is empty.
120                        $data = (object) $data;
121                }
122
123                return rest_ensure_response( $data );
124        }
125
126        /**
127         * Checks if a given request has access to a taxonomy.
128         *
129         * @since 4.7.0
130         * @access public
131         *
132         * @param  WP_REST_Request $request Full details about the request.
133         * @return true|WP_Error True if the request has read access for the item, otherwise false or WP_Error object.
134         */
135        public function get_item_permissions_check( $request ) {
136
137                $tax_obj = get_taxonomy( $request['taxonomy'] );
138
139                if ( $tax_obj ) {
140                        if ( empty( $tax_obj->show_in_rest ) ) {
141                                return false;
142                        }
143                        if ( 'edit' === $request['context'] && ! current_user_can( $tax_obj->cap->manage_terms ) ) {
144                                return new WP_Error( 'rest_forbidden_context', __( 'Sorry, you are not allowed to manage terms in this taxonomy.' ), array( 'status' => rest_authorization_required_code() ) );
145                        }
146                }
147
148                return true;
149        }
150
151        /**
152         * Retrieves a specific taxonomy.
153         *
154         * @since 4.7.0
155         * @access public
156         *
157         * @param WP_REST_Request $request Full details about the request.
158         * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
159         */
160        public function get_item( $request ) {
161                $tax_obj = get_taxonomy( $request['taxonomy'] );
162                if ( empty( $tax_obj ) ) {
163                        return new WP_Error( 'rest_taxonomy_invalid', __( 'Invalid taxonomy.' ), array( 'status' => 404 ) );
164                }
165                $data = $this->prepare_item_for_response( $tax_obj, $request );
166                return rest_ensure_response( $data );
167        }
168
169        /**
170         * Prepares a taxonomy object for serialization.
171         *
172         * @since 4.7.0
173         * @access public
174         *
175         * @param stdClass        $taxonomy Taxonomy data.
176         * @param WP_REST_Request $request  Full details about the request.
177         * @return WP_REST_Response Response object.
178         */
179        public function prepare_item_for_response( $taxonomy, $request ) {
180                $base = ! empty( $taxonomy->rest_base ) ? $taxonomy->rest_base : $taxonomy->name;
181                $data = array(
182                        'name'         => $taxonomy->label,
183                        'slug'         => $taxonomy->name,
184                        'capabilities' => $taxonomy->cap,
185                        'description'  => $taxonomy->description,
186                        'labels'       => $taxonomy->labels,
187                        'types'        => $taxonomy->object_type,
188                        'show_cloud'   => $taxonomy->show_tagcloud,
189                        'hierarchical' => $taxonomy->hierarchical,
190                        'rest_base'    => $base,
191                );
192
193                $context = ! empty( $request['context'] ) ? $request['context'] : 'view';
194                $data = $this->add_additional_fields_to_object( $data, $request );
195                $data = $this->filter_response_by_context( $data, $context );
196
197                // Wrap the data in a response object.
198                $response = rest_ensure_response( $data );
199
200                $response->add_links( array(
201                        'collection'                => array(
202                                'href'                  => rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ),
203                        ),
204                        'https://api.w.org/items'   => array(
205                                'href'                  => rest_url( sprintf( 'wp/v2/%s', $base ) ),
206                        ),
207                ) );
208
209                /**
210                 * Filters a taxonomy returned from the REST API.
211                 *
212                 * Allows modification of the taxonomy data right before it is returned.
213                 *
214                 * @since 4.7.0
215                 *
216                 * @param WP_REST_Response $response The response object.
217                 * @param object           $item     The original taxonomy object.
218                 * @param WP_REST_Request  $request  Request used to generate the response.
219                 */
220                return apply_filters( 'rest_prepare_taxonomy', $response, $taxonomy, $request );
221        }
222
223        /**
224         * Retrieves the taxonomy's schema, conforming to JSON Schema.
225         *
226         * @since 4.7.0
227         * @access public
228         *
229         * @return array Item schema data.
230         */
231        public function get_item_schema() {
232                $schema = array(
233                        '$schema'              => 'http://json-schema.org/schema#',
234                        'title'                => 'taxonomy',
235                        'type'                 => 'object',
236                        'properties'           => array(
237                                'capabilities'     => array(
238                                        'description'  => __( 'All capabilities used by the taxonomy.' ),
239                                        'type'         => 'object',
240                                        'context'      => array( 'edit' ),
241                                        'readonly'     => true,
242                                ),
243                                'description'      => array(
244                                        'description'  => __( 'A human-readable description of the taxonomy.' ),
245                                        'type'         => 'string',
246                                        'context'      => array( 'view', 'edit' ),
247                                        'readonly'     => true,
248                                ),
249                                'hierarchical'     => array(
250                                        'description'  => __( 'Whether or not the taxonomy should have children.' ),
251                                        'type'         => 'boolean',
252                                        'context'      => array( 'view', 'edit' ),
253                                        'readonly'     => true,
254                                ),
255                                'labels'           => array(
256                                        'description'  => __( 'Human-readable labels for the taxonomy for various contexts.' ),
257                                        'type'         => 'object',
258                                        'context'      => array( 'edit' ),
259                                        'readonly'     => true,
260                                ),
261                                'name'             => array(
262                                        'description'  => __( 'The title for the taxonomy.' ),
263                                        'type'         => 'string',
264                                        'context'      => array( 'view', 'edit', 'embed' ),
265                                        'readonly'     => true,
266                                ),
267                                'slug'             => array(
268                                        'description'  => __( 'An alphanumeric identifier for the taxonomy.' ),
269                                        'type'         => 'string',
270                                        'context'      => array( 'view', 'edit', 'embed' ),
271                                        'readonly'     => true,
272                                ),
273                                'show_cloud'       => array(
274                                        'description'  => __( 'Whether or not the term cloud should be displayed.' ),
275                                        'type'         => 'boolean',
276                                        'context'      => array( 'edit' ),
277                                        'readonly'     => true,
278                                ),
279                                'types'            => array(
280                                        'description'  => __( 'Types associated with the taxonomy.' ),
281                                        'type'         => 'array',
282                                        'items'        => array(
283                                                'type' => 'string',
284                                        ),
285                                        'context'      => array( 'view', 'edit' ),
286                                        'readonly'     => true,
287                                ),
288                                'rest_base'            => array(
289                                        'description'  => __( 'REST base route for the taxonomy.' ),
290                                        'type'         => 'string',
291                                        'context'      => array( 'view', 'edit', 'embed' ),
292                                        'readonly'     => true,
293                                ),
294                        ),
295                );
296                return $this->add_additional_fields_schema( $schema );
297        }
298
299        /**
300         * Retrieves the query params for collections.
301         *
302         * @since 4.7.0
303         * @access public
304         *
305         * @return array Collection parameters.
306         */
307        public function get_collection_params() {
308                $new_params = array();
309                $new_params['context'] = $this->get_context_param( array( 'default' => 'view' ) );
310                $new_params['type'] = array(
311                        'description'  => __( 'Limit results to taxonomies associated with a specific post type.' ),
312                        'type'         => 'string',
313                );
314                return $new_params;
315        }
316
317}