Changeset 39011 for trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php
- Timestamp:
- 10/30/2016 05:39:09 AM (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php
r38832 r39011 1 1 <?php 2 2 /** 3 * REST API: WP_REST_Attachments_Controller class 4 * 5 * @package WordPress 6 * @subpackage REST_API 7 * @since 4.7.0 8 */ 9 10 /** 11 * Core controller used to access attachments via the REST API. 12 * 13 * @since 4.7.0 14 * 15 * @see WP_REST_Posts_Controller 16 */ 3 17 class WP_REST_Attachments_Controller extends WP_REST_Posts_Controller { 4 18 5 19 /** 6 * Determine the allowed query_vars for a get_items() response and 7 * prepare for WP_Query. 8 * 9 * @param array $prepared_args Optional. Array of prepared arguments. 20 * Determines the allowed query_vars for a get_items() response and 21 * prepares for WP_Query. 22 * 23 * @since 4.7.0 24 * @access protected 25 * 26 * @param array $prepared_args Optional. Array of prepared arguments. Default empty array. 10 27 * @param WP_REST_Request $request Optional. Request to prepare items for. 11 28 * @return array Array of query arguments. … … 13 30 protected function prepare_items_query( $prepared_args = array(), $request = null ) { 14 31 $query_args = parent::prepare_items_query( $prepared_args, $request ); 32 15 33 if ( empty( $query_args['post_status'] ) || ! in_array( $query_args['post_status'], array( 'inherit', 'private', 'trash' ), true ) ) { 16 34 $query_args['post_status'] = 'inherit'; 17 35 } 36 18 37 $media_types = $this->get_media_types(); 38 19 39 if ( ! empty( $request['media_type'] ) && isset( $media_types[ $request['media_type'] ] ) ) { 20 40 $query_args['post_mime_type'] = $media_types[ $request['media_type'] ]; 21 41 } 42 22 43 if ( ! empty( $request['mime_type'] ) ) { 23 44 $parts = explode( '/', $request['mime_type'] ); … … 26 47 } 27 48 } 49 28 50 return $query_args; 29 51 } 30 52 31 53 /** 32 * Check if a given request has access to create an attachment. 33 * 34 * @param WP_REST_Request $request Full details about the request. 54 * Checks if a given request has access to create an attachment. 55 * 56 * @since 4.7.0 57 * @access public 58 * 59 * @param WP_REST_Request $request Full details about the request. 35 60 * @return WP_Error|true Boolean true if the attachment may be created, or a WP_Error if not. 36 61 */ 37 62 public function create_item_permissions_check( $request ) { 38 63 $ret = parent::create_item_permissions_check( $request ); 64 39 65 if ( ! $ret || is_wp_error( $ret ) ) { 40 66 return $ret; … … 49 75 $parent = $this->get_post( (int) $request['post'] ); 50 76 $post_parent_type = get_post_type_object( $parent->post_type ); 77 51 78 if ( ! current_user_can( $post_parent_type->cap->edit_post, $request['post'] ) ) { 52 79 return new WP_Error( 'rest_cannot_edit', __( 'Sorry, you are not allowed to upload media to this resource.' ), array( 'status' => rest_authorization_required_code() ) ); … … 58 85 59 86 /** 60 * Create a single attachment. 87 * Creates a single attachment. 88 * 89 * @since 4.7.0 90 * @access public 61 91 * 62 92 * @param WP_REST_Request $request Full details about the request. … … 69 99 } 70 100 71 // Get the file via $_FILES or raw data 101 // Get the file via $_FILES or raw data. 72 102 $files = $request->get_file_params(); 73 103 $headers = $request->get_headers(); 104 74 105 if ( ! empty( $files ) ) { 75 106 $file = $this->upload_from_file( $files, $headers ); … … 91 122 92 123 // use image exif/iptc data for title and caption defaults if possible 93 // @codingStandardsIgnoreStart94 124 $image_meta = @wp_read_image_metadata( $file ); 95 // @codingStandardsIgnoreEnd 125 96 126 if ( ! empty( $image_meta ) ) { 97 127 if ( empty( $request['title'] ) && trim( $image_meta['title'] ) && ! is_numeric( sanitize_title( $image_meta['title'] ) ) ) { … … 114 144 115 145 $id = wp_insert_post( $attachment, true ); 146 116 147 if ( is_wp_error( $id ) ) { 117 148 if ( 'db_update_error' === $id->get_error_code() ) { … … 122 153 return $id; 123 154 } 155 124 156 $attachment = $this->get_post( $id ); 125 157 … … 134 166 135 167 $fields_update = $this->update_additional_fields_for_object( $attachment, $request ); 168 136 169 if ( is_wp_error( $fields_update ) ) { 137 170 return $fields_update; … … 147 180 * Fires after a single attachment is created or updated via the REST API. 148 181 * 182 * @since 4.7.0 183 * 149 184 * @param object $attachment Inserted attachment. 150 185 * @param WP_REST_Request $request The request sent to the API. 151 * @param bool ean$creating True when creating an attachment, false when updating.186 * @param bool $creating True when creating an attachment, false when updating. 152 187 */ 153 188 do_action( 'rest_insert_attachment', $attachment, $request, true ); 154 189 155 190 return $response; 156 157 } 158 159 /** 160 * Update a single post. 191 } 192 193 /** 194 * Updates a single attachment. 195 * 196 * @since 4.7.0 197 * @access public 161 198 * 162 199 * @param WP_REST_Request $request Full details about the request. … … 167 204 return new WP_Error( 'rest_invalid_param', __( 'Invalid parent type.' ), array( 'status' => 400 ) ); 168 205 } 206 169 207 $response = parent::update_item( $request ); 208 170 209 if ( is_wp_error( $response ) ) { 171 210 return $response; … … 182 221 183 222 $fields_update = $this->update_additional_fields_for_object( $attachment, $request ); 223 184 224 if ( is_wp_error( $fields_update ) ) { 185 225 return $fields_update; … … 190 230 $response = rest_ensure_response( $response ); 191 231 192 /* This action is documented in lib/endpoints/class-wp-rest-attachments-controller.php */232 /* This action is documented in wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php */ 193 233 do_action( 'rest_insert_attachment', $data, $request, false ); 194 234 … … 197 237 198 238 /** 199 * Prepare a single attachment for create or update. 239 * Prepares a single attachment for create or update. 240 * 241 * @since 4.7.0 242 * @access public 200 243 * 201 244 * @param WP_REST_Request $request Request object. … … 221 264 222 265 /** 223 * Prepare a single attachment output for response. 224 * 225 * @param WP_Post $post Post object. 266 * Prepares a single attachment output for response. 267 * 268 * @since 4.7.0 269 * @access public 270 * 271 * @param WP_Post $post Attachment object. 226 272 * @param WP_REST_Request $request Request object. 227 273 * @return WP_REST_Response Response object. … … 262 308 263 309 $full_src = wp_get_attachment_image_src( $post->ID, 'full' ); 310 264 311 if ( ! empty( $full_src ) ) { 265 312 $data['media_details']['sizes']['full'] = array( 266 'file' 267 'width' 268 'height' 269 'mime_type' 270 'source_url' 271 313 'file' => wp_basename( $full_src[0] ), 314 'width' => $full_src[1], 315 'height' => $full_src[2], 316 'mime_type' => $post->post_mime_type, 317 'source_url' => $full_src[0], 318 ); 272 319 } 273 320 } else { … … 285 332 286 333 /** 287 * Filter an attachment returned from theAPI.334 * Filters an attachment returned from the REST API. 288 335 * 289 336 * Allows modification of the attachment right before it is returned. 290 337 * 291 * @param WP_REST_Response $response The response object. 292 * @param WP_Post $post The original attachment post. 293 * @param WP_REST_Request $request Request used to generate the response. 338 * @since 4.7.0 339 * 340 * @param WP_REST_Response $response The response object. 341 * @param WP_Post $post The original attachment post. 342 * @param WP_REST_Request $request Request used to generate the response. 294 343 */ 295 344 return apply_filters( 'rest_prepare_attachment', $response, $post, $request ); … … 297 346 298 347 /** 299 * Get the Attachment's schema, conforming to JSON Schema. 348 * Retrieves the attachment's schema, conforming to JSON Schema. 349 * 350 * @since 4.7.0 351 * @access public 300 352 * 301 353 * @return array Item schema as an array. … … 313 365 ), 314 366 ); 367 315 368 $schema['properties']['caption'] = array( 316 369 'description' => __( 'The caption for the resource.' ), … … 321 374 ), 322 375 ); 376 323 377 $schema['properties']['description'] = array( 324 378 'description' => __( 'The description for the resource.' ), … … 329 383 ), 330 384 ); 385 331 386 $schema['properties']['media_type'] = array( 332 387 'description' => __( 'Type of resource.' ), … … 336 391 'readonly' => true, 337 392 ); 393 338 394 $schema['properties']['mime_type'] = array( 339 395 'description' => __( 'MIME type of resource.' ), … … 342 398 'readonly' => true, 343 399 ); 400 344 401 $schema['properties']['media_details'] = array( 345 402 'description' => __( 'Details about the resource file, specific to its type.' ), … … 348 405 'readonly' => true, 349 406 ); 407 350 408 $schema['properties']['post'] = array( 351 409 'description' => __( 'The id for the associated post of the resource.' ), … … 353 411 'context' => array( 'view', 'edit' ), 354 412 ); 413 355 414 $schema['properties']['source_url'] = array( 356 415 'description' => __( 'URL to the original resource file.' ), … … 360 419 'readonly' => true, 361 420 ); 421 362 422 return $schema; 363 423 } 364 424 365 425 /** 366 * Handle an upload via raw POST data. 426 * Handles an upload via raw POST data. 427 * 428 * @since 4.7.0 429 * @access protected 367 430 * 368 431 * @param array $data Supplied file data. 369 432 * @param array $headers HTTP headers from the request. 370 * @return array|WP_Error Data from {@see wp_handle_sideload()}.433 * @return array|WP_Error Data from wp_handle_sideload(). 371 434 */ 372 435 protected function upload_from_data( $data, $headers ) { … … 391 454 if ( ! empty( $headers['content_md5'] ) ) { 392 455 $content_md5 = array_shift( $headers['content_md5'] ); 393 $expected = trim( $content_md5 );394 $actual = md5( $data );456 $expected = trim( $content_md5 ); 457 $actual = md5( $data ); 395 458 396 459 if ( $expected !== $actual ) { … … 424 487 'type' => $type, 425 488 ); 489 426 490 $overrides = array( 427 491 'test_form' => false, 428 492 ); 493 429 494 $sideloaded = wp_handle_sideload( $file_data, $overrides ); 430 495 431 496 if ( isset( $sideloaded['error'] ) ) { 432 // @codingStandardsIgnoreStart433 497 @unlink( $tmpfname ); 434 // @codingStandardsIgnoreEnd 498 435 499 return new WP_Error( 'rest_upload_sideload_error', $sideloaded['error'], array( 'status' => 500 ) ); 436 500 } … … 440 504 441 505 /** 442 * Parse filename from a Content-Disposition header value.506 * Parses filename from a Content-Disposition header value. 443 507 * 444 508 * As per RFC6266: … … 460 524 * ext-token = <the characters in token, followed by "*"> 461 525 * 462 * @see http://tools.ietf.org/html/rfc2388 463 * @see http://tools.ietf.org/html/rfc6266 526 * @since 4.7.0 527 * @access public 528 * 529 * @link http://tools.ietf.org/html/rfc2388 530 * @link http://tools.ietf.org/html/rfc6266 464 531 * 465 532 * @param string[] $disposition_header List of Content-Disposition header values. … … 478 545 479 546 list( $type, $attr_parts ) = explode( ';', $value, 2 ); 547 480 548 $attr_parts = explode( ';', $attr_parts ); 481 549 $attributes = array(); 550 482 551 foreach ( $attr_parts as $part ) { 483 552 if ( strpos( $part, '=' ) === false ) { … … 486 555 487 556 list( $key, $value ) = explode( '=', $part, 2 ); 557 488 558 $attributes[ trim( $key ) ] = trim( $value ); 489 559 } … … 505 575 506 576 /** 507 * Get the query params for collections of attachments. 577 * Retrieves the query params for collections of attachments. 578 * 579 * @since 4.7.0 580 * @access public 508 581 * 509 582 * @return array Query parameters for the attachment collection as an array. … … 514 587 $params['status']['enum'] = array( 'inherit', 'private', 'trash' ); 515 588 $media_types = $this->get_media_types(); 589 516 590 $params['media_type'] = array( 517 'default' => null, 518 'description' => __( 'Limit result set to attachments of a particular media type.' ), 519 'type' => 'string', 520 'enum' => array_keys( $media_types ), 521 'validate_callback' => 'rest_validate_request_arg', 522 ); 591 'default' => null, 592 'description' => __( 'Limit result set to attachments of a particular media type.' ), 593 'type' => 'string', 594 'enum' => array_keys( $media_types ), 595 'validate_callback' => 'rest_validate_request_arg', 596 ); 597 523 598 $params['mime_type'] = array( 524 'default' => null, 525 'description' => __( 'Limit result set to attachments of a particular MIME type.' ), 526 'type' => 'string', 527 ); 599 'default' => null, 600 'description' => __( 'Limit result set to attachments of a particular MIME type.' ), 601 'type' => 'string', 602 ); 603 528 604 return $params; 529 605 } 530 606 531 607 /** 532 * Validate whether the user can query private statuses 533 * 534 * @param mixed $value Status value. 535 * @param WP_REST_Request $request Request object. 536 * @param string $parameter Additional parameter to pass to validation. 537 * @return WP_Error|boolean Boolean true if the user may query, WP_Error if not. 608 * Validates whether the user can query private statuses. 609 * 610 * @since 4.7.0 611 * @access public 612 * 613 * @param mixed $value Status value. 614 * @param WP_REST_Request $request Request object. 615 * @param string $parameter Additional parameter to pass for validation. 616 * @return WP_Error|bool True if the user may query, WP_Error if not. 538 617 */ 539 618 public function validate_user_can_query_private_statuses( $value, $request, $parameter ) { … … 541 620 return true; 542 621 } 622 543 623 return parent::validate_user_can_query_private_statuses( $value, $request, $parameter ); 544 624 } 545 625 546 626 /** 547 * Handle an upload via multipart/form-data ($_FILES). 548 * 549 * @param array $files Data from $_FILES. 627 * Handles an upload via multipart/form-data ($_FILES). 628 * 629 * @since 4.7.0 630 * @access protected 631 * 632 * @param array $files Data from the `$_FILES` superglobal. 550 633 * @param array $headers HTTP headers from the request. 551 * @return array|WP_Error Data from {@see wp_handle_upload()}.634 * @return array|WP_Error Data from wp_handle_upload(). 552 635 */ 553 636 protected function upload_from_file( $files, $headers ) { … … 559 642 if ( ! empty( $headers['content_md5'] ) ) { 560 643 $content_md5 = array_shift( $headers['content_md5'] ); 561 $expected = trim( $content_md5 ); 562 $actual = md5_file( $files['file']['tmp_name'] ); 644 $expected = trim( $content_md5 ); 645 $actual = md5_file( $files['file']['tmp_name'] ); 646 563 647 if ( $expected !== $actual ) { 564 648 return new WP_Error( 'rest_upload_hash_mismatch', __( 'Content hash did not match expected.' ), array( 'status' => 412 ) ); … … 570 654 'test_form' => false, 571 655 ); 656 572 657 // Bypasses is_uploaded_file() when running unit tests. 573 658 if ( defined( 'DIR_TESTDATA' ) && DIR_TESTDATA ) { … … 575 660 } 576 661 577 / / Include admin functions to get access to wp_handle_upload().662 /** Include admin functions to get access to wp_handle_upload() */ 578 663 require_once ABSPATH . 'wp-admin/includes/admin.php'; 664 579 665 $file = wp_handle_upload( $files['file'], $overrides ); 580 666 … … 587 673 588 674 /** 589 * Getthe supported media types.675 * Retrieves the supported media types. 590 676 * 591 677 * Media types are considered the MIME type category. 592 678 * 593 * @return array 679 * @since 4.7.0 680 * @access protected 681 * 682 * @return array Array of supported media types. 594 683 */ 595 684 protected function get_media_types() { 596 685 $media_types = array(); 686 597 687 foreach ( get_allowed_mime_types() as $mime_type ) { 598 688 $parts = explode( '/', $mime_type ); 689 599 690 if ( ! isset( $media_types[ $parts[0] ] ) ) { 600 691 $media_types[ $parts[0] ] = array(); 601 692 } 693 602 694 $media_types[ $parts[0] ][] = $mime_type; 603 695 } 696 604 697 return $media_types; 605 698 }
Note: See TracChangeset
for help on using the changeset viewer.