From c7a48687b5819e6b906499328bf7949830a9d2c9 Mon Sep 17 00:00:00 2001 From: joedolson Date: Sat, 2 Mar 2024 20:15:13 +0000 Subject: [PATCH] Media: Accessibility: Copy attachment properties on site icon crop. Add parity between site icon, custom header, and default image crop behaviors. [53027] fixed a bug where alt text and caption were not copied on custom headers, but did not apply that change in any other context. Deprecate the `create_attachment_object` method in the `Wp_Site_Icon` and `Custom_Image_Header` classes and replace that functionality with the new function `wp_copy_parent_attachment_properties()` to improve consistency. Props afercia, rcreators, jorbin, joedolson, huzaifaalmesbah, shailu25, swissspidy, mukesh27. Fixes #60524. Built from https://develop.svn.wordpress.org/trunk@57755 git-svn-id: http://core.svn.wordpress.org/trunk@57256 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- wp-admin/includes/ajax-actions.php | 49 ++-------------- .../includes/class-custom-image-header.php | 6 +- wp-admin/includes/class-wp-site-icon.php | 3 + wp-admin/includes/image.php | 56 +++++++++++++++++++ wp-includes/version.php | 2 +- 5 files changed, 70 insertions(+), 46 deletions(-) diff --git a/wp-admin/includes/ajax-actions.php b/wp-admin/includes/ajax-actions.php index f8b6ac4589..30aab700b4 100644 --- a/wp-admin/includes/ajax-actions.php +++ b/wp-admin/includes/ajax-actions.php @@ -4035,9 +4035,10 @@ function wp_ajax_crop_image() { } /** This filter is documented in wp-admin/includes/class-custom-image-header.php */ - $cropped = apply_filters( 'wp_create_file_in_uploads', $cropped, $attachment_id ); // For replication. - $attachment = $wp_site_icon->create_attachment_object( $cropped, $attachment_id ); - unset( $attachment['ID'] ); + $cropped = apply_filters( 'wp_create_file_in_uploads', $cropped, $attachment_id ); // For replication. + + // Copy attachment properties. + $attachment = wp_copy_parent_attachment_properties( $cropped, $attachment_id, $context ); // Update the attachment. add_filter( 'intermediate_image_sizes_advanced', array( $wp_site_icon, 'additional_sizes' ) ); @@ -4065,46 +4066,8 @@ function wp_ajax_crop_image() { /** This filter is documented in wp-admin/includes/class-custom-image-header.php */ $cropped = apply_filters( 'wp_create_file_in_uploads', $cropped, $attachment_id ); // For replication. - $parent_url = wp_get_attachment_url( $attachment_id ); - $parent_basename = wp_basename( $parent_url ); - $url = str_replace( $parent_basename, wp_basename( $cropped ), $parent_url ); - - $size = wp_getimagesize( $cropped ); - $image_type = ( $size ) ? $size['mime'] : 'image/jpeg'; - - // Get the original image's post to pre-populate the cropped image. - $original_attachment = get_post( $attachment_id ); - $sanitized_post_title = sanitize_file_name( $original_attachment->post_title ); - $use_original_title = ( - ( '' !== trim( $original_attachment->post_title ) ) && - /* - * Check if the original image has a title other than the "filename" default, - * meaning the image had a title when originally uploaded or its title was edited. - */ - ( $parent_basename !== $sanitized_post_title ) && - ( pathinfo( $parent_basename, PATHINFO_FILENAME ) !== $sanitized_post_title ) - ); - $use_original_description = ( '' !== trim( $original_attachment->post_content ) ); - - $attachment = array( - 'post_title' => $use_original_title ? $original_attachment->post_title : wp_basename( $cropped ), - 'post_content' => $use_original_description ? $original_attachment->post_content : $url, - 'post_mime_type' => $image_type, - 'guid' => $url, - 'context' => $context, - ); - - // Copy the image caption attribute (post_excerpt field) from the original image. - if ( '' !== trim( $original_attachment->post_excerpt ) ) { - $attachment['post_excerpt'] = $original_attachment->post_excerpt; - } - - // Copy the image alt text attribute from the original image. - if ( '' !== trim( $original_attachment->_wp_attachment_image_alt ) ) { - $attachment['meta_input'] = array( - '_wp_attachment_image_alt' => wp_slash( $original_attachment->_wp_attachment_image_alt ), - ); - } + // Copy attachment properties. + $attachment = wp_copy_parent_attachment_properties( $cropped, $attachment_id, $context ); $attachment_id = wp_insert_attachment( $attachment, $cropped ); $metadata = wp_generate_attachment_metadata( $attachment_id, $cropped ); diff --git a/wp-admin/includes/class-custom-image-header.php b/wp-admin/includes/class-custom-image-header.php index 5c3271478b..20f19593b8 100644 --- a/wp-admin/includes/class-custom-image-header.php +++ b/wp-admin/includes/class-custom-image-header.php @@ -1077,7 +1077,7 @@ endif; /** This filter is documented in wp-admin/includes/class-custom-image-header.php */ $cropped = apply_filters( 'wp_create_file_in_uploads', $cropped, $attachment_id ); // For replication. - $attachment = $this->create_attachment_object( $cropped, $attachment_id ); + $attachment = wp_copy_parent_attachment_properties( $cropped, $attachment_id, 'custom-header' ); if ( ! empty( $_POST['create-new-attachment'] ) ) { unset( $attachment['ID'] ); @@ -1314,12 +1314,14 @@ endif; * Creates an attachment 'object'. * * @since 3.9.0 + * @deprecated 6.5.0 * * @param string $cropped Cropped image URL. * @param int $parent_attachment_id Attachment ID of parent image. * @return array An array with attachment object data. */ final public function create_attachment_object( $cropped, $parent_attachment_id ) { + _deprecated_function( __METHOD__, '6.5.0', 'wp_copy_parent_attachment_properties()' ); $parent = get_post( $parent_attachment_id ); $parent_url = wp_get_attachment_url( $parent->ID ); $url = str_replace( wp_basename( $parent_url ), wp_basename( $cropped ), $parent_url ); @@ -1421,7 +1423,7 @@ endif; /** This filter is documented in wp-admin/includes/class-custom-image-header.php */ $cropped = apply_filters( 'wp_create_file_in_uploads', $cropped, $attachment_id ); // For replication. - $attachment = $this->create_attachment_object( $cropped, $attachment_id ); + $attachment = wp_copy_parent_attachment_properties( $cropped, $attachment_id, 'custom-header' ); $previous = $this->get_previous_crop( $attachment ); diff --git a/wp-admin/includes/class-wp-site-icon.php b/wp-admin/includes/class-wp-site-icon.php index ff417718f6..d14ead34cd 100644 --- a/wp-admin/includes/class-wp-site-icon.php +++ b/wp-admin/includes/class-wp-site-icon.php @@ -78,12 +78,15 @@ class WP_Site_Icon { * Creates an attachment 'object'. * * @since 4.3.0 + * @deprecated 6.5.0 * * @param string $cropped Cropped image URL. * @param int $parent_attachment_id Attachment ID of parent image. * @return array An array with attachment object data. */ public function create_attachment_object( $cropped, $parent_attachment_id ) { + _deprecated_function( __METHOD__, '6.5.0', 'wp_copy_parent_attachment_properties()' ); + $parent = get_post( $parent_attachment_id ); $parent_url = wp_get_attachment_url( $parent->ID ); $url = str_replace( wp_basename( $parent_url ), wp_basename( $cropped ), $parent_url ); diff --git a/wp-admin/includes/image.php b/wp-admin/includes/image.php index 0f4ba818e6..69f58d52ed 100644 --- a/wp-admin/includes/image.php +++ b/wp-admin/includes/image.php @@ -482,6 +482,62 @@ function _wp_make_subsizes( $new_sizes, $file, $image_meta, $attachment_id ) { return $image_meta; } +/** + * Copy parent attachment properties to newly cropped image. + * + * @since 6.5.0 + * + * @param string $cropped Path to the cropped image file. + * @param int $parent_attachment_id Parent file Attachment ID. + * @param string $context Control calling the function. + * @return array Properties of attachment. + */ +function wp_copy_parent_attachment_properties( $cropped, $parent_attachment_id, $context = '' ) { + $parent = get_post( $parent_attachment_id ); + $parent_url = wp_get_attachment_url( $parent->ID ); + $parent_basename = wp_basename( $parent_url ); + $url = str_replace( wp_basename( $parent_url ), wp_basename( $cropped ), $parent_url ); + + $size = wp_getimagesize( $cropped ); + $image_type = $size ? $size['mime'] : 'image/jpeg'; + + $sanitized_post_title = sanitize_file_name( $parent->post_title ); + $use_original_title = ( + ( '' !== trim( $parent->post_title ) ) && + /* + * Check if the original image has a title other than the "filename" default, + * meaning the image had a title when originally uploaded or its title was edited. + */ + ( $parent_basename !== $sanitized_post_title ) && + ( pathinfo( $parent_basename, PATHINFO_FILENAME ) !== $sanitized_post_title ) + ); + $use_original_description = ( '' !== trim( $parent->post_content ) ); + + $attachment = array( + 'post_title' => $use_original_title ? $parent->post_title : wp_basename( $cropped ), + 'post_content' => $use_original_description ? $parent->post_content : $url, + 'post_mime_type' => $image_type, + 'guid' => $url, + 'context' => $context, + ); + + // Copy the image caption attribute (post_excerpt field) from the original image. + if ( '' !== trim( $parent->post_excerpt ) ) { + $attachment['post_excerpt'] = $parent->post_excerpt; + } + + // Copy the image alt text attribute from the original image. + if ( '' !== trim( $parent->_wp_attachment_image_alt ) ) { + $attachment['meta_input'] = array( + '_wp_attachment_image_alt' => wp_slash( $parent->_wp_attachment_image_alt ), + ); + } + + $attachment['post_parent'] = $parent_attachment_id; + + return $attachment; +} + /** * Generates attachment meta data and create image sub-sizes for images. * diff --git a/wp-includes/version.php b/wp-includes/version.php index f26dc4764e..dfa8d6dc88 100644 --- a/wp-includes/version.php +++ b/wp-includes/version.php @@ -16,7 +16,7 @@ * * @global string $wp_version */ -$wp_version = '6.5-beta3-57754'; +$wp_version = '6.5-beta3-57755'; /** * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.