Media: revert the multi-mime feature.

This feature isn't quite ready to land.

Reverts r53786, r53848, r53847, r53845, r53751.

Props flixos90, azaozz, dd32.
See #55443.


Built from https://develop.svn.wordpress.org/trunk@54085


git-svn-id: http://core.svn.wordpress.org/trunk@53644 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
Adam Silverstein 2022-09-06 21:13:12 +00:00
parent 32b92a213a
commit 4b5968aa9b
10 changed files with 134 additions and 727 deletions

View File

@ -71,29 +71,22 @@ function wp_crop_image( $src, $src_x, $src_y, $src_w, $src_h, $dst_w, $dst_h, $s
}
/**
* Compares the existing image sub-sizes (as saved in the attachment meta)
* to the currently registered image sub-sizes, and returns the difference.
* Compare the existing image sub-sizes (as saved in the attachment meta)
* to the currently registered image sub-sizes, and return the difference.
*
* Registered sub-sizes that are larger than the image are skipped.
*
* @since 5.3.0
* @since 6.1.0 The $mime_type parameter was added.
*
* @param int $attachment_id The image attachment post ID.
* @param string $mime_type Optional. The mime type to check for missing sizes. Default is the primary image mime.
* @param int $attachment_id The image attachment post ID.
* @return array[] Associative array of arrays of image sub-size information for
* missing image sizes, keyed by image size name.
*/
function wp_get_missing_image_subsizes( $attachment_id, $mime_type = '' ) {
function wp_get_missing_image_subsizes( $attachment_id ) {
if ( ! wp_attachment_is_image( $attachment_id ) ) {
return array();
}
$primary_mime_type = get_post_mime_type( get_post( $attachment_id ) );
if ( ! $mime_type ) {
$mime_type = $primary_mime_type;
}
$registered_sizes = wp_get_registered_image_subsizes();
$image_meta = wp_get_attachment_metadata( $attachment_id );
@ -136,38 +129,19 @@ function wp_get_missing_image_subsizes( $attachment_id, $mime_type = '' ) {
* However we keep the old sub-sizes with the previous dimensions
* as the image may have been used in an older post.
*/
$missing_sizes = array();
foreach ( $possible_sizes as $size_name => $size_data ) {
if ( ! isset( $image_meta['sizes'][ $size_name ] ) ) {
$missing_sizes[ $size_name ] = $size_data;
continue;
}
if ( ( isset( $size_data['mime-type'] ) && $size_data['mime-type'] === $mime_type ) || isset( $size_data['sources'][ $mime_type ] ) ) {
continue;
}
$missing_sizes[ $size_name ] = $size_data;
}
// Filter secondary mime types to those sizes that are enabled.
if ( $primary_mime_type !== $mime_type ) {
$missing_sizes = _wp_filter_image_sizes_additional_mime_type_support( $missing_sizes, $attachment_id );
}
$missing_sizes = array_diff_key( $possible_sizes, $image_meta['sizes'] );
/**
* Filters the array of missing image sub-sizes for an uploaded image.
*
* @since 5.3.0
* @since 6.1.0 The $mime_type filter parameter was added.
*
* @param array[] $missing_sizes Associative array of arrays of image sub-size information for
* missing image sizes, keyed by image size name.
* @param array $image_meta The image meta data.
* @param int $attachment_id The image attachment post ID.
* @param string $mime_type The image mime type to get missing sizes for.
*/
return apply_filters( 'wp_get_missing_image_subsizes', $missing_sizes, $image_meta, $attachment_id, $mime_type );
return apply_filters( 'wp_get_missing_image_subsizes', $missing_sizes, $image_meta, $attachment_id );
}
/**
@ -175,7 +149,6 @@ function wp_get_missing_image_subsizes( $attachment_id, $mime_type = '' ) {
* create them and update the image meta data.
*
* @since 5.3.0
* @since 6.1.0 Now supports additional mime types, creating the additional sub-sizes and 'full' sized images.
*
* @param int $attachment_id The image attachment post ID.
* @return array|WP_Error The updated image meta data array or WP_Error object
@ -194,33 +167,14 @@ function wp_update_image_subsizes( $attachment_id ) {
return new WP_Error( 'invalid_attachment', __( 'The attached file cannot be found.' ) );
}
} else {
// Get the primary and additional mime types to generate.
list( $primary_mime_type, $additional_mime_types ) = _wp_get_primary_and_additional_mime_types( $image_file, $attachment_id );
$missing_sizes = wp_get_missing_image_subsizes( $attachment_id );
// Generate missing 'full' image files for additional mime types.
if ( ! empty( $additional_mime_types ) ) {
if ( isset( $image_meta['sources'] ) ) {
$missing_mime_types = array_diff( $additional_mime_types, array_keys( $image_meta['sources'] ) );
} else {
$missing_mime_types = $additional_mime_types;
}
if ( ! empty( $missing_mime_types ) ) {
$image_meta = _wp_make_additional_mime_types( $missing_mime_types, $image_file, $image_meta, $attachment_id );
}
if ( empty( $missing_sizes ) ) {
return $image_meta;
}
// Generate missing image sub-sizes for each mime type.
$all_mime_types = array_merge( array( $primary_mime_type ), $additional_mime_types );
foreach ( $all_mime_types as $mime_type ) {
$missing_sizes = wp_get_missing_image_subsizes( $attachment_id, $mime_type );
if ( empty( $missing_sizes ) ) {
continue;
}
// This also updates the image meta.
$image_meta = _wp_make_subsizes( $missing_sizes, $image_file, $image_meta, $attachment_id, $mime_type );
}
// This also updates the image meta.
$image_meta = _wp_make_subsizes( $missing_sizes, $image_file, $image_meta, $attachment_id );
}
/** This filter is documented in wp-admin/includes/image.php */
@ -268,13 +222,12 @@ function _wp_image_meta_replace_original( $saved_data, $original_file, $image_me
}
/**
* Creates image mime variations and sub-sizes, adds the new data to the image meta `sizes` array, and updates the image metadata.
* Creates image sub-sizes, adds the new data to the image meta `sizes` array, and updates the image metadata.
*
* Intended for use after an image is uploaded. Saves/updates the image metadata after each
* sub-size is created. If there was an error, it is added to the returned image metadata array.
*
* @since 5.3.0
* @since 6.1.0 Generates sub-sizes in alternate mime types based on the `wp_image_mime_transforms` filter.
*
* @param string $file Full path to the image file.
* @param int $attachment_id Attachment ID to process.
@ -295,7 +248,6 @@ function wp_create_image_subsizes( $file, $attachment_id ) {
'file' => _wp_relative_upload_path( $file ),
'filesize' => wp_filesize( $file ),
'sizes' => array(),
'sources' => array(),
);
// Fetch additional metadata from EXIF/IPTC.
@ -305,127 +257,9 @@ function wp_create_image_subsizes( $file, $attachment_id ) {
$image_meta['image_meta'] = $exif_meta;
}
// Get the primary and additional mime types to generate.
list( $primary_mime_type, $additional_mime_types ) = _wp_get_primary_and_additional_mime_types( $file, $attachment_id );
list( $editor, $resized, $rotated ) = _wp_maybe_scale_and_rotate_image( $file, $attachment_id, $imagesize, $exif_meta, $primary_mime_type );
if ( is_wp_error( $editor ) ) {
return $image_meta;
}
$suffix = _wp_get_image_suffix( $resized, $rotated );
// Save image only if either it was modified or if the primary mime type is different from the original.
if ( ! empty( $suffix ) || $primary_mime_type !== $imagesize['mime'] ) {
$saved = $editor->save( $editor->generate_filename( $suffix ) );
if ( ! is_wp_error( $saved ) ) {
$image_meta = _wp_image_meta_replace_original( $saved, $file, $image_meta, $attachment_id );
// If the image was rotated update the stored EXIF data.
if ( true === $rotated && ! empty( $image_meta['image_meta']['orientation'] ) ) {
$image_meta['image_meta']['orientation'] = 1;
}
} else {
// TODO: Log errors.
}
}
// Set 'sources' for the primary mime type.
$image_meta['sources'][ $primary_mime_type ] = _wp_get_sources_from_meta( $image_meta );
/*
* Initial save of the new metadata.
* At this point the file was uploaded and moved to the uploads directory
* but the image sub-sizes haven't been created yet and the `sizes` array is empty.
*/
wp_update_attachment_metadata( $attachment_id, $image_meta );
if ( ! empty( $additional_mime_types ) ) {
// Use the original file's exif_meta orientation and size information for secondary mime generation to ensure
// sub-sized images are correctly scaled and rotated.
// Save data.
$saved_meta = array();
$saved_meta['orientation'] = $image_meta['image_meta']['orientation'];
$saved_meta['width'] = $image_meta['width'];
$saved_meta['height'] = $image_meta['height'];
// Temporarily set the image meta to the original file's meta.
$image_meta['image_meta']['orientation'] = $exif_meta['orientation'];
$image_meta['width'] = $imagesize[0];
$image_meta['height'] = $imagesize[1];
$image_meta = _wp_make_additional_mime_types( $additional_mime_types, $file, $image_meta, $attachment_id );
// Restore the saved meta data.
$image_meta['image_meta']['orientation'] = $saved_meta['orientation'];
$image_meta['width'] = $saved_meta['width'];
$image_meta['height'] = $saved_meta['height'];
}
$new_sizes = wp_get_registered_image_subsizes();
/**
* Filters the image sizes automatically generated when uploading an image.
*
* @since 2.9.0
* @since 4.4.0 Added the `$image_meta` argument.
* @since 5.3.0 Added the `$attachment_id` argument.
*
* @param array $new_sizes Associative array of image sizes to be created.
* @param array $image_meta The image meta data: width, height, file, sizes, etc.
* @param int $attachment_id The attachment post ID for the image.
*/
$new_sizes = apply_filters( 'intermediate_image_sizes_advanced', $new_sizes, $image_meta, $attachment_id );
$image_meta = _wp_make_subsizes( $new_sizes, $file, $image_meta, $attachment_id, $primary_mime_type );
// Filter secondary mime types to those sizes that are enabled.
$new_sizes = _wp_filter_image_sizes_additional_mime_type_support( $new_sizes, $attachment_id );
foreach ( $additional_mime_types as $additional_mime_type ) {
$image_meta = _wp_make_subsizes( $new_sizes, $file, $image_meta, $attachment_id, $additional_mime_type );
}
return $image_meta;
}
/**
* Returns a WP_Image_Editor instance where the image file has been scaled and rotated as necessary.
*
* @since 6.1.0
* @access private
*
* @param string $file Full path to the image file.
* @param int $attachment_id Attachment ID.
* @param array $imagesize {
* Indexed array of the image width and height in pixels.
*
* @type int $0 The image width.
* @type int $1 The image height.
* }
* @param array|null $exif_meta EXIF metadata if extracted from the image file.
* @param string $mime_type Output mime type.
* @return array Array with three entries: The WP_Image_Editor instance, whether the image was resized, and whether the
* image was rotated (booleans). Each entry can alternatively be a WP_Error in case something went wrong.
*/
function _wp_maybe_scale_and_rotate_image( $file, $attachment_id, $imagesize, $exif_meta, $mime_type ) {
$resized = false;
$rotated = false;
$editor = wp_get_image_editor( $file, array( 'mime_type' => $mime_type ) );
if ( is_wp_error( $editor ) ) {
// This image cannot be edited.
return array( $editor, $resized, $rotated );
}
if ( ! empty( $mime_type ) ) {
$editor->set_output_mime_type( $mime_type );
}
// Do not scale (large) PNG images. May result in sub-sizes that have greater file size than the original. See #48736.
if ( 'image/png' !== $mime_type ) {
if ( 'image/png' !== $imagesize['mime'] ) {
/**
* Filters the "BIG image" threshold value.
*
@ -451,65 +285,96 @@ function _wp_maybe_scale_and_rotate_image( $file, $attachment_id, $imagesize, $e
// If the original image's dimensions are over the threshold,
// scale the image and use it as the "full" size.
if ( $threshold && ( $imagesize[0] > $threshold || $imagesize[1] > $threshold ) ) {
if ( $threshold && ( $image_meta['width'] > $threshold || $image_meta['height'] > $threshold ) ) {
$editor = wp_get_image_editor( $file );
if ( is_wp_error( $editor ) ) {
// This image cannot be edited.
return $image_meta;
}
// Resize the image.
$resized = $editor->resize( $threshold, $threshold );
$rotated = null;
// If there is EXIF data, rotate according to EXIF Orientation.
if ( ! is_wp_error( $resized ) && is_array( $exif_meta ) ) {
$rotated = $editor->maybe_exif_rotate();
$resized = $editor->maybe_exif_rotate();
$rotated = $resized;
}
if ( ! is_wp_error( $resized ) ) {
// Append "-scaled" to the image file name. It will look like "my_image-scaled.jpg".
// This doesn't affect the sub-sizes names as they are generated from the original image (for best quality).
$saved = $editor->save( $editor->generate_filename( 'scaled' ) );
if ( ! is_wp_error( $saved ) ) {
$image_meta = _wp_image_meta_replace_original( $saved, $file, $image_meta, $attachment_id );
// If the image was rotated update the stored EXIF data.
if ( true === $rotated && ! empty( $image_meta['image_meta']['orientation'] ) ) {
$image_meta['image_meta']['orientation'] = 1;
}
} else {
// TODO: Log errors.
}
} else {
// TODO: Log errors.
}
} elseif ( ! empty( $exif_meta['orientation'] ) && 1 !== (int) $exif_meta['orientation'] ) {
// Rotate the whole original image if there is EXIF data and "orientation" is not 1.
$editor = wp_get_image_editor( $file );
if ( is_wp_error( $editor ) ) {
// This image cannot be edited.
return $image_meta;
}
// Rotate the image.
$rotated = $editor->maybe_exif_rotate();
if ( true === $rotated ) {
// Append `-rotated` to the image file name.
$saved = $editor->save( $editor->generate_filename( 'rotated' ) );
if ( ! is_wp_error( $saved ) ) {
$image_meta = _wp_image_meta_replace_original( $saved, $file, $image_meta, $attachment_id );
// Update the stored EXIF data.
if ( ! empty( $image_meta['image_meta']['orientation'] ) ) {
$image_meta['image_meta']['orientation'] = 1;
}
} else {
// TODO: Log errors.
}
}
}
}
return array( $editor, $resized, $rotated );
}
/*
* Initial save of the new metadata.
* At this point the file was uploaded and moved to the uploads directory
* but the image sub-sizes haven't been created yet and the `sizes` array is empty.
*/
wp_update_attachment_metadata( $attachment_id, $image_meta );
/**
* Gets the suffix to use for image files based on resizing and rotating.
*
* @since 6.1.0
* @access private
*
* @param bool|WP_Error Whether the image was resized, or an error if resizing failed.
* @param bool|WP_Error Whether the image was rotated, or an error if rotating failed.
* @return string The suffix to use for the file name, or empty string if none.
*/
function _wp_get_image_suffix( $resized, $rotated ) {
if ( $resized && ! is_wp_error( $resized ) ) {
// Append "-scaled" to the image file name. It will look like "my_image-scaled.jpg".
// This doesn't affect the sub-sizes names as they are generated from the original image (for best quality).
return 'scaled';
}
$new_sizes = wp_get_registered_image_subsizes();
if ( true === $rotated ) {
// Append `-rotated` to the image file name.
return 'rotated';
}
/**
* Filters the image sizes automatically generated when uploading an image.
*
* @since 2.9.0
* @since 4.4.0 Added the `$image_meta` argument.
* @since 5.3.0 Added the `$attachment_id` argument.
*
* @param array $new_sizes Associative array of image sizes to be created.
* @param array $image_meta The image meta data: width, height, file, sizes, etc.
* @param int $attachment_id The attachment post ID for the image.
*/
$new_sizes = apply_filters( 'intermediate_image_sizes_advanced', $new_sizes, $image_meta, $attachment_id );
if ( is_wp_error( $resized ) || is_wp_error( $rotated ) ) {
// TODO: Log errors.
}
return '';
}
/**
* Gets a sources array element from a meta.
*
* @since 6.1.0
* @access private
*
* @param array $meta The meta to get the source from.
* @return array The source array element.
*/
function _wp_get_sources_from_meta( $meta ) {
return array(
'file' => isset( $meta['file'] ) ? wp_basename( $meta['file'] ) : '',
'filesize' => isset( $meta['filesize'] ) ? $meta['filesize'] : wp_filesize( $meta['path'] ),
);
return _wp_make_subsizes( $new_sizes, $file, $image_meta, $attachment_id );
}
/**
@ -519,26 +384,20 @@ function _wp_get_sources_from_meta( $meta ) {
* Errors are stored in the returned image metadata array.
*
* @since 5.3.0
* @since 6.1.0 The $mime_type parameter was added.
* @access private
*
* @param array $new_sizes Array defining what sizes to create.
* @param string $file Full path to the image file.
* @param array $image_meta The attachment meta data array.
* @param int $attachment_id Attachment ID to process.
* @param string $mime_type Optional. The mime type to check for missing sizes. Default is the image mime of $file.
* @param array $new_sizes Array defining what sizes to create.
* @param string $file Full path to the image file.
* @param array $image_meta The attachment meta data array.
* @param int $attachment_id Attachment ID to process.
* @return array The attachment meta data with updated `sizes` array. Includes an array of errors encountered while resizing.
*/
function _wp_make_subsizes( $new_sizes, $file, $image_meta, $attachment_id, $mime_type = '' ) {
function _wp_make_subsizes( $new_sizes, $file, $image_meta, $attachment_id ) {
if ( empty( $image_meta ) || ! is_array( $image_meta ) ) {
// Not an image attachment.
return array();
}
if ( ! $mime_type ) {
$mime_type = wp_get_image_mime( $file );
}
// Check if any of the new sizes already exist.
if ( isset( $image_meta['sizes'] ) && is_array( $image_meta['sizes'] ) ) {
foreach ( $image_meta['sizes'] as $size_name => $size_meta ) {
@ -548,11 +407,7 @@ function _wp_make_subsizes( $new_sizes, $file, $image_meta, $attachment_id, $mim
* To change the behavior, unset changed/mismatched sizes in the `sizes` array in image meta.
*/
if ( array_key_exists( $size_name, $new_sizes ) ) {
// Unset the size if it is either the required mime type already exists either as main mime type or
// within sources.
if ( $size_meta['mime-type'] === $mime_type || isset( $size_meta['sources'][ $mime_type ] ) ) {
unset( $new_sizes[ $size_name ] );
}
unset( $new_sizes[ $size_name ] );
}
}
} else {
@ -578,15 +433,13 @@ function _wp_make_subsizes( $new_sizes, $file, $image_meta, $attachment_id, $mim
$new_sizes = array_filter( array_merge( $priority, $new_sizes ) );
$editor = wp_get_image_editor( $file, array( 'mime_type' => $mime_type ) );
$editor = wp_get_image_editor( $file );
if ( is_wp_error( $editor ) ) {
// The image cannot be edited.
return $image_meta;
}
$editor->set_output_mime_type( $mime_type );
// If stored EXIF data exists, rotate the source image before creating sub-sizes.
if ( ! empty( $image_meta['image_meta'] ) ) {
$rotated = $editor->maybe_exif_rotate();
@ -604,22 +457,7 @@ function _wp_make_subsizes( $new_sizes, $file, $image_meta, $attachment_id, $mim
// TODO: Log errors.
} else {
// Save the size meta value.
if ( ! isset( $image_meta['sizes'][ $new_size_name ] ) ) {
$image_meta['sizes'][ $new_size_name ] = $new_size_meta;
} else {
// Remove any newly generated images that are larger than the primary mime type.
$new_size = isset( $new_size_meta['filesize'] ) ? $new_size_meta['filesize'] : 0;
$primary_size = isset( $image_meta['sizes'][ $new_size_name ]['filesize'] ) ? $image_meta['sizes'][ $new_size_name ]['filesize'] : 0;
if ( $new_size && $primary_size && $new_size >= $primary_size ) {
wp_delete_file( dirname( $file ) . '/' . $new_size_meta['file'] );
continue;
}
}
if ( ! isset( $image_meta['sizes'][ $new_size_name ]['sources'] ) ) {
$image_meta['sizes'][ $new_size_name ]['sources'] = array();
}
$image_meta['sizes'][ $new_size_name ]['sources'][ $mime_type ] = _wp_get_sources_from_meta( $new_size_meta );
$image_meta['sizes'][ $new_size_name ] = $new_size_meta;
wp_update_attachment_metadata( $attachment_id, $image_meta );
}
}
@ -628,112 +466,7 @@ function _wp_make_subsizes( $new_sizes, $file, $image_meta, $attachment_id, $mim
$created_sizes = $editor->multi_resize( $new_sizes );
if ( ! empty( $created_sizes ) ) {
foreach ( $created_sizes as $created_size_name => $created_size_meta ) {
// Primary mime type is set in 'sizes' array.
if ( ! isset( $image_meta['sizes'][ $created_size_name ] ) ) {
$image_meta['sizes'][ $created_size_name ] = $created_size_meta;
} else {
// Remove any newly generated images that are larger than the primary mime type.
$new_size = isset( $created_size_meta['filesize'] ) ? $created_size_meta['filesize'] : 0;
$primary_size = isset( $image_meta['sizes'][ $created_size_name ]['filesize'] ) ? $image_meta['sizes'][ $created_size_name ]['filesize'] : 0;
if ( $new_size && $primary_size && $new_size >= $primary_size ) {
wp_delete_file( dirname( $file ) . '/' . $created_size_meta['file'] );
continue;
}
}
if ( ! isset( $image_meta['sizes'][ $created_size_name ]['sources'] ) ) {
$image_meta['sizes'][ $created_size_name ]['sources'] = array();
}
$image_meta['sizes'][ $created_size_name ]['sources'][ $mime_type ] = _wp_get_sources_from_meta( $created_size_meta );
}
wp_update_attachment_metadata( $attachment_id, $image_meta );
}
}
return $image_meta;
}
/**
* Filters the list of image size objects that support secondary mime type output.
*
* @since 6.1.0
*
* @param array $sizes Associative array of image sizes.
* @param int $attachment_id Attachment ID.
* @return array $sizes Filtered $sizes with only those that support secondary mime type output.
*/
function _wp_filter_image_sizes_additional_mime_type_support( $sizes, $attachment_id ) {
// Include only the core sizes that do not rely on add_image_size(). Additional image sizes are opt-in.
$enabled_sizes = array(
'thumbnail' => true,
'medium' => true,
'medium_large' => true,
'large' => true,
'post-thumbnail' => true,
);
/**
* Filter the sizes that support secondary mime type output. Developers can use this
* to control the output of additional mime type sub-sized images.
*
* @since 6.1.0
*
* @param array $enabled_sizes Map of size names and whether they support secondary mime type output.
* @param int $attachment_id Attachment ID.
*/
$enabled_sizes = apply_filters( 'wp_image_sizes_with_additional_mime_type_support', $enabled_sizes, $attachment_id );
// Filter supported sizes to only include enabled sizes.
return array_intersect_key( $sizes, array_filter( $enabled_sizes ) );
}
/**
* Low-level function to create full-size images in additional mime types.
*
* Updates the image meta after each mime type image is created.
*
* @since 6.1.0
* @access private
*
* @param array $new_mime_types Array defining what mime types to create.
* @param string $file Full path to the image file.
* @param array $image_meta The attachment meta data array.
* @param int $attachment_id Attachment ID to process.
* @return array The attachment meta data with updated `sizes` array. Includes an array of errors encountered while resizing.
*/
function _wp_make_additional_mime_types( $new_mime_types, $file, $image_meta, $attachment_id ) {
$imagesize = array(
$image_meta['width'],
$image_meta['height'],
);
$exif_meta = isset( $image_meta['image_meta'] ) ? $image_meta['image_meta'] : null;
$original_file_size = isset( $image_meta['filesize'] ) ? $image_meta['filesize'] : wp_filesize( $file );
foreach ( $new_mime_types as $mime_type ) {
list( $editor, $resized, $rotated ) = _wp_maybe_scale_and_rotate_image( $file, $attachment_id, $imagesize, $exif_meta, $mime_type );
if ( is_wp_error( $editor ) ) {
// The image cannot be edited.
continue;
}
$suffix = _wp_get_image_suffix( $resized, $rotated );
$extension = wp_get_default_extension_for_mime_type( $mime_type );
$saved = $editor->save( $editor->generate_filename( $suffix, null, $extension ) );
if ( is_wp_error( $saved ) ) {
// TODO: Log errors.
} else {
// If the saved image is larger than the original, discard it.
$filesize = isset( $saved['filesize'] ) ? $saved['filesize'] : wp_filesize( $saved['path'] );
if ( $filesize && $original_file_size && $filesize > $original_file_size ) {
wp_delete_file( $saved['path'] );
continue;
}
$image_meta['sources'][ $mime_type ] = _wp_get_sources_from_meta( $saved );
$image_meta['sizes'] = array_merge( $image_meta['sizes'], $created_sizes );
wp_update_attachment_metadata( $attachment_id, $image_meta );
}
}
@ -827,9 +560,9 @@ function wp_generate_attachment_metadata( $attachment_id, $file ) {
* @param array $uploaded {
* Information about the newly-uploaded file.
*
* @type string $file Filename of the newly-uploaded file.
* @type string $url URL of the uploaded file.
* @type string $type File type.
* @type string $file Filename of the newly-uploaded file.
* @type string $url URL of the uploaded file.
* @type string $type File type.
* }
*/
$image_attachment = apply_filters( 'attachment_thumbnail_args', $image_attachment, $metadata, $uploaded );
@ -897,7 +630,7 @@ function wp_generate_attachment_metadata( $attachment_id, $file ) {
wp_update_attachment_metadata( $attachment_id, $metadata );
// Create sub-sizes saving the image meta after each.
$metadata = _wp_make_subsizes( $merged_sizes, $image_file, $metadata, $attachment_id, '' );
$metadata = _wp_make_subsizes( $merged_sizes, $image_file, $metadata, $attachment_id );
}
}
}
@ -1424,97 +1157,3 @@ function _copy_image_file( $attachment_id ) {
return $dst_file;
}
/**
* Returns an array with the list of valid mime types that a specific mime type should be converted into.
* For example an `image/jpeg` should be converted into an `image/jpeg` and `image/webp`. The first type
* is considered the primary output type for this image.
*
* Called for each uploaded image to determine the list of mime types that should be converted into. Then,
* called again for each image size as they are generated to check if the image should be converted into the mime type
* for that size.
*
* @since 6.1.0
*
* @param int $attachment_id The attachment ID.
* @return array An array of valid mime types, where the key is the source file mime type and the list of mime types to
* generate.
*/
function wp_upload_image_mime_transforms( $attachment_id ) {
$default_image_mime_transforms = array(
'image/jpeg' => array( 'image/jpeg', 'image/webp' ),
'image/webp' => array( 'image/webp', 'image/jpeg' ),
);
$image_mime_transforms = $default_image_mime_transforms;
/**
* Filters the output mime types for a given input mime type and image size.
*
* @since 6.1.0
*
* @param array $image_mime_transforms A map with the valid mime transforms where the key is the source file mime type
* and the value is one or more mime file types to generate.
* @param int $attachment_id The ID of the attachment where the hook was dispatched.
*/
$image_mime_transforms = apply_filters( 'wp_upload_image_mime_transforms', $image_mime_transforms, $attachment_id );
if ( ! is_array( $image_mime_transforms ) ) {
return $default_image_mime_transforms;
}
return array_map(
function( $transforms_list ) {
return (array) $transforms_list;
},
$image_mime_transforms
);
}
/**
* Extracts the primary and additional mime output types for an image from the $image_mime_transforms.
*
* @since 6.1.0
* @access private
*
* @param string $file Full path to the image file.
* @param int $attachment_id Attachment ID to process.
* @return array An array with two entries, the primary mime type and the list of additional mime types.
*/
function _wp_get_primary_and_additional_mime_types( $file, $attachment_id ) {
$image_mime_transforms = wp_upload_image_mime_transforms( $attachment_id );
$original_mime_type = wp_get_image_mime( $file );
$output_mime_types = isset( $image_mime_transforms[ $original_mime_type ] ) ? $image_mime_transforms[ $original_mime_type ] : array( $original_mime_type );
// Exclude any output mime types that the system doesn't support.
$output_mime_types = array_values(
array_filter(
$output_mime_types,
function( $mime_type ) {
return wp_image_editor_supports(
array(
'mime_type' => $mime_type,
)
);
}
)
);
// Handle an empty value for $output_mime_types: only output the original type.
if ( empty( $output_mime_types ) ) {
return array( $original_mime_type, array() );
}
// Use original mime type as primary mime type, or alternatively the first one.
$primary_mime_type_key = array_search( $original_mime_type, $output_mime_types, true );
if ( false === $primary_mime_type_key ) {
$primary_mime_type_key = 0;
}
// Split output mime types into primary mime type and additional mime types.
$additional_mime_types = $output_mime_types;
list( $primary_mime_type ) = array_splice( $additional_mime_types, $primary_mime_type_key, 1 );
return array(
$primary_mime_type,
$additional_mime_types,
);
}

View File

@ -334,11 +334,6 @@ abstract class WP_Image_Editor {
protected function get_output_format( $filename = null, $mime_type = null ) {
$new_ext = null;
// If no mime type is passed but output mime type is set, use that.
if ( ! $mime_type && ! empty( $this->output_mime_type ) ) {
$mime_type = $this->output_mime_type;
}
// By default, assume specified type takes priority.
if ( $mime_type ) {
$new_ext = $this->get_extension( $mime_type );
@ -430,25 +425,18 @@ abstract class WP_Image_Editor {
}
/**
* Builds an output filename based on current file, and adding proper suffix.
* Builds an output filename based on current file, and adding proper suffix
*
* @since 3.5.0
* @since 6.1.0 Skips adding a suffix when set to an empty string. When the
* file extension being generated doesn't match the image file extension,
* add the extension to the suffix
*
* @param string $suffix Optional. Suffix to add to the filename. The default null
* will result in a 'widthxheight' suffix. Passing
* an empty string will result in no suffix.
* @param string $dest_path Optional. The path to save the file to. The default null
* will use the image file path.
* @param string $extension Optional. The file extension to use. The default null
* will use the image file extension.
* @return string filename The generated file name.
* @param string $suffix
* @param string $dest_path
* @param string $extension
* @return string filename
*/
public function generate_filename( $suffix = null, $dest_path = null, $extension = null ) {
// $suffix will be appended to the destination filename, just before the extension.
if ( null === $suffix ) {
if ( ! $suffix ) {
$suffix = $this->get_suffix();
}
@ -469,21 +457,7 @@ abstract class WP_Image_Editor {
}
}
if ( empty( $suffix ) ) {
$suffix = '';
} else {
$suffix = "-{$suffix}";
}
// When the file extension being generated doesn't match the image file extension,
// add the extension to the suffix to ensure a unique file name. Prevents
// name conflicts when a single image type can have multiple extensions,
// eg. .jpg, .jpeg and .jpe are all valid JPEG extensions.
if ( ! empty( $extension ) && $extension !== $ext ) {
$suffix .= "-{$ext}";
}
return trailingslashit( $dir ) . "{$name}{$suffix}.{$new_ext}";
return trailingslashit( $dir ) . "{$name}-{$suffix}.{$new_ext}";
}
/**
@ -663,28 +637,5 @@ abstract class WP_Image_Editor {
return wp_get_default_extension_for_mime_type( $mime_type );
}
/**
* Set the editor output mime type, useful when outputting alternate mime types.
*
* Track that the mime type is set with the mime type set flag.
*
* @since 6.1.0
*
* @param string $output_mime_type The mime type to set.
*/
public function set_output_mime_type( $output_mime_type ) {
$this->output_mime_type = $output_mime_type;
}
/**
* Reset the mime type to the original file mime type.
*
* Reset the mime type set flag.
*
* @since 6.1.0
*/
public function reset_output_mime_type() {
$this->output_mime_type = $this->mime_type;
}
}

View File

@ -486,7 +486,7 @@ jQuery( document ).ready( function( $ ) {
times = tryAgainCount[ file.id ];
if ( times && times > 8 ) {
if ( times && times > 4 ) {
/*
* The file may have been uploaded and attachment post created,
* but post-processing and resizing failed...

File diff suppressed because one or more lines are too long

View File

@ -138,7 +138,7 @@ window.wp = window.wp || {};
times = tryAgainCount[ file.id ];
if ( times && times > 8 ) {
if ( times && times > 4 ) {
/*
* The file may have been uploaded and attachment post created,
* but post-processing and resizing failed...

File diff suppressed because one or more lines are too long

View File

@ -1852,11 +1852,6 @@ function wp_filter_content_tags( $content, $context = null ) {
$filtered_image = wp_img_tag_add_decoding_attr( $filtered_image, $context );
}
// Use alternate mime types when specified and available.
if ( $attachment_id > 0 && _wp_in_front_end_context() ) {
$filtered_image = wp_image_use_alternate_mime_types( $filtered_image, $context, $attachment_id );
}
/**
* Filters an img tag within the content for a given context.
*
@ -1903,117 +1898,6 @@ function wp_filter_content_tags( $content, $context = null ) {
return $content;
}
/**
* Use alternate mime type images in the front end content output when available.
*
* @since 6.1.0
*
* @param string $image The HTML `img` tag where the attribute should be added.
* @param string $context Additional context to pass to the filters.
* @param int $attachment_id The attachment ID.
* @return string Converted `img` tag with `loading` attribute added.
*/
function wp_image_use_alternate_mime_types( $image, $context, $attachment_id ) {
$metadata = wp_get_attachment_metadata( $attachment_id );
if ( empty( $metadata['file'] ) ) {
return $image;
}
// Only alter images with a `sources` attribute
if ( empty( $metadata['sources'] ) ) {
return $image;
};
$target_mimes = array( 'image/webp', 'image/jpeg' );
/**
* Filter the content image mime type output selection and order.
*
* When outputting images in the content, the first mime type available will be used.
*
* @since 6.1.0
*
* @param array $target_mimes The image output mime type and order. Default is array( 'image/webp', 'image/jpeg' ).
* @param int $attachment_id The attachment ID.
* @param string $context Additional context to pass to the filters.
* @return array The filtered output mime type and order. Return an empty array to skip mime type substitution.
*/
$target_mimes = apply_filters( 'wp_content_image_mimes', $target_mimes, $attachment_id, $context );
if ( false === $target_mimes ) {
return $image;
}
// Find the appropriate size for the provided URL in the first available mime type.
foreach ( $target_mimes as $target_mime ) {
// Handle full size image replacement.
if ( ! empty( $metadata['sources'][ $target_mime ]['file'] ) ) {
$src_filename = wp_basename( $metadata['file'] );
// This is the same MIME type as the original, so the entire $target_mime can be skipped.
// Since it is already the preferred MIME type, the entire loop can be cancelled.
if ( $metadata['sources'][ $target_mime ]['file'] === $src_filename ) {
break;
}
$image = str_replace( $src_filename, $metadata['sources'][ $target_mime ]['file'], $image );
// The full size was replaced, so unset this entirely here so that in the next iteration it is no longer
// considered, simply for a small performance optimization.
unset( $metadata['sources'] );
}
// Go through each image size and replace with the first available mime type version.
foreach ( $metadata['sizes'] as $name => $size_data ) {
// Check if size has an original file.
if ( empty( $size_data['file'] ) ) {
continue;
}
// Check if size has a source in the desired mime type.
if ( empty( $size_data['sources'][ $target_mime ]['file'] ) ) {
continue;
}
$src_filename = wp_basename( $size_data['file'] );
// This is the same MIME type as the original, so the entire $target_mime can be skipped.
// Since it is already the preferred MIME type, the entire loop can be cancelled.
if ( $size_data['sources'][ $target_mime ]['file'] === $src_filename ) {
break 2;
}
// Found a match, replace with the new filename.
$image = str_replace( $src_filename, $size_data['sources'][ $target_mime ]['file'], $image );
// This size was replaced, so unset this entirely here so that in the next iteration it is no longer
// considered, simply for a small performance optimization.
unset( $metadata['sizes'][ $name ] );
}
}
return $image;
}
/**
* Check if execution is currently in the front end content context, outside of <head>.
*
* @since 6.1.0
* @access private
*
* @return bool True if in the front end content context, false otherwise.
*/
function _wp_in_front_end_context() {
global $wp_query;
// Check if this request is generally outside (or before) any frontend context.
if ( ! isset( $wp_query ) || defined( 'XMLRPC_REQUEST' ) || defined( 'REST_REQUEST' ) || is_feed() ) {
return false;
}
// Check if we're anywhere before the 'wp_head' action has completed.
return did_action( 'template_redirect' ) && ! doing_action( 'wp_head' );
}
/**
* Adds `loading` attribute to an `img` HTML tag.
*

View File

@ -6486,28 +6486,13 @@ function wp_delete_attachment_files( $post_id, $meta, $backup_sizes, $file ) {
$intermediate_dir = path_join( $uploadpath['basedir'], dirname( $file ) );
foreach ( $meta['sizes'] as $size => $sizeinfo ) {
$intermediate_file = str_replace( wp_basename( $file ), $sizeinfo['file'], $file );
// Check for alternate size mime types in the sizeinfo['sources'] array to delete.
if ( isset( $sizeinfo['sources'] ) && is_array( $sizeinfo['sources'] ) ) {
foreach ( $sizeinfo['sources'] as $mime => $properties ) {
$intermediate_file = str_replace( wp_basename( $file ), $properties['file'], $file );
if ( ! empty( $intermediate_file ) ) {
$intermediate_file = path_join( $uploadpath['basedir'], $intermediate_file );
if ( ! wp_delete_file_from_directory( $intermediate_file, $intermediate_dir ) ) {
$deleted = false;
}
}
}
} else {
// Otherwise, delete files from the sizeinfo data.
$intermediate_file = str_replace( wp_basename( $file ), $sizeinfo['file'], $file );
if ( ! empty( $intermediate_file ) ) {
$intermediate_file = path_join( $uploadpath['basedir'], $intermediate_file );
if ( ! empty( $intermediate_file ) ) {
$intermediate_file = path_join( $uploadpath['basedir'], $intermediate_file );
if ( ! wp_delete_file_from_directory( $intermediate_file, $intermediate_dir ) ) {
$deleted = false;
}
if ( ! wp_delete_file_from_directory( $intermediate_file, $intermediate_dir ) ) {
$deleted = false;
}
}
}
@ -6529,58 +6514,24 @@ function wp_delete_attachment_files( $post_id, $meta, $backup_sizes, $file ) {
}
}
// Delete the full size images from 'sources' if available, or the root file.
if ( isset( $meta['sources'] ) && is_array( $meta['sources'] ) ) {
$sources = $meta['sources'];
$intermediate_dir = path_join( $uploadpath['basedir'], dirname( $file ) );
foreach ( $sources as $mime => $properties ) {
if ( ! is_array( $properties ) || empty( $properties['file'] ) ) {
continue;
if ( is_array( $backup_sizes ) ) {
$del_dir = path_join( $uploadpath['basedir'], dirname( $meta['file'] ) );
foreach ( $backup_sizes as $size ) {
$del_file = path_join( dirname( $meta['file'] ), $size['file'] );
if ( ! empty( $del_file ) ) {
$del_file = path_join( $uploadpath['basedir'], $del_file );
if ( ! wp_delete_file_from_directory( $del_file, $del_dir ) ) {
$deleted = false;
}
}
$intermediate_file = str_replace( wp_basename( $file ), $properties['file'], $file );
if ( ! wp_delete_file_from_directory( $intermediate_file, $intermediate_dir ) ) {
$deleted = false;
}
}
} else {
if ( ! wp_delete_file_from_directory( $file, $uploadpath['basedir'] ) ) {
$deleted = false;
}
}
if ( is_array( $backup_sizes ) ) {
$del_dir = path_join( $uploadpath['basedir'], dirname( $meta['file'] ) );
// Delete the root (edited) file which was not deleted above.
if ( ! wp_delete_file_from_directory( $file, $uploadpath['basedir'] ) ) {
$deleted = false;
}
foreach ( $backup_sizes as $size ) {
// Delete files from 'sources' data if available, otherwise from 'sizes' data.
if ( isset( $meta['sources'] ) && is_array( $meta['sources'] ) ) {
// Delete any backup images stored in the 'sources' array.
if ( isset( $size['sources'] ) && is_array( $size['sources'] ) ) {
foreach ( $size['sources'] as $mime => $properties ) {
$del_file = path_join( dirname( $meta['file'] ), $properties['file'] );
if ( ! empty( $del_file ) ) {
$del_file = path_join( $uploadpath['basedir'], $del_file );
if ( ! wp_delete_file_from_directory( $del_file, $del_dir ) ) {
$deleted = false;
}
}
}
}
} else {
$del_file = path_join( dirname( $meta['file'] ), $size['file'] );
if ( ! empty( $del_file ) ) {
$del_file = path_join( $uploadpath['basedir'], $del_file );
if ( ! wp_delete_file_from_directory( $del_file, $del_dir ) ) {
$deleted = false;
}
}
}
}
if ( ! wp_delete_file_from_directory( $file, $uploadpath['basedir'] ) ) {
$deleted = false;
}
return $deleted;

View File

@ -783,15 +783,6 @@ class WP_REST_Attachments_Controller extends WP_REST_Posts_Controller {
}
$size_data['source_url'] = $image_src[0];
if ( empty( $size_data['sources'] ) || ! is_array( $size_data['sources'] ) ) {
continue;
}
$image_url_basename = wp_basename( $image_src[0] );
foreach ( $size_data['sources'] as $mime => &$mime_details ) {
$mime_details['source_url'] = str_replace( $image_url_basename, $mime_details['file'], $image_src[0] );
}
}
$full_src = wp_get_attachment_image_src( $post->ID, 'full' );
@ -804,15 +795,6 @@ class WP_REST_Attachments_Controller extends WP_REST_Posts_Controller {
'mime_type' => $post->post_mime_type,
'source_url' => $full_src[0],
);
if ( ! empty( $data['media_details']['sources'] ) ) {
$full_url_basename = wp_basename( $full_src[0] );
foreach ( $data['media_details']['sources'] as $mime => &$mime_details ) {
$mime_details['source_url'] = str_replace( $full_url_basename, $mime_details['file'], $full_src[0] );
}
$data['media_details']['sizes']['full']['sources'] = $data['media_details']['sources'];
unset( $data['media_details']['sources'] );
}
}
} else {
$data['media_details']['sizes'] = new stdClass;

View File

@ -16,7 +16,7 @@
*
* @global string $wp_version
*/
$wp_version = '6.1-alpha-54084';
$wp_version = '6.1-alpha-54085';
/**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.