diff --git a/src/js/_enqueues/vendor/plupload/handlers.js b/src/js/_enqueues/vendor/plupload/handlers.js index 81d91e9f88..f225c49970 100644 --- a/src/js/_enqueues/vendor/plupload/handlers.js +++ b/src/js/_enqueues/vendor/plupload/handlers.js @@ -450,7 +450,7 @@ jQuery( document ).ready( function( $ ) { data: { action: 'media-create-image-subsizes', _wpnonce: _wpPluploadSettings.defaults.multipart_params._wpnonce, - _wp_temp_image_ref: file.id, + _wp_temp_upload_ref: file.id, _wp_upload_failed_cleanup: true, } }); @@ -478,7 +478,7 @@ jQuery( document ).ready( function( $ ) { data: { action: 'media-create-image-subsizes', _wpnonce: wpUploaderInit.multipart_params._wpnonce, - _wp_temp_image_ref: file.id, + _wp_temp_upload_ref: file.id, _legasy_support: 'true', } }).done( function( response ) { @@ -599,9 +599,9 @@ jQuery( document ).ready( function( $ ) { */ uploader.bind( 'BeforeUpload', function( up, file ) { if ( file.type && file.type.indexOf( 'image/' ) === 0 ) { - up.settings.multipart_params._wp_temp_image_ref = file.id; + up.settings.multipart_params._wp_temp_upload_ref = file.id; } else { - up.settings.multipart_params._wp_temp_image_ref = ''; + up.settings.multipart_params._wp_temp_upload_ref = ''; } } ); }; diff --git a/src/js/_enqueues/vendor/plupload/wp-plupload.js b/src/js/_enqueues/vendor/plupload/wp-plupload.js index 7677cc66ea..67e44226e6 100644 --- a/src/js/_enqueues/vendor/plupload/wp-plupload.js +++ b/src/js/_enqueues/vendor/plupload/wp-plupload.js @@ -138,7 +138,7 @@ window.wp = window.wp || {}; data: { action: 'media-create-image-subsizes', _wpnonce: _wpPluploadSettings.defaults.multipart_params._wpnonce, - _wp_temp_image_ref: file.id, + _wp_temp_upload_ref: file.id, _wp_upload_failed_cleanup: true, } }); @@ -161,7 +161,7 @@ window.wp = window.wp || {}; data: { action: 'media-create-image-subsizes', _wpnonce: _wpPluploadSettings.defaults.multipart_params._wpnonce, - _wp_temp_image_ref: file.id, // Used to find the new attachment_id. + _wp_temp_upload_ref: file.id, // Used to find the new attachment_id. } }).done( function( response ) { if ( response.success ) { @@ -324,9 +324,9 @@ window.wp = window.wp || {}; */ this.uploader.bind( 'BeforeUpload', function( up, file ) { if ( file.type && file.type.indexOf( 'image/' ) === 0 ) { - up.settings.multipart_params._wp_temp_image_ref = file.id; + up.settings.multipart_params._wp_temp_upload_ref = file.id; } else { - up.settings.multipart_params._wp_temp_image_ref = ''; + up.settings.multipart_params._wp_temp_upload_ref = ''; } } ); diff --git a/src/wp-admin/includes/ajax-actions.php b/src/wp-admin/includes/ajax-actions.php index 759f011b09..8d10ff731d 100644 --- a/src/wp-admin/includes/ajax-actions.php +++ b/src/wp-admin/includes/ajax-actions.php @@ -2422,21 +2422,18 @@ function wp_ajax_media_create_image_subsizes() { wp_send_json_error( array( 'message' => __( 'Sorry, you are not allowed to upload files.' ) ) ); } - // Using Plupload `file.id` as ref. - if ( ! empty( $_POST['_wp_temp_image_ref'] ) ) { - $image_ref = preg_replace( '/[^a-zA-Z0-9_]/', '', $_POST['_wp_temp_image_ref'] ); + if ( ! empty( $_POST['_wp_temp_upload_ref'] ) ) { + // Uploading of images usually fails while creating the sub-sizes, either because of a timeout or out of memory. + // At this point the file has been uploaded and an attachment post created, but because of the PHP fatal error + // the cliend doesn't know the attachment ID yet. + // To be able to find the new attachment_id in these cases we temporarily store an upload reference sent by the client + // in the original upload request. It is used to save a transient with the attachment_id as value. + // That reference currently is Plupload's `file.id` but can be any sufficiently random alpha-numeric string. + $attachment_id = _wp_get_upload_ref_attachment_id( $_POST['_wp_temp_upload_ref'] ); } else { wp_send_json_error( array( 'message' => __( 'Invalid file reference.' ) ) ); } - // Uploading of images usually fails while creating the sub-sizes, either because of a timeout or out of memory. - // At this point the file has been uploaded and an attachment post created, but because of the PHP fatal error - // the cliend doesn't know the attachment ID yet. - // To be able to find the new attachment_id in these cases we temporarily store an upload reference sent by the client - // in the original upload request. It is used to save a transient with the attachment_id as value. - // That reference currently is Plupload's `file.id` but can be any sufficiently random alpha-numeric string. - $attachment_id = get_transient( '_wp_temp_image_ref:' . $image_ref ); - if ( empty( $attachment_id ) ) { wp_send_json_error( array( 'message' => __( 'Upload failed. Please reload and try again.' ) ) ); } @@ -2481,7 +2478,7 @@ function wp_ajax_media_create_image_subsizes() { } // At this point the image has been uploaded successfully. - delete_transient( '_wp_temp_image_ref:' . $image_ref ); + _wp_clear_upload_ref( $_POST['_wp_temp_upload_ref'] ); wp_send_json_success( $response ); } diff --git a/src/wp-admin/includes/file.php b/src/wp-admin/includes/file.php index 4f04c62fbe..9d5244202e 100644 --- a/src/wp-admin/includes/file.php +++ b/src/wp-admin/includes/file.php @@ -978,6 +978,63 @@ function wp_handle_sideload( &$file, $overrides = false, $time = null ) { return _wp_handle_upload( $file, $overrides, $time, $action ); } +/** + * Temporarily stores the client upload reference in a transient. + * + * @since 5.3.0 + * @access private + * + * @param string $upload_ref The upload reference sent by the client. + * @param int $attachment_id Attachment post ID. + * @return bool Whether the transient was set. + */ +function _wp_set_upload_ref( $upload_ref, $attachment_id ) { + $upload_ref = preg_replace( '/[^a-zA-Z0-9_]/', '', $upload_ref ); + + if ( ! empty( $upload_ref ) ) { + return set_transient( '_wp_temp_image_ref:' . $upload_ref, $attachment_id, HOUR_IN_SECONDS ); + } + + return false; +} + +/** + * Get attachment post ID from an upload reference. + * + * @since 5.3.0 + * @access private + * + * @param string $upload_ref The upload reference sent by the client. + * @return int The attachemtn post ID. Zero if the upload reference has expired or doesn't exist. + */ +function _wp_get_upload_ref_attachment_id( $upload_ref ) { + $upload_ref = preg_replace( '/[^a-zA-Z0-9_]/', '', $upload_ref ); + + if ( ! empty( $upload_ref ) ) { + return (int) get_transient( '_wp_temp_image_ref:' . $upload_ref ); + } + + return 0; +} + +/** + * Remove the transient that stores a temporary upload reference. + * + * @since 5.3.0 + * @access private + * + * @param string $upload_ref The upload reference sent by the client. + * @return bool Whether the transient was removed. + */ +function _wp_clear_upload_ref( $upload_ref ) { + $upload_ref = preg_replace( '/[^a-zA-Z0-9_]/', '', $upload_ref ); + + if ( ! empty( $upload_ref ) ) { + return delete_transient( '_wp_temp_image_ref:' . $upload_ref ); + } + + return false; +} /** * Downloads a URL to a local temporary file using the WordPress HTTP API. diff --git a/src/wp-admin/includes/media.php b/src/wp-admin/includes/media.php index 2efe0830b5..9cab599662 100644 --- a/src/wp-admin/includes/media.php +++ b/src/wp-admin/includes/media.php @@ -308,13 +308,13 @@ function media_handle_upload( $file_id, $post_id, $post_data = array(), $overrid $ext = pathinfo( $name, PATHINFO_EXTENSION ); $name = wp_basename( $name, ".$ext" ); - $url = $file['url']; - $type = $file['type']; - $file = $file['file']; - $title = sanitize_text_field( $name ); - $content = ''; - $excerpt = ''; - $image_ref = false; + $url = $file['url']; + $type = $file['type']; + $file = $file['file']; + $title = sanitize_text_field( $name ); + $content = ''; + $excerpt = ''; + $_ref = false; if ( preg_match( '#^audio#', $type ) ) { $meta = wp_read_audio_metadata( $file ); @@ -376,11 +376,6 @@ function media_handle_upload( $file_id, $post_id, $post_data = array(), $overrid // Use image exif/iptc data for title and caption defaults if possible. } elseif ( 0 === strpos( $type, 'image/' ) ) { - // Image file reference passed by the uploader. - if ( ! empty( $_POST['_wp_temp_image_ref'] ) ) { - $image_ref = preg_replace( '/[^a-zA-Z0-9_]/', '', $_POST['_wp_temp_image_ref'] ); - } - $image_meta = wp_read_image_metadata( $file ); if ( $image_meta ) { @@ -415,8 +410,8 @@ function media_handle_upload( $file_id, $post_id, $post_data = array(), $overrid if ( ! is_wp_error( $attachment_id ) ) { // If an image, keep the upload reference until all image sub-sizes are created. - if ( $image_ref ) { - set_transient( '_wp_temp_image_ref:' . $image_ref, $attachment_id, HOUR_IN_SECONDS ); + if ( ! empty( $_POST['_wp_temp_upload_ref'] ) && wp_attachment_is_image( $attachment_id ) ) { + $_ref = _wp_set_upload_ref( $_POST['_wp_temp_upload_ref'], $attachment_id ); } // The image sub-sizes are created during wp_generate_attachment_metadata(). @@ -425,8 +420,8 @@ function media_handle_upload( $file_id, $post_id, $post_data = array(), $overrid // At this point the image is uploaded successfully even if there were specific errors or some sub-sizes were not created. // The transient is not needed any more. - if ( $image_ref ) { - delete_transient( '_wp_temp_image_ref:' . $image_ref ); + if ( $_ref ) { + _wp_clear_upload_ref( $_POST['_wp_temp_upload_ref'] ); } }