diff -r 7b1b88e27a20 -r 48c4eec2b7e6 wp/wp-admin/includes/image-edit.php --- a/wp/wp-admin/includes/image-edit.php Thu Sep 29 08:06:27 2022 +0200 +++ b/wp/wp-admin/includes/image-edit.php Fri Sep 05 18:40:08 2025 +0200 @@ -28,40 +28,44 @@ die( __( 'Image data does not exist. Please re-upload the image.' ) ); } - $sizer = $big > 400 ? 400 / $big : 1; + $sizer = $big > 600 ? 600 / $big : 1; $backup_sizes = get_post_meta( $post_id, '_wp_attachment_backup_sizes', true ); $can_restore = false; + if ( ! empty( $backup_sizes ) && isset( $backup_sizes['full-orig'], $meta['file'] ) ) { $can_restore = wp_basename( $meta['file'] ) !== $backup_sizes['full-orig']['file']; } if ( $msg ) { if ( isset( $msg->error ) ) { - $note = ""; + $note = ""; } elseif ( isset( $msg->msg ) ) { - $note = ""; + $note = ""; } } - $edit_custom_sizes = false; + /** - * Filters whether custom sizes are available options for image editing. + * Shows the settings in the Image Editor that allow selecting to edit only the thumbnail of an image. * - * @since 6.0.0 + * @since 6.3.0 * - * @param bool|string[] $edit_custom_sizes True if custom sizes can be edited or array of custom size names. + * @param bool $show Whether to show the settings in the Image Editor. Default false. */ - $edit_custom_sizes = apply_filters( 'edit_custom_thumbnail_sizes', $edit_custom_sizes ); + $edit_thumbnails_separately = (bool) apply_filters( 'image_edit_thumbnails_separately', false ); + ?>
- -
- + +
- + + +
+ +
- - + + + ' . __( 'Image rotation is not supported by your web host.' ) . '

'; ?> - - - - - - - -
+ + + +
+ + + +
+
+
+
- -
- - - - - - - - -
- -
- -
- - )" disabled="disabled" class="button button-primary imgedit-submit-btn" value="" /> + +
-
-
-
-

- -
-

+
+
+ + + + + + + + +
+
+ +
- -

- ' . $meta['width'] . ' × ' . $meta['height'] . '' - ); - ?> -

- -
- -
- -
- - - - - - ! -
, 'scale')" class="button button-primary" value="" />
-
-
- -
-
-
+
+
+
+
+
+

+ +
+

+
+ +

+ ' . $meta['width'] . ' × ' . $meta['height'] . '' + ); + ?> +

+ +
+
+ +
+ + + + + + +
+ +
+
+
+
+
- - -
-
-

-
-

- +

+
+

+
+

+ +

+
+ , 'restore')" class="button button-primary" value="" /> +
+
+
+
+ +
+
+
+

+ +
+

+


+

- if ( ! defined( 'IMAGE_EDIT_OVERWRITE' ) || ! IMAGE_EDIT_OVERWRITE ) { - echo ' ' . __( 'Previously edited copies of the image will not be deleted.' ); - } - ?> -

-
- , 'restore')" class="button button-primary" value="" /> -
-
-
-
- - - -
-
-

- - -
-

- -


-

- -


-

+


+

+
+
+
+ +
+ + + + + +
+
+
+ +
+ + + + + +
+
+
+ +
+ + + + + +
+
+
+ +
+
-
- -
- - - - - -
-
- -
- -
- - - - - -
-
- -
-
-
-

- -
-

+
+

+ +
+

