[ Index ] |
PHP Cross Reference of WordPress Trunk (Updated Daily) |
[Summary view] [Print] [Text view]
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 */ 17 class WP_REST_Taxonomies_Controller extends WP_REST_Controller { 18 19 /** 20 * Constructor. 21 * 22 * @since 4.7.0 23 */ 24 public function __construct() { 25 $this->namespace = 'wp/v2'; 26 $this->rest_base = 'taxonomies'; 27 } 28 29 /** 30 * Registers the routes for taxonomies. 31 * 32 * @since 4.7.0 33 * 34 * @see register_rest_route() 35 */ 36 public function register_routes() { 37 38 register_rest_route( 39 $this->namespace, 40 '/' . $this->rest_base, 41 array( 42 array( 43 'methods' => WP_REST_Server::READABLE, 44 'callback' => array( $this, 'get_items' ), 45 'permission_callback' => array( $this, 'get_items_permissions_check' ), 46 'args' => $this->get_collection_params(), 47 ), 48 'schema' => array( $this, 'get_public_item_schema' ), 49 ) 50 ); 51 52 register_rest_route( 53 $this->namespace, 54 '/' . $this->rest_base . '/(?P<taxonomy>[\w-]+)', 55 array( 56 'args' => array( 57 'taxonomy' => array( 58 'description' => __( 'An alphanumeric identifier for the taxonomy.' ), 59 'type' => 'string', 60 ), 61 ), 62 array( 63 'methods' => WP_REST_Server::READABLE, 64 'callback' => array( $this, 'get_item' ), 65 'permission_callback' => array( $this, 'get_item_permissions_check' ), 66 'args' => array( 67 'context' => $this->get_context_param( array( 'default' => 'view' ) ), 68 ), 69 ), 70 'schema' => array( $this, 'get_public_item_schema' ), 71 ) 72 ); 73 } 74 75 /** 76 * Checks whether a given request has permission to read taxonomies. 77 * 78 * @since 4.7.0 79 * 80 * @param WP_REST_Request $request Full details about the request. 81 * @return true|WP_Error True if the request has read access, WP_Error object otherwise. 82 */ 83 public function get_items_permissions_check( $request ) { 84 if ( 'edit' === $request['context'] ) { 85 if ( ! empty( $request['type'] ) ) { 86 $taxonomies = get_object_taxonomies( $request['type'], 'objects' ); 87 } else { 88 $taxonomies = get_taxonomies( '', 'objects' ); 89 } 90 91 foreach ( $taxonomies as $taxonomy ) { 92 if ( ! empty( $taxonomy->show_in_rest ) && current_user_can( $taxonomy->cap->assign_terms ) ) { 93 return true; 94 } 95 } 96 97 return new WP_Error( 98 'rest_cannot_view', 99 __( 'Sorry, you are not allowed to manage terms in this taxonomy.' ), 100 array( 'status' => rest_authorization_required_code() ) 101 ); 102 } 103 104 return true; 105 } 106 107 /** 108 * Retrieves all public taxonomies. 109 * 110 * @since 4.7.0 111 * 112 * @param WP_REST_Request $request Full details about the request. 113 * @return WP_REST_Response Response object on success, or WP_Error object on failure. 114 */ 115 public function get_items( $request ) { 116 117 // Retrieve the list of registered collection query parameters. 118 $registered = $this->get_collection_params(); 119 120 if ( isset( $registered['type'] ) && ! empty( $request['type'] ) ) { 121 $taxonomies = get_object_taxonomies( $request['type'], 'objects' ); 122 } else { 123 $taxonomies = get_taxonomies( '', 'objects' ); 124 } 125 126 $data = array(); 127 128 foreach ( $taxonomies as $tax_type => $value ) { 129 if ( empty( $value->show_in_rest ) || ( 'edit' === $request['context'] && ! current_user_can( $value->cap->assign_terms ) ) ) { 130 continue; 131 } 132 133 $tax = $this->prepare_item_for_response( $value, $request ); 134 $tax = $this->prepare_response_for_collection( $tax ); 135 $data[ $tax_type ] = $tax; 136 } 137 138 if ( empty( $data ) ) { 139 // Response should still be returned as a JSON object when it is empty. 140 $data = (object) $data; 141 } 142 143 return rest_ensure_response( $data ); 144 } 145 146 /** 147 * Checks if a given request has access to a taxonomy. 148 * 149 * @since 4.7.0 150 * 151 * @param WP_REST_Request $request Full details about the request. 152 * @return bool|WP_Error True if the request has read access for the item, otherwise false or WP_Error object. 153 */ 154 public function get_item_permissions_check( $request ) { 155 156 $tax_obj = get_taxonomy( $request['taxonomy'] ); 157 158 if ( $tax_obj ) { 159 if ( empty( $tax_obj->show_in_rest ) ) { 160 return false; 161 } 162 163 if ( 'edit' === $request['context'] && ! current_user_can( $tax_obj->cap->assign_terms ) ) { 164 return new WP_Error( 165 'rest_forbidden_context', 166 __( 'Sorry, you are not allowed to manage terms in this taxonomy.' ), 167 array( 'status' => rest_authorization_required_code() ) 168 ); 169 } 170 } 171 172 return true; 173 } 174 175 /** 176 * Retrieves a specific taxonomy. 177 * 178 * @since 4.7.0 179 * 180 * @param WP_REST_Request $request Full details about the request. 181 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. 182 */ 183 public function get_item( $request ) { 184 $tax_obj = get_taxonomy( $request['taxonomy'] ); 185 186 if ( empty( $tax_obj ) ) { 187 return new WP_Error( 188 'rest_taxonomy_invalid', 189 __( 'Invalid taxonomy.' ), 190 array( 'status' => 404 ) 191 ); 192 } 193 194 $data = $this->prepare_item_for_response( $tax_obj, $request ); 195 196 return rest_ensure_response( $data ); 197 } 198 199 /** 200 * Prepares a taxonomy object for serialization. 201 * 202 * @since 4.7.0 203 * @since 5.9.0 Renamed `$taxonomy` to `$item` to match parent class for PHP 8 named parameter support. 204 * 205 * @param WP_Taxonomy $item Taxonomy data. 206 * @param WP_REST_Request $request Full details about the request. 207 * @return WP_REST_Response Response object. 208 */ 209 public function prepare_item_for_response( $item, $request ) { 210 // Restores the more descriptive, specific name for use within this method. 211 $taxonomy = $item; 212 213 $base = ! empty( $taxonomy->rest_base ) ? $taxonomy->rest_base : $taxonomy->name; 214 215 $fields = $this->get_fields_for_response( $request ); 216 $data = array(); 217 218 if ( in_array( 'name', $fields, true ) ) { 219 $data['name'] = $taxonomy->label; 220 } 221 222 if ( in_array( 'slug', $fields, true ) ) { 223 $data['slug'] = $taxonomy->name; 224 } 225 226 if ( in_array( 'capabilities', $fields, true ) ) { 227 $data['capabilities'] = $taxonomy->cap; 228 } 229 230 if ( in_array( 'description', $fields, true ) ) { 231 $data['description'] = $taxonomy->description; 232 } 233 234 if ( in_array( 'labels', $fields, true ) ) { 235 $data['labels'] = $taxonomy->labels; 236 } 237 238 if ( in_array( 'types', $fields, true ) ) { 239 $data['types'] = array_values( $taxonomy->object_type ); 240 } 241 242 if ( in_array( 'show_cloud', $fields, true ) ) { 243 $data['show_cloud'] = $taxonomy->show_tagcloud; 244 } 245 246 if ( in_array( 'hierarchical', $fields, true ) ) { 247 $data['hierarchical'] = $taxonomy->hierarchical; 248 } 249 250 if ( in_array( 'rest_base', $fields, true ) ) { 251 $data['rest_base'] = $base; 252 } 253 254 if ( in_array( 'rest_namespace', $fields, true ) ) { 255 $data['rest_namespace'] = $taxonomy->rest_namespace; 256 } 257 258 if ( in_array( 'visibility', $fields, true ) ) { 259 $data['visibility'] = array( 260 'public' => (bool) $taxonomy->public, 261 'publicly_queryable' => (bool) $taxonomy->publicly_queryable, 262 'show_admin_column' => (bool) $taxonomy->show_admin_column, 263 'show_in_nav_menus' => (bool) $taxonomy->show_in_nav_menus, 264 'show_in_quick_edit' => (bool) $taxonomy->show_in_quick_edit, 265 'show_ui' => (bool) $taxonomy->show_ui, 266 ); 267 } 268 269 $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; 270 $data = $this->add_additional_fields_to_object( $data, $request ); 271 $data = $this->filter_response_by_context( $data, $context ); 272 273 // Wrap the data in a response object. 274 $response = rest_ensure_response( $data ); 275 276 if ( rest_is_field_included( '_links', $fields ) || rest_is_field_included( '_embedded', $fields ) ) { 277 $response->add_links( $this->prepare_links( $taxonomy ) ); 278 } 279 280 /** 281 * Filters a taxonomy returned from the REST API. 282 * 283 * Allows modification of the taxonomy data right before it is returned. 284 * 285 * @since 4.7.0 286 * 287 * @param WP_REST_Response $response The response object. 288 * @param WP_Taxonomy $item The original taxonomy object. 289 * @param WP_REST_Request $request Request used to generate the response. 290 */ 291 return apply_filters( 'rest_prepare_taxonomy', $response, $taxonomy, $request ); 292 } 293 294 /** 295 * Prepares links for the request. 296 * 297 * @since 6.1.0 298 * 299 * @param WP_Taxonomy $taxonomy The taxonomy. 300 * @return array Links for the given taxonomy. 301 */ 302 protected function prepare_links( $taxonomy ) { 303 return array( 304 'collection' => array( 305 'href' => rest_url( sprintf( '%s/%s', $this->namespace, $this->rest_base ) ), 306 ), 307 'https://api.w.org/items' => array( 308 'href' => rest_url( rest_get_route_for_taxonomy_items( $taxonomy->name ) ), 309 ), 310 ); 311 } 312 313 /** 314 * Retrieves the taxonomy's schema, conforming to JSON Schema. 315 * 316 * @since 4.7.0 317 * @since 5.0.0 The `visibility` property was added. 318 * @since 5.9.0 The `rest_namespace` property was added. 319 * 320 * @return array Item schema data. 321 */ 322 public function get_item_schema() { 323 if ( $this->schema ) { 324 return $this->add_additional_fields_schema( $this->schema ); 325 } 326 327 $schema = array( 328 '$schema' => 'http://json-schema.org/draft-04/schema#', 329 'title' => 'taxonomy', 330 'type' => 'object', 331 'properties' => array( 332 'capabilities' => array( 333 'description' => __( 'All capabilities used by the taxonomy.' ), 334 'type' => 'object', 335 'context' => array( 'edit' ), 336 'readonly' => true, 337 ), 338 'description' => array( 339 'description' => __( 'A human-readable description of the taxonomy.' ), 340 'type' => 'string', 341 'context' => array( 'view', 'edit' ), 342 'readonly' => true, 343 ), 344 'hierarchical' => array( 345 'description' => __( 'Whether or not the taxonomy should have children.' ), 346 'type' => 'boolean', 347 'context' => array( 'view', 'edit' ), 348 'readonly' => true, 349 ), 350 'labels' => array( 351 'description' => __( 'Human-readable labels for the taxonomy for various contexts.' ), 352 'type' => 'object', 353 'context' => array( 'edit' ), 354 'readonly' => true, 355 ), 356 'name' => array( 357 'description' => __( 'The title for the taxonomy.' ), 358 'type' => 'string', 359 'context' => array( 'view', 'edit', 'embed' ), 360 'readonly' => true, 361 ), 362 'slug' => array( 363 'description' => __( 'An alphanumeric identifier for the taxonomy.' ), 364 'type' => 'string', 365 'context' => array( 'view', 'edit', 'embed' ), 366 'readonly' => true, 367 ), 368 'show_cloud' => array( 369 'description' => __( 'Whether or not the term cloud should be displayed.' ), 370 'type' => 'boolean', 371 'context' => array( 'edit' ), 372 'readonly' => true, 373 ), 374 'types' => array( 375 'description' => __( 'Types associated with the taxonomy.' ), 376 'type' => 'array', 377 'items' => array( 378 'type' => 'string', 379 ), 380 'context' => array( 'view', 'edit' ), 381 'readonly' => true, 382 ), 383 'rest_base' => array( 384 'description' => __( 'REST base route for the taxonomy.' ), 385 'type' => 'string', 386 'context' => array( 'view', 'edit', 'embed' ), 387 'readonly' => true, 388 ), 389 'rest_namespace' => array( 390 'description' => __( 'REST namespace route for the taxonomy.' ), 391 'type' => 'string', 392 'context' => array( 'view', 'edit', 'embed' ), 393 'readonly' => true, 394 ), 395 'visibility' => array( 396 'description' => __( 'The visibility settings for the taxonomy.' ), 397 'type' => 'object', 398 'context' => array( 'edit' ), 399 'readonly' => true, 400 'properties' => array( 401 'public' => array( 402 'description' => __( 'Whether a taxonomy is intended for use publicly either via the admin interface or by front-end users.' ), 403 'type' => 'boolean', 404 ), 405 'publicly_queryable' => array( 406 'description' => __( 'Whether the taxonomy is publicly queryable.' ), 407 'type' => 'boolean', 408 ), 409 'show_ui' => array( 410 'description' => __( 'Whether to generate a default UI for managing this taxonomy.' ), 411 'type' => 'boolean', 412 ), 413 'show_admin_column' => array( 414 'description' => __( 'Whether to allow automatic creation of taxonomy columns on associated post-types table.' ), 415 'type' => 'boolean', 416 ), 417 'show_in_nav_menus' => array( 418 'description' => __( 'Whether to make the taxonomy available for selection in navigation menus.' ), 419 'type' => 'boolean', 420 ), 421 'show_in_quick_edit' => array( 422 'description' => __( 'Whether to show the taxonomy in the quick/bulk edit panel.' ), 423 'type' => 'boolean', 424 ), 425 426 ), 427 ), 428 ), 429 ); 430 431 $this->schema = $schema; 432 433 return $this->add_additional_fields_schema( $this->schema ); 434 } 435 436 /** 437 * Retrieves the query params for collections. 438 * 439 * @since 4.7.0 440 * 441 * @return array Collection parameters. 442 */ 443 public function get_collection_params() { 444 $new_params = array(); 445 $new_params['context'] = $this->get_context_param( array( 'default' => 'view' ) ); 446 $new_params['type'] = array( 447 'description' => __( 'Limit results to taxonomies associated with a specific post type.' ), 448 'type' => 'string', 449 ); 450 return $new_params; 451 } 452 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated : Tue Dec 17 08:20:01 2024 | Cross-referenced by PHPXref |