diff --git a/inc/class-s3-uploads.php b/inc/class-s3-uploads.php index 50f01f61..bf80a4fc 100644 --- a/inc/class-s3-uploads.php +++ b/inc/class-s3-uploads.php @@ -53,6 +53,7 @@ public function setup() { remove_filter( 'admin_notices', 'wpthumb_errors' ); add_action( 'wp_handle_sideload_prefilter', array( $this, 'filter_sideload_move_temp_file_to_s3' ) ); + add_filter( 'wp_generate_attachment_metadata', array( $this, 'set_filesize_in_attachment_meta' ), 10, 3 ); } /** @@ -64,6 +65,7 @@ public function tear_down() { remove_filter( 'upload_dir', array( $this, 'filter_upload_dir' ) ); remove_filter( 'wp_image_editors', array( $this, 'filter_editors' ), 9 ); remove_filter( 'wp_handle_sideload_prefilter', array( $this, 'filter_sideload_move_temp_file_to_s3' ) ); + remove_filter( 'wp_generate_attachment_metadata', array( $this, 'set_filesize_in_attachment_meta' ) ); } /** @@ -210,7 +212,6 @@ public function filter_editors( $editors ) { return $editors; } - /** * Copy the file from /tmp to an s3 dir so handle_sideload doesn't fail due to * trying to do a rename() on the file cross streams. This is somewhat of a hack @@ -230,6 +231,32 @@ public function filter_sideload_move_temp_file_to_s3( array $file ) { return $file; } + /** + * Store the attachment filesize in the attachment meta array. + * + * Getting the filesize of an image in S3 involves a remote HEAD request, + * which is a bit slower than a local filesystem operation would be. As a + * result, operations like `wp_prepare_attachments_for_js' take substantially + * longer to complete against s3 uploads than if they were performed with a + * local filesystem.i + * + * Saving the filesize in the attachment metadata when the image is + * uploaded allows core to skip this stat when retrieving and formatting it. + * + * @param array $metadata Attachment metadata. + * @param int $attachment_id ID of uploaded attachment. + * @return array Attachment metadata array, with "filesize" value added. + */ + function set_filesize_in_attachment_meta( array $metadata, int $attachment_id ) { + $file = get_attached_file( $attachment_id ); + + if ( file_exists( $file ) ) { + $metadata['filesize'] = filesize( $file ); + } + + return $metadata; + } + /** * Filters wp_read_image_metadata. exif_read_data() doesn't work on * file streams so we need to make a temporary local copy to extract