Changeset 61982
- Timestamp:
- 03/12/2026 06:01:47 AM (38 hours ago)
- Location:
- trunk
- Files:
-
- 4 edited
-
src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php (modified) (2 diffs)
-
tests/phpunit/tests/rest-api/rest-attachments-controller.php (modified) (1 diff)
-
tests/phpunit/tests/rest-api/rest-schema-setup.php (modified) (1 diff)
-
tests/qunit/fixtures/wp-api-generated.js (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php
r61980 r61982 97 97 'default' => true, 98 98 'description' => __( 'Whether to convert image formats.' ), 99 ), 100 ), 101 ), 102 'allow_batch' => $this->allow_batch, 103 'schema' => array( $this, 'get_public_item_schema' ), 104 ) 105 ); 106 107 register_rest_route( 108 $this->namespace, 109 '/' . $this->rest_base . '/(?P<id>[\d]+)/finalize', 110 array( 111 array( 112 'methods' => WP_REST_Server::CREATABLE, 113 'callback' => array( $this, 'finalize_item' ), 114 'permission_callback' => array( $this, 'edit_media_item_permissions_check' ), 115 'args' => array( 116 'id' => array( 117 'description' => __( 'Unique identifier for the attachment.' ), 118 'type' => 'integer', 99 119 ), 100 120 ), … … 2192 2212 return $filename; 2193 2213 } 2214 2215 /** 2216 * Finalizes an attachment after client-side media processing. 2217 * 2218 * Triggers the 'wp_generate_attachment_metadata' filter so that 2219 * server-side plugins can process the attachment after all client-side 2220 * operations (upload, thumbnail generation, sideloads) are complete. 2221 * 2222 * @since 7.0.0 2223 * 2224 * @param WP_REST_Request $request Full details about the request. 2225 * @return WP_REST_Response|WP_Error Response object on success, WP_Error object on failure. 2226 */ 2227 public function finalize_item( WP_REST_Request $request ) { 2228 $attachment_id = $request['id']; 2229 2230 $post = $this->get_post( $attachment_id ); 2231 if ( is_wp_error( $post ) ) { 2232 return $post; 2233 } 2234 2235 $metadata = wp_get_attachment_metadata( $attachment_id ); 2236 if ( ! is_array( $metadata ) ) { 2237 $metadata = array(); 2238 } 2239 2240 /** This filter is documented in wp-admin/includes/image.php */ 2241 $metadata = apply_filters( 'wp_generate_attachment_metadata', $metadata, $attachment_id, 'update' ); 2242 2243 wp_update_attachment_metadata( $attachment_id, $metadata ); 2244 2245 $response_request = new WP_REST_Request( 2246 WP_REST_Server::READABLE, 2247 rest_get_route_for_post( $attachment_id ) 2248 ); 2249 2250 $response_request['context'] = 'edit'; 2251 2252 if ( isset( $request['_fields'] ) ) { 2253 $response_request['_fields'] = $request['_fields']; 2254 } 2255 2256 return $this->prepare_item_for_response( $post, $response_request ); 2257 } 2194 2258 } -
trunk/tests/phpunit/tests/rest-api/rest-attachments-controller.php
r61980 r61982 3448 3448 $this->assertMatchesRegularExpression( '/canola-scaled-\d+\.jpg$/', $basename, 'Scaled filename should have numeric suffix when file conflicts with a different attachment.' ); 3449 3449 } 3450 3451 /** 3452 * Tests that the finalize endpoint triggers wp_generate_attachment_metadata. 3453 * 3454 * @ticket 62243 3455 * @covers WP_REST_Attachments_Controller::finalize_item 3456 * @requires function imagejpeg 3457 */ 3458 public function test_finalize_item(): void { 3459 wp_set_current_user( self::$author_id ); 3460 3461 // Create an attachment. 3462 $request = new WP_REST_Request( 'POST', '/wp/v2/media' ); 3463 $request->set_header( 'Content-Type', 'image/jpeg' ); 3464 $request->set_header( 'Content-Disposition', 'attachment; filename=canola.jpg' ); 3465 $request->set_body( (string) file_get_contents( self::$test_file ) ); 3466 $response = rest_get_server()->dispatch( $request ); 3467 $attachment_id = $response->get_data()['id']; 3468 3469 $this->assertSame( 201, $response->get_status() ); 3470 3471 // Track whether wp_generate_attachment_metadata filter fires. 3472 $filter_metadata = null; 3473 $filter_id = null; 3474 $filter_context = null; 3475 add_filter( 3476 'wp_generate_attachment_metadata', 3477 function ( array $metadata, int $id, string $context ) use ( &$filter_metadata, &$filter_id, &$filter_context ) { 3478 $filter_metadata = $metadata; 3479 $filter_id = $id; 3480 $filter_context = $context; 3481 $metadata['foo'] = 'bar'; 3482 return $metadata; 3483 }, 3484 10, 3485 3 3486 ); 3487 3488 // Call the finalize endpoint. 3489 $request = new WP_REST_Request( 'POST', "/wp/v2/media/{$attachment_id}/finalize" ); 3490 $response = rest_get_server()->dispatch( $request ); 3491 3492 $this->assertSame( 200, $response->get_status(), 'Finalize endpoint should return 200.' ); 3493 $this->assertIsArray( $filter_metadata ); 3494 $this->assertStringContainsString( 'canola', $filter_metadata['file'], 'Expected the canola image to have been had its metadata updated.' ); 3495 $this->assertSame( $attachment_id, $filter_id, 'Expected the post ID to be passed to the filter.' ); 3496 $this->assertSame( 'update', $filter_context, 'Filter context should be "update".' ); 3497 $resulting_metadata = wp_get_attachment_metadata( $attachment_id ); 3498 $this->assertIsArray( $resulting_metadata ); 3499 $this->assertArrayHasKey( 'foo', $resulting_metadata, 'Expected new metadata key to have been added.' ); 3500 $this->assertSame( 'bar', $resulting_metadata['foo'], 'Expected filtered metadata to be updated.' ); 3501 } 3502 3503 /** 3504 * Tests that the finalize endpoint requires authentication. 3505 * 3506 * @ticket 62243 3507 * @covers WP_REST_Attachments_Controller::finalize_item 3508 * @requires function imagejpeg 3509 */ 3510 public function test_finalize_item_requires_auth(): void { 3511 wp_set_current_user( self::$author_id ); 3512 3513 // Create an attachment. 3514 $request = new WP_REST_Request( 'POST', '/wp/v2/media' ); 3515 $request->set_header( 'Content-Type', 'image/jpeg' ); 3516 $request->set_header( 'Content-Disposition', 'attachment; filename=canola.jpg' ); 3517 $request->set_body( (string) file_get_contents( self::$test_file ) ); 3518 $response = rest_get_server()->dispatch( $request ); 3519 $attachment_id = $response->get_data()['id']; 3520 3521 // Try finalizing without authentication. 3522 wp_set_current_user( 0 ); 3523 3524 $request = new WP_REST_Request( 'POST', "/wp/v2/media/{$attachment_id}/finalize" ); 3525 $response = rest_get_server()->dispatch( $request ); 3526 3527 $this->assertErrorResponse( 'rest_cannot_edit_image', $response, 401 ); 3528 } 3529 3530 /** 3531 * Tests that the finalize endpoint returns error for invalid attachment ID. 3532 * 3533 * @ticket 62243 3534 * @covers WP_REST_Attachments_Controller::finalize_item 3535 */ 3536 public function test_finalize_item_invalid_id(): void { 3537 wp_set_current_user( self::$author_id ); 3538 3539 $invalid_id = PHP_INT_MAX; 3540 $this->assertNull( get_post( $invalid_id ), 'Expected invalid ID to not exist for an existing post.' ); 3541 $request = new WP_REST_Request( 'POST', "/wp/v2/media/$invalid_id/finalize" ); 3542 $response = rest_get_server()->dispatch( $request ); 3543 3544 $this->assertErrorResponse( 'rest_post_invalid_id', $response, 404 ); 3545 } 3450 3546 } -
trunk/tests/phpunit/tests/rest-api/rest-schema-setup.php
r61947 r61982 114 114 '/wp/v2/media/(?P<id>[\\d]+)/edit', 115 115 '/wp/v2/media/(?P<id>[\\d]+)/sideload', 116 '/wp/v2/media/(?P<id>[\\d]+)/finalize', 116 117 '/wp/v2/blocks', 117 118 '/wp/v2/blocks/(?P<id>[\d]+)', -
trunk/tests/qunit/fixtures/wp-api-generated.js
r61943 r61982 3720 3720 ] 3721 3721 }, 3722 "/wp/v2/media/(?P<id>[\\d]+)/finalize": { 3723 "namespace": "wp/v2", 3724 "methods": [ 3725 "POST" 3726 ], 3727 "endpoints": [ 3728 { 3729 "methods": [ 3730 "POST" 3731 ], 3732 "args": { 3733 "id": { 3734 "description": "Unique identifier for the attachment.", 3735 "type": "integer", 3736 "required": false 3737 } 3738 } 3739 } 3740 ] 3741 }, 3722 3742 "/wp/v2/menu-items": { 3723 3743 "namespace": "wp/v2",
Note: See TracChangeset
for help on using the changeset viewer.