WordPress.org

Make WordPress Core

Ticket #47987: 47987.5.diff

File 47987.5.diff, 11.3 KB (added by TimothyBlynJacobs, 6 weeks ago)
  • src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php

    diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php
    index c1be06a2a0..571d207803 100644
    a b  
    1616 */
    1717class WP_REST_Attachments_Controller extends WP_REST_Posts_Controller {
    1818
     19        public function register_routes() {
     20                parent::register_routes();
     21                register_rest_route(
     22                        $this->namespace,
     23                        '/' . $this->rest_base . '/(?P<id>[\d]+)/post-process',
     24                        array(
     25                                'methods'             => WP_REST_Server::CREATABLE,
     26                                'callback'            => array( $this, 'post_process_item' ),
     27                                'permission_callback' => array( $this, 'post_process_item_permissions_check' ),
     28                                'args'                => array(
     29                                        'id'     => array(
     30                                                'description' => __( 'Unique identifier for the object.' ),
     31                                                'type'        => 'integer',
     32                                        ),
     33                                        'action' => array(
     34                                                'type'     => 'string',
     35                                                'enum'     => array( 'create-image-subsizes' ),
     36                                                'required' => true,
     37                                        ),
     38                                ),
     39                        )
     40                );
     41        }
     42
    1943        /**
    2044         * Determines the allowed query_vars for a get_items() response and
    2145         * prepares for WP_Query.
    class WP_REST_Attachments_Controller extends WP_REST_Posts_Controller { 
    100124                        return new WP_Error( 'rest_invalid_param', __( 'Invalid parent type.' ), array( 'status' => 400 ) );
    101125                }
    102126
     127                $insert = $this->insert_attachment( $request );
     128
     129                if ( is_wp_error( $insert ) ) {
     130                        return $insert;
     131                }
     132
     133                // Extract by name.
     134                $attachment_id = $insert['attachment_id'];
     135                $file          = $insert['file'];
     136
     137                if ( isset( $request['alt_text'] ) ) {
     138                        update_post_meta( $attachment_id, '_wp_attachment_image_alt', sanitize_text_field( $request['alt_text'] ) );
     139                }
     140
     141                $attachment    = get_post( $attachment_id );
     142                $fields_update = $this->update_additional_fields_for_object( $attachment, $request );
     143
     144                if ( is_wp_error( $fields_update ) ) {
     145                        return $fields_update;
     146                }
     147
     148                $request->set_param( 'context', 'edit' );
     149
     150                /**
     151                 * Fires after a single attachment is completely created or updated via the REST API.
     152                 *
     153                 * @since 5.0.0
     154                 *
     155                 * @param WP_Post         $attachment Inserted or updated attachment object.
     156                 * @param WP_REST_Request $request    Request object.
     157                 * @param bool            $creating   True when creating an attachment, false when updating.
     158                 */
     159                do_action( 'rest_after_insert_attachment', $attachment, $request, true );
     160
     161                if ( defined( 'REST_REQUEST' ) && REST_REQUEST ) {
     162                        // Set a custom header with the attachment_id.
     163                        // Used by the browser/client to resume creating image sub-sizes after a PHP fatal error.
     164                        header( 'X-WP-Upload-Attachment-ID: ' . $attachment_id );
     165                }
     166
     167                // Include admin function to get access to wp_generate_attachment_metadata().
     168                require_once ABSPATH . 'wp-admin/includes/media.php';
     169
     170                // Post-process the upload (create image sub-sizes, make PDF thumbnalis, etc.) and insert attachment meta.
     171                // At this point the server may run out of resources and post-processing of uploaded images may fail.
     172                wp_update_attachment_metadata( $attachment_id, wp_generate_attachment_metadata( $attachment_id, $file ) );
     173
     174                $response = $this->prepare_item_for_response( $attachment, $request );
     175                $response = rest_ensure_response( $response );
     176                $response->set_status( 201 );
     177                $response->header( 'Location', rest_url( sprintf( '%s/%s/%d', $this->namespace, $this->rest_base, $attachment_id ) ) );
     178
     179                return $response;
     180        }
     181
     182        /**
     183         * Inserts the attachment post in the database. Does not update the attachment meta.
     184         *
     185         * @since 5.3.0
     186         *
     187         * @param WP_REST_Request $request
     188         * @return array|WP_Error
     189         */
     190        protected function insert_attachment( $request ) {
    103191                // Get the file via $_FILES or raw data.
    104192                $files   = $request->get_file_params();
    105193                $headers = $request->get_headers();
    class WP_REST_Attachments_Controller extends WP_REST_Posts_Controller { 
    138226                        }
    139227                }
    140228
    141                 $attachment                 = $this->prepare_item_for_database( $request );
     229                $attachment = $this->prepare_item_for_database( $request );
     230
    142231                $attachment->post_mime_type = $type;
    143232                $attachment->guid           = $url;
    144233
    class WP_REST_Attachments_Controller extends WP_REST_Posts_Controller { 
    155244                        } else {
    156245                                $id->add_data( array( 'status' => 400 ) );
    157246                        }
     247
    158248                        return $id;
    159249                }
    160250
    class WP_REST_Attachments_Controller extends WP_REST_Posts_Controller { 
    172262                 */
    173263                do_action( 'rest_insert_attachment', $attachment, $request, true );
    174264
    175                 // Include admin function to get access to wp_generate_attachment_metadata().
    176                 require_once ABSPATH . 'wp-admin/includes/media.php';
    177 
    178                 wp_update_attachment_metadata( $id, wp_generate_attachment_metadata( $id, $file ) );
    179 
    180                 if ( isset( $request['alt_text'] ) ) {
    181                         update_post_meta( $id, '_wp_attachment_image_alt', sanitize_text_field( $request['alt_text'] ) );
    182                 }
    183 
    184                 $fields_update = $this->update_additional_fields_for_object( $attachment, $request );
    185 
    186                 if ( is_wp_error( $fields_update ) ) {
    187                         return $fields_update;
    188                 }
    189 
    190                 $request->set_param( 'context', 'edit' );
    191 
    192                 /**
    193                  * Fires after a single attachment is completely created or updated via the REST API.
    194                  *
    195                  * @since 5.0.0
    196                  *
    197                  * @param WP_Post         $attachment Inserted or updated attachment object.
    198                  * @param WP_REST_Request $request    Request object.
    199                  * @param bool            $creating   True when creating an attachment, false when updating.
    200                  */
    201                 do_action( 'rest_after_insert_attachment', $attachment, $request, true );
    202 
    203                 $response = $this->prepare_item_for_response( $attachment, $request );
    204                 $response = rest_ensure_response( $response );
    205                 $response->set_status( 201 );
    206                 $response->header( 'Location', rest_url( sprintf( '%s/%s/%d', $this->namespace, $this->rest_base, $id ) ) );
    207 
    208                 return $response;
     265                return array(
     266                        'attachment_id' => $id,
     267                        'file'          => $file,
     268                );
    209269        }
    210270
    211271        /**
    class WP_REST_Attachments_Controller extends WP_REST_Posts_Controller { 
    253313                return $response;
    254314        }
    255315
     316        /**
     317         * Performs post processing on an attachment.
     318         *
     319         * @since 5.3.0
     320         *
     321         * @param WP_REST_Request $request
     322         * @return WP_REST_Response|WP_Error
     323         */
     324        public function post_process_item( $request ) {
     325                switch ( $request['action'] ) {
     326                        case 'create-image-subsizes':
     327                                require_once ABSPATH . 'wp-admin/includes/image.php';
     328                                wp_update_image_subsizes( $request['id'] );
     329                                break;
     330                }
     331
     332                $request['context'] = 'edit';
     333
     334                return $this->prepare_item_for_response( get_post( $request['id'] ), $request );
     335        }
     336
     337        /**
     338         * Checks if a given request can perform post processing on an attachment.
     339         *
     340         * @sicne 5.3.0
     341         *
     342         * @param WP_REST_Request $request Full details about the request.
     343         * @return true|WP_Error True if the request has access to update the item, WP_Error object otherwise.
     344         */
     345        public function post_process_item_permissions_check( $request ) {
     346                return $this->update_item_permissions_check( $request );
     347        }
     348
    256349        /**
    257350         * Prepares a single attachment for create or update.
    258351         *
    class WP_REST_Attachments_Controller extends WP_REST_Posts_Controller { 
    380473                        $data['source_url'] = wp_get_attachment_url( $post->ID );
    381474                }
    382475
     476                if ( in_array( 'missing_image_sizes', $fields, true ) ) {
     477                        require_once ABSPATH . 'wp-admin/includes/image.php';
     478                        $data['missing_image_sizes'] = array_keys( wp_get_missing_image_subsizes( $post->ID ) );
     479                }
     480
    383481                $context = ! empty( $request['context'] ) ? $request['context'] : 'view';
    384482
    385483                $data = $this->filter_response_by_context( $data, $context );
    class WP_REST_Attachments_Controller extends WP_REST_Posts_Controller { 
    514612                        'readonly'    => true,
    515613                );
    516614
     615                $schema['properties']['missing_image_sizes'] = array(
     616                        'description' => __( 'List of the missing image sizes of the attachment.' ),
     617                        'type'        => 'array',
     618                        'items'       => array( 'type' => 'string' ),
     619                        'context'     => array( 'edit' ),
     620                        'readonly'    => true,
     621                );
     622
    517623                unset( $schema['properties']['password'] );
    518624
    519625                $this->schema = $schema;
  • tests/phpunit/tests/rest-api/rest-attachments-controller.php

    diff --git a/tests/phpunit/tests/rest-api/rest-attachments-controller.php b/tests/phpunit/tests/rest-api/rest-attachments-controller.php
    index 556cc6c8be..dc0b61835d 100644
    a b class WP_Test_REST_Attachments_Controller extends WP_Test_REST_Post_Type_Control 
    13271327                $response   = rest_get_server()->dispatch( $request );
    13281328                $data       = $response->get_data();
    13291329                $properties = $data['schema']['properties'];
    1330                 $this->assertEquals( 26, count( $properties ) );
     1330                $this->assertEquals( 27, count( $properties ) );
    13311331                $this->assertArrayHasKey( 'author', $properties );
    13321332                $this->assertArrayHasKey( 'alt_text', $properties );
    13331333                $this->assertArrayHasKey( 'caption', $properties );
    class WP_Test_REST_Attachments_Controller extends WP_Test_REST_Post_Type_Control 
    13601360                $this->assertArrayHasKey( 'raw', $properties['title']['properties'] );
    13611361                $this->assertArrayHasKey( 'rendered', $properties['title']['properties'] );
    13621362                $this->assertArrayHasKey( 'type', $properties );
     1363                $this->assertArrayHasKey( 'missing_image_sizes', $properties );
    13631364        }
    13641365
    13651366        public function test_get_additional_field_registration() {
  • tests/phpunit/tests/rest-api/rest-schema-setup.php

    diff --git a/tests/phpunit/tests/rest-api/rest-schema-setup.php b/tests/phpunit/tests/rest-api/rest-schema-setup.php
    index 5c780011d3..51abf95fc1 100644
    a b class WP_Test_REST_Schema_Initialization extends WP_Test_REST_TestCase { 
    9999                        '/wp/v2/pages/(?P<parent>[\\d]+)/autosaves/(?P<id>[\\d]+)',
    100100                        '/wp/v2/media',
    101101                        '/wp/v2/media/(?P<id>[\\d]+)',
     102                        '/wp/v2/media/(?P<id>[\\d]+)/post-process',
    102103                        '/wp/v2/blocks',
    103104                        '/wp/v2/blocks/(?P<id>[\d]+)',
    104105                        '/wp/v2/blocks/(?P<id>[\d]+)/autosaves',
  • tests/qunit/fixtures/wp-api-generated.js

    diff --git a/tests/qunit/fixtures/wp-api-generated.js b/tests/qunit/fixtures/wp-api-generated.js
    index 3083545431..b8217e729b 100644
    a b mockedApiResponse.Schema = { 
    23042304                }
    23052305            ]
    23062306        },
     2307        "/wp/v2/media/(?P<id>[\\d+])/post-process": {
     2308            "namespace": "wp/v2",
     2309            "methods": [
     2310                "POST"
     2311            ],
     2312            "endpoints": [
     2313                {
     2314                    "methods": [
     2315                        "POST"
     2316                    ],
     2317                    "args": {
     2318                        "id": {
     2319                            "required": false,
     2320                            "description": "Unique identifier for the object.",
     2321                            "type": "integer"
     2322                        },
     2323                        "action": {
     2324                            "required": true,
     2325                            "enum": [
     2326                                "create-image-subsizes"
     2327                            ],
     2328                            "type": "string"
     2329                        }
     2330                    }
     2331                }
     2332            ]
     2333        },
    23072334        "/wp/v2/blocks": {
    23082335            "namespace": "wp/v2",
    23092336            "methods": [