+
+
+
+
+ +
+
+
+
+ + + + + + + + + + + + + + + + + +
+
+
+
+
-
- -
-
- -
-
- - - - - - - - - - - - - - - - - $size ) { - if ( array_key_exists( $size, $meta['sizes'] ) ) { - if ( 'thumbnail' === $size ) { - continue; - } - ?> - - - - - -
-
- - -
- -
@@ -341,6 +390,12 @@ return imagewebp( $image, null, 90 ); } return false; + case 'image/avif': + if ( function_exists( 'imageavif' ) ) { + header( 'Content-Type: image/avif' ); + return imageavif( $image, null, 90 ); + } + return false; default: return false; } @@ -351,12 +406,26 @@ * Saves image to file. * * @since 2.9.0 + * @since 3.5.0 The `$image` parameter expects a `WP_Image_Editor` instance. + * @since 6.0.0 The `$filesize` value was added to the returned array. * * @param string $filename Name of the file to be saved. * @param WP_Image_Editor $image The image editor instance. * @param string $mime_type The mime type of the image. * @param int $post_id Attachment post ID. - * @return bool True on success, false on failure. + * @return array|WP_Error|bool { + * Array on success or WP_Error if the file failed to save. + * When called with a deprecated value for the `$image` parameter, + * i.e. a non-`WP_Image_Editor` image resource or `GdImage` instance, + * the function will return true on success, false on failure. + * + * @type string $path Path to the image file. + * @type string $file Name of the image file. + * @type int $width Image width. + * @type int $height Image height. + * @type string $mime-type The mime type of the image. + * @type int $filesize File size of the image. + * } */ function wp_save_image_file( $filename, $image, $mime_type, $post_id ) { if ( $image instanceof WP_Image_Editor ) { @@ -431,6 +500,11 @@ return imagewebp( $image, $filename ); } return false; + case 'image/avif': + if ( function_exists( 'imageavif' ) ) { + return imageavif( $image, $filename ); + } + return false; default: return false; } @@ -449,7 +523,7 @@ */ function _image_get_preview_ratio( $w, $h ) { $max = max( $w, $h ); - return $max > 400 ? ( 400 / $max ) : 1; + return $max > 600 ? ( 600 / $max ) : 1; } /** @@ -574,15 +648,18 @@ $obj->sel = $obj->c; unset( $obj->c ); } + $changes[ $key ] = $obj; } // Combine operations. if ( count( $changes ) > 1 ) { $filtered = array( $changes[0] ); + for ( $i = 0, $j = 1, $c = count( $changes ); $j < $c; $j++ ) { $combined = false; - if ( $filtered[ $i ]->type == $changes[ $j ]->type ) { + + if ( $filtered[ $i ]->type === $changes[ $j ]->type ) { switch ( $filtered[ $i ]->type ) { case 'rotate': $filtered[ $i ]->angle += $changes[ $j ]->angle; @@ -594,10 +671,12 @@ break; } } + if ( ! $combined ) { $filtered[ ++$i ] = $changes[ $j ]; } } + $changes = $filtered; unset( $filtered ); } @@ -631,7 +710,7 @@ foreach ( $changes as $operation ) { switch ( $operation->type ) { case 'rotate': - if ( 0 != $operation->angle ) { + if ( 0 !== $operation->angle ) { if ( $image instanceof WP_Image_Editor ) { $image->rotate( $operation->angle ); } else { @@ -640,11 +719,11 @@ } break; case 'flip': - if ( 0 != $operation->axis ) { + if ( 0 !== $operation->axis ) { if ( $image instanceof WP_Image_Editor ) { - $image->flip( ( $operation->axis & 1 ) != 0, ( $operation->axis & 2 ) != 0 ); + $image->flip( ( $operation->axis & 1 ) !== 0, ( $operation->axis & 2 ) !== 0 ); } else { - $image = _flip_image_resource( $image, ( $operation->axis & 1 ) != 0, ( $operation->axis & 2 ) != 0 ); + $image = _flip_image_resource( $image, ( $operation->axis & 1 ) !== 0, ( $operation->axis & 2 ) !== 0 ); } } break; @@ -657,7 +736,7 @@ $h = $size['height']; $scale = 1 / _image_get_preview_ratio( $w, $h ); // Discard preview scaling. - $image->crop( $sel->x * $scale, $sel->y * $scale, $sel->w * $scale, $sel->h * $scale ); + $image->crop( (int) ( $sel->x * $scale ), (int) ( $sel->y * $scale ), (int) ( $sel->w * $scale ), (int) ( $sel->h * $scale ) ); } else { $scale = 1 / _image_get_preview_ratio( imagesx( $image ), imagesy( $image ) ); // Discard preview scaling. $image = _crop_image_resource( $image, $sel->x * $scale, $sel->y * $scale, $sel->w * $scale, $sel->h * $scale ); @@ -725,7 +804,7 @@ $backup_sizes = get_post_meta( $post_id, '_wp_attachment_backup_sizes', true ); $old_backup_sizes = $backup_sizes; $restored = false; - $msg = new stdClass; + $msg = new stdClass(); if ( ! is_array( $backup_sizes ) ) { $msg->error = __( 'Cannot load image metadata.' ); @@ -739,9 +818,8 @@ if ( isset( $backup_sizes['full-orig'] ) && is_array( $backup_sizes['full-orig'] ) ) { $data = $backup_sizes['full-orig']; - if ( $parts['basename'] != $data['file'] ) { + if ( $parts['basename'] !== $data['file'] ) { if ( defined( 'IMAGE_EDIT_OVERWRITE' ) && IMAGE_EDIT_OVERWRITE ) { - // Delete only if it's an edited image. if ( preg_match( '/-e[0-9]{13}\./', $parts['basename'] ) ) { wp_delete_file( $file ); @@ -766,9 +844,9 @@ foreach ( $default_sizes as $default_size ) { if ( isset( $backup_sizes[ "$default_size-orig" ] ) ) { $data = $backup_sizes[ "$default_size-orig" ]; - if ( isset( $meta['sizes'][ $default_size ] ) && $meta['sizes'][ $default_size ]['file'] != $data['file'] ) { + + if ( isset( $meta['sizes'][ $default_size ] ) && $meta['sizes'][ $default_size ]['file'] !== $data['file'] ) { if ( defined( 'IMAGE_EDIT_OVERWRITE' ) && IMAGE_EDIT_OVERWRITE ) { - // Delete only if it's an edited image. if ( preg_match( '/-e[0-9]{13}-/', $meta['sizes'][ $default_size ]['file'] ) ) { $delete_file = path_join( $parts['dirname'], $meta['sizes'][ $default_size ]['file'] ); @@ -785,9 +863,9 @@ } } - if ( ! wp_update_attachment_metadata( $post_id, $meta ) || - ( $old_backup_sizes !== $backup_sizes && ! update_post_meta( $post_id, '_wp_attachment_backup_sizes', $backup_sizes ) ) ) { - + if ( ! wp_update_attachment_metadata( $post_id, $meta ) + || ( $old_backup_sizes !== $backup_sizes && ! update_post_meta( $post_id, '_wp_attachment_backup_sizes', $backup_sizes ) ) + ) { $msg->error = __( 'Cannot save image metadata.' ); return $msg; } @@ -796,6 +874,10 @@ $msg->error = __( 'Image metadata is inconsistent.' ); } else { $msg->msg = __( 'Image restored successfully.' ); + + if ( defined( 'IMAGE_EDIT_OVERWRITE' ) && IMAGE_EDIT_OVERWRITE ) { + delete_post_meta( $post_id, '_wp_attachment_backup_sizes' ); + } } return $msg; @@ -813,7 +895,7 @@ function wp_save_image( $post_id ) { $_wp_additional_image_sizes = wp_get_additional_image_sizes(); - $return = new stdClass; + $return = new stdClass(); $success = false; $delete = false; $scaled = false; @@ -821,33 +903,44 @@ $post = get_post( $post_id ); $img = wp_get_image_editor( _load_image_to_edit_path( $post_id, 'full' ) ); + if ( is_wp_error( $img ) ) { $return->error = esc_js( __( 'Unable to create new image.' ) ); return $return; } - $fwidth = ! empty( $_REQUEST['fwidth'] ) ? (int) $_REQUEST['fwidth'] : 0; - $fheight = ! empty( $_REQUEST['fheight'] ) ? (int) $_REQUEST['fheight'] : 0; - $target = ! empty( $_REQUEST['target'] ) ? preg_replace( '/[^a-z0-9_-]+/i', '', $_REQUEST['target'] ) : ''; - $scale = ! empty( $_REQUEST['do'] ) && 'scale' === $_REQUEST['do']; + $full_width = ! empty( $_REQUEST['fwidth'] ) ? (int) $_REQUEST['fwidth'] : 0; + $full_height = ! empty( $_REQUEST['fheight'] ) ? (int) $_REQUEST['fheight'] : 0; + $target = ! empty( $_REQUEST['target'] ) ? preg_replace( '/[^a-z0-9_-]+/i', '', $_REQUEST['target'] ) : ''; + $scale = ! empty( $_REQUEST['do'] ) && 'scale' === $_REQUEST['do']; + + /** This filter is documented in wp-admin/includes/image-edit.php */ + $edit_thumbnails_separately = (bool) apply_filters( 'image_edit_thumbnails_separately', false ); - if ( $scale && $fwidth > 0 && $fheight > 0 ) { - $size = $img->get_size(); - $sX = $size['width']; - $sY = $size['height']; + if ( $scale ) { + $size = $img->get_size(); + $original_width = $size['width']; + $original_height = $size['height']; - // Check if it has roughly the same w / h ratio. - $diff = round( $sX / $sY, 2 ) - round( $fwidth / $fheight, 2 ); - if ( -0.1 < $diff && $diff < 0.1 ) { - // Scale the full size image. - if ( $img->resize( $fwidth, $fheight ) ) { - $scaled = true; - } + if ( $full_width > $original_width || $full_height > $original_height ) { + $return->error = esc_js( __( 'Images cannot be scaled to a size larger than the original.' ) ); + return $return; } - if ( ! $scaled ) { - $return->error = esc_js( __( 'Error while saving the scaled image. Please reload the page and try again.' ) ); - return $return; + if ( $full_width > 0 && $full_height > 0 ) { + // Check if it has roughly the same w / h ratio. + $diff = round( $original_width / $original_height, 2 ) - round( $full_width / $full_height, 2 ); + if ( -0.1 < $diff && $diff < 0.1 ) { + // Scale the full size image. + if ( $img->resize( $full_width, $full_height ) ) { + $scaled = true; + } + } + + if ( ! $scaled ) { + $return->error = esc_js( __( 'Error while saving the scaled image. Please reload the page and try again.' ) ); + return $return; + } } } elseif ( ! empty( $_REQUEST['history'] ) ) { $changes = json_decode( wp_unslash( $_REQUEST['history'] ) ); @@ -880,10 +973,11 @@ $filename = pathinfo( $path, PATHINFO_FILENAME ); $suffix = time() . rand( 100, 999 ); - if ( defined( 'IMAGE_EDIT_OVERWRITE' ) && IMAGE_EDIT_OVERWRITE && - isset( $backup_sizes['full-orig'] ) && $backup_sizes['full-orig']['file'] != $basename ) { + if ( defined( 'IMAGE_EDIT_OVERWRITE' ) && IMAGE_EDIT_OVERWRITE + && isset( $backup_sizes['full-orig'] ) && $backup_sizes['full-orig']['file'] !== $basename + ) { - if ( 'thumbnail' === $target ) { + if ( $edit_thumbnails_separately && 'thumbnail' === $target ) { $new_path = "{$dirname}/{$filename}-temp.{$ext}"; } else { $new_path = $path; @@ -894,8 +988,9 @@ $filename .= "-e{$suffix}"; $new_filename = "{$filename}.{$ext}"; $new_path = "{$dirname}/$new_filename"; + if ( file_exists( $new_path ) ) { - $suffix++; + ++$suffix; } else { break; } @@ -910,8 +1005,11 @@ if ( 'nothumb' === $target || 'all' === $target || 'full' === $target || $scaled ) { $tag = false; + if ( isset( $backup_sizes['full-orig'] ) ) { - if ( ( ! defined( 'IMAGE_EDIT_OVERWRITE' ) || ! IMAGE_EDIT_OVERWRITE ) && $backup_sizes['full-orig']['file'] !== $basename ) { + if ( ( ! defined( 'IMAGE_EDIT_OVERWRITE' ) || ! IMAGE_EDIT_OVERWRITE ) + && $backup_sizes['full-orig']['file'] !== $basename + ) { $tag = "full-$suffix"; } } else { @@ -925,6 +1023,7 @@ 'file' => $basename, ); } + $success = ( $path === $new_path ) || update_attached_file( $post_id, $new_path ); $meta['file'] = _wp_relative_upload_path( $new_path ); @@ -933,29 +1032,21 @@ $meta['width'] = $size['width']; $meta['height'] = $size['height']; - if ( $success ) { + if ( $success && ( 'nothumb' === $target || 'all' === $target ) ) { $sizes = get_intermediate_image_sizes(); - if ( 'nothumb' === $target || 'all' === $target ) { - if ( 'nothumb' === $target ) { - $sizes = array_diff( $sizes, array( 'thumbnail' ) ); - } - } elseif ( 'thumbnail' !== $target ) { - $sizes = array_diff( $sizes, array( $target ) ); + + if ( $edit_thumbnails_separately && 'nothumb' === $target ) { + $sizes = array_diff( $sizes, array( 'thumbnail' ) ); } } $return->fw = $meta['width']; $return->fh = $meta['height']; - } elseif ( 'thumbnail' === $target ) { + } elseif ( $edit_thumbnails_separately && 'thumbnail' === $target ) { $sizes = array( 'thumbnail' ); $success = true; $delete = true; $nocrop = true; - } else { - $sizes = array( $target ); - $success = true; - $delete = true; - $nocrop = $_wp_additional_image_sizes[ $size ]['crop']; } /* @@ -978,9 +1069,12 @@ foreach ( $sizes as $size ) { $tag = false; + if ( isset( $meta['sizes'][ $size ] ) ) { if ( isset( $backup_sizes[ "$size-orig" ] ) ) { - if ( ( ! defined( 'IMAGE_EDIT_OVERWRITE' ) || ! IMAGE_EDIT_OVERWRITE ) && $backup_sizes[ "$size-orig" ]['file'] != $meta['sizes'][ $size ]['file'] ) { + if ( ( ! defined( 'IMAGE_EDIT_OVERWRITE' ) || ! IMAGE_EDIT_OVERWRITE ) + && $backup_sizes[ "$size-orig" ]['file'] !== $meta['sizes'][ $size ]['file'] + ) { $tag = "$size-$suffix"; } } else { @@ -1021,10 +1115,12 @@ if ( 'thumbnail' === $target || 'all' === $target || 'full' === $target ) { // Check if it's an image edit from attachment edit screen. if ( ! empty( $_REQUEST['context'] ) && 'edit-attachment' === $_REQUEST['context'] ) { - $thumb_url = wp_get_attachment_image_src( $post_id, array( 900, 600 ), true ); + $thumb_url = wp_get_attachment_image_src( $post_id, array( 900, 600 ), true ); + $return->thumbnail = $thumb_url[0]; } else { $file_url = wp_get_attachment_url( $post_id ); + if ( ! empty( $meta['sizes']['thumbnail'] ) ) { $thumb = $meta['sizes']['thumbnail']; $return->thumbnail = path_join( dirname( $file_url ), $thumb['file'] ); @@ -1042,5 +1138,6 @@ } $return->msg = esc_js( __( 'Image saved' ) ); + return $return; }