WordPress.org

Make WordPress Core

Ticket #47987: 47987.3.diff

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

     
    100100                        return new WP_Error( 'rest_invalid_param', __( 'Invalid parent type.' ), array( 'status' => 400 ) );
    101101                }
    102102
     103                $upload_ref   = $request->get_header( 'X-WP-UploadRef' );
     104                $post_process = $request->get_header( 'X-WP-UploadPostProcess' );
     105
     106                if ( $upload_ref && $post_process ) {
     107                        // Include upload ref functions.
     108                        require_once ABSPATH . 'wp-admin/includes/file.php';
     109
     110                        $attachment_id = _wp_get_upload_ref_attachment_id( $upload_ref );
     111
     112                        if ( ! $attachment_id ) {
     113                                // The upload has failed before an attachment post was created.
     114                                return new WP_Error( 'upload_reference_not_found', __( 'Upload failed. Please try again.' ), array( 'status' => 404 ) );
     115                        }
     116
     117                        if ( 'create-image-subsizes' === $post_process ) {
     118                                // Try to create image sub-sizes again.
     119                                // This can still be pretty slow and cause timeout or out of memory errors.
     120                                // The client would need to also handle HTTP 500 responses.
     121                                require_once ABSPATH . 'wp-admin/includes/image.php';
     122                                wp_update_image_subsizes( $attachment_id );
     123
     124                                // If this completed successfully the upload ref is no longer needed.
     125                                _wp_clear_upload_ref( $upload_ref );
     126                        } elseif ( 'upload-failed-cleanup' === $post_process ) {
     127                                // The upload failed. Cleanup.
     128                                if ( wp_attachment_is_image( $attachment_id ) ) {
     129                                        $attachment = get_post( $attachment_id );
     130
     131                                        // Posted at most 10 min ago.
     132                                        if ( $attachment && ( time() - strtotime( $attachment->post_date_gmt ) < 600 ) ) {
     133                                                /**
     134                                                 * Runs when an image upload fails during the post-processing phase,
     135                                                 * and the newly created attachment post is about to be deleted.
     136                                                 *
     137                                                 * @since 5.3.0
     138                                                 *
     139                                                 * @param int $attachment_id The attachment post ID.
     140                                                 */
     141                                                do_action( 'wp_upload_failed_cleanup', $attachment_id );
     142
     143                                                wp_delete_attachment( $attachment_id, true );
     144                                                _wp_clear_upload_ref( $upload_ref );
     145
     146                                                // Error message is the same as in script-loader.php
     147                                                $message = __( 'Post-processing of the image failed. If this is a photo or a large image, please scale it down to 2500 pixels and upload it again.' );
     148                                                return new WP_Error( 'upload_failed_post_processing', $message );
     149                                        }
     150                                }
     151
     152                                return new WP_Error( 'upload_reference_not_found', __( 'Upload failed. Please try again.' ), array( 'status' => 404 ) );
     153                        }
     154                } else {
     155                        // Initial upload request.
     156                        $insert  = $this->insert_attachment( $request );
     157                        $set_ref = null;
     158
     159                        if ( is_wp_error( $insert ) ) {
     160                                return $insert;
     161                        }
     162
     163                        // Extract by name.
     164                        $attachment_id = $insert['attachment_id'];
     165                        $file          = $insert['file'];
     166
     167                        if ( isset( $request['alt_text'] ) ) {
     168                                update_post_meta( $attachment_id, '_wp_attachment_image_alt', sanitize_text_field( $request['alt_text'] ) );
     169                        }
     170
     171                        $attachment    = get_post( $attachment_id );
     172                        $fields_update = $this->update_additional_fields_for_object( $attachment, $request );
     173
     174                        if ( is_wp_error( $fields_update ) ) {
     175                                return $fields_update;
     176                        }
     177
     178                        // When uploading images store the unique upload ref.
     179                        if ( $upload_ref && wp_attachment_is_image( $attachment_id ) ) {
     180                                // Include upload ref functions.
     181                                require_once ABSPATH . 'wp-admin/includes/file.php';
     182                                $set_ref = _wp_set_upload_ref( $upload_ref, $attachment_id );
     183                        }
     184
     185                        // Include admin function to get access to wp_generate_attachment_metadata().
     186                        require_once ABSPATH . 'wp-admin/includes/media.php';
     187
     188                        // Post-process the upload (create image sub-sizes, make PDF thumbnalis, etc.) and insert attachment meta.
     189                        // At this point the server may run out of resources and post-processing of uploaded images may fail.
     190                        wp_update_attachment_metadata( $attachment_id, wp_generate_attachment_metadata( $attachment_id, $file ) );
     191
     192                        // At this point the file has been uploaded successfully. The upload ref is no longer needed.
     193                        if ( $set_ref ) {
     194                                _wp_clear_upload_ref( $upload_ref );
     195                        }
     196                }
     197
     198                // The following runs on initial upload requests and after successfully re-trying to create image sub-sizes.
     199                // At this point the file has been uploaded and post-processed successfully.
     200                if ( empty( $attachment ) ) {
     201                        $attachment = get_post( $attachment_id );
     202                }
     203
     204                $request->set_param( 'context', 'edit' );
     205
     206                /**
     207                 * Fires after a single attachment is completely created or updated via the REST API.
     208                 *
     209                 * @since 5.0.0
     210                 *
     211                 * @param WP_Post         $attachment Inserted or updated attachment object.
     212                 * @param WP_REST_Request $request    Request object.
     213                 * @param bool            $creating   True when creating an attachment, false when updating.
     214                 */
     215                do_action( 'rest_after_insert_attachment', $attachment, $request, true );
     216
     217                $response = $this->prepare_item_for_response( $attachment, $request );
     218                $response = rest_ensure_response( $response );
     219                $response->set_status( 201 );
     220                $response->header( 'Location', rest_url( sprintf( '%s/%s/%d', $this->namespace, $this->rest_base, $attachment_id ) ) );
     221
     222                return $response;
     223        }
     224
     225        /**
     226         * Inserts the attachment post in the database. Does not update the attachment meta.
     227         *
     228         * @since 5.3.0
     229         *
     230         * @param WP_REST_Request $request
     231         *
     232         * @return array|WP_Error
     233         */
     234        protected function insert_attachment( $request ) {
    103235                // Get the file via $_FILES or raw data.
    104236                $files   = $request->get_file_params();
    105237                $headers = $request->get_headers();
     
    138270                        }
    139271                }
    140272
    141                 $attachment                 = $this->prepare_item_for_database( $request );
     273                $attachment = $this->prepare_item_for_database( $request );
     274
    142275                $attachment->post_mime_type = $type;
    143276                $attachment->guid           = $url;
    144277
     
    155288                        } else {
    156289                                $id->add_data( array( 'status' => 400 ) );
    157290                        }
     291
    158292                        return $id;
    159293                }
    160294
     
    172306                 */
    173307                do_action( 'rest_insert_attachment', $attachment, $request, true );
    174308
    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;
     309                return array(
     310                        'attachment_id' => $id,
     311                        'file'          => $file,
     312                );
    209313        }
    210314
    211315        /**