wp/wp-admin/includes/image.php
changeset 18 be944660c56a
parent 16 a86126ab1dd4
child 19 3d72ae0968f4
--- a/wp/wp-admin/includes/image.php	Tue Dec 15 15:52:01 2020 +0100
+++ b/wp/wp-admin/includes/image.php	Wed Sep 21 18:19:35 2022 +0200
@@ -11,15 +11,15 @@
  *
  * @since 2.1.0
  *
- * @param string|int $src      The source file or Attachment ID.
- * @param int        $src_x    The start x position to crop from.
- * @param int        $src_y    The start y position to crop from.
- * @param int        $src_w    The width to crop.
- * @param int        $src_h    The height to crop.
- * @param int        $dst_w    The destination width.
- * @param int        $dst_h    The destination height.
- * @param bool       $src_abs  Optional. If the source crop points are absolute.
- * @param string     $dst_file Optional. The destination file to write to.
+ * @param string|int   $src      The source file or Attachment ID.
+ * @param int          $src_x    The start x position to crop from.
+ * @param int          $src_y    The start y position to crop from.
+ * @param int          $src_w    The width to crop.
+ * @param int          $src_h    The height to crop.
+ * @param int          $dst_w    The destination width.
+ * @param int          $dst_h    The destination height.
+ * @param bool|false   $src_abs  Optional. If the source crop points are absolute.
+ * @param string|false $dst_file Optional. The destination file to write to.
  * @return string|WP_Error New filepath on success, WP_Error on failure.
  */
 function wp_crop_image( $src, $src_x, $src_y, $src_w, $src_h, $dst_w, $dst_h, $src_abs = false, $dst_file = false ) {
@@ -93,7 +93,7 @@
 	// Use the originally uploaded image dimensions as full_width and full_height.
 	if ( ! empty( $image_meta['original_image'] ) ) {
 		$image_file = wp_get_original_image_path( $attachment_id );
-		$imagesize  = @getimagesize( $image_file );
+		$imagesize  = wp_getimagesize( $image_file );
 	}
 
 	if ( ! empty( $imagesize ) ) {
@@ -224,7 +224,7 @@
  * @return array The image attachment meta data.
  */
 function wp_create_image_subsizes( $file, $attachment_id ) {
-	$imagesize = @getimagesize( $file );
+	$imagesize = wp_getimagesize( $file );
 
 	if ( empty( $imagesize ) ) {
 		// File is not an image.
@@ -470,7 +470,7 @@
  *
  * @param int    $attachment_id Attachment Id to process.
  * @param string $file          Filepath of the Attached image.
- * @return mixed Metadata for attachment.
+ * @return array Metadata for attachment.
  */
 function wp_generate_attachment_metadata( $attachment_id, $file ) {
 	$attachment = get_post( $attachment_id );
@@ -490,6 +490,15 @@
 		$support  = current_theme_supports( 'post-thumbnails', 'attachment:audio' ) || post_type_supports( 'attachment:audio', 'thumbnail' );
 	}
 
+	/*
+	 * wp_read_video_metadata() and wp_read_audio_metadata() return `false`
+	 * if the attachment does not exist in the local filesystem,
+	 * so make sure to convert the value to an array.
+	 */
+	if ( ! is_array( $metadata ) ) {
+		$metadata = array();
+	}
+
 	if ( $support && ! empty( $metadata['image']['data'] ) ) {
 		// Check for existing cover.
 		$hash   = md5( $metadata['image']['data'] );
@@ -517,6 +526,9 @@
 				case 'image/png':
 					$ext = '.png';
 					break;
+				case 'image/webp':
+					$ext = '.webp';
+					break;
 			}
 			$basename = str_replace( '.', '-', wp_basename( $file ) ) . '-image' . $ext;
 			$uploaded = wp_upload_bits( $basename, '', $metadata['image']['data'] );
@@ -613,9 +625,7 @@
 	}
 
 	// Remove the blob of binary data from the array.
-	if ( $metadata ) {
-		unset( $metadata['image']['data'] );
-	}
+	unset( $metadata['image']['data'] );
 
 	/**
 	 * Filters the generated attachment meta data.
@@ -680,14 +690,14 @@
  * @since 2.5.0
  *
  * @param string $file
- * @return bool|array False on failure. Image metadata array on success.
+ * @return array|false Image metadata array on success, false on failure.
  */
 function wp_read_image_metadata( $file ) {
 	if ( ! file_exists( $file ) ) {
 		return false;
 	}
 
-	list( , , $image_type ) = @getimagesize( $file );
+	list( , , $image_type ) = wp_getimagesize( $file );
 
 	/*
 	 * EXIF contains a bunch of data we'll probably never need formatted in ways
@@ -711,15 +721,24 @@
 	);
 
 	$iptc = array();
+	$info = array();
 	/*
 	 * Read IPTC first, since it might contain data not available in exif such
 	 * as caption, description etc.
 	 */
 	if ( is_callable( 'iptcparse' ) ) {
-		@getimagesize( $file, $info );
+		wp_getimagesize( $file, $info );
 
 		if ( ! empty( $info['APP13'] ) ) {
-			$iptc = @iptcparse( $info['APP13'] );
+			// Don't silence errors when in debug mode, unless running unit tests.
+			if ( defined( 'WP_DEBUG' ) && WP_DEBUG
+				&& ! defined( 'WP_RUN_CORE_TESTS' )
+			) {
+				$iptc = iptcparse( $info['APP13'] );
+			} else {
+				// phpcs:ignore WordPress.PHP.NoSilencedErrors -- Silencing notice and warning is intentional. See https://core.trac.wordpress.org/ticket/42480
+				$iptc = @iptcparse( $info['APP13'] );
+			}
 
 			// Headline, "A brief synopsis of the caption".
 			if ( ! empty( $iptc['2#105'][0] ) ) {
@@ -779,7 +798,15 @@
 	$exif_image_types = apply_filters( 'wp_read_image_metadata_types', array( IMAGETYPE_JPEG, IMAGETYPE_TIFF_II, IMAGETYPE_TIFF_MM ) );
 
 	if ( is_callable( 'exif_read_data' ) && in_array( $image_type, $exif_image_types, true ) ) {
-		$exif = @exif_read_data( $file );
+		// Don't silence errors when in debug mode, unless running unit tests.
+		if ( defined( 'WP_DEBUG' ) && WP_DEBUG
+			&& ! defined( 'WP_RUN_CORE_TESTS' )
+		) {
+			$exif = exif_read_data( $file );
+		} else {
+			// phpcs:ignore WordPress.PHP.NoSilencedErrors -- Silencing notice and warning is intentional. See https://core.trac.wordpress.org/ticket/42480
+			$exif = @exif_read_data( $file );
+		}
 
 		if ( ! empty( $exif['ImageDescription'] ) ) {
 			mbstring_binary_safe_encoding();
@@ -877,7 +904,7 @@
  * @return bool True if valid image, false if not valid image.
  */
 function file_is_valid_image( $path ) {
-	$size = @getimagesize( $path );
+	$size = wp_getimagesize( $path );
 	return ! empty( $size );
 }
 
@@ -890,9 +917,9 @@
  * @return bool True if suitable, false if not suitable.
  */
 function file_is_displayable_image( $path ) {
-	$displayable_image_types = array( IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG, IMAGETYPE_BMP, IMAGETYPE_ICO );
+	$displayable_image_types = array( IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG, IMAGETYPE_BMP, IMAGETYPE_ICO, IMAGETYPE_WEBP ); // phpcs:ignore PHPCompatibility.Constants.NewConstants.imagetype_webpFound
 
-	$info = @getimagesize( $path );
+	$info = wp_getimagesize( $path );
 	if ( empty( $info ) ) {
 		$result = false;
 	} elseif ( ! in_array( $info[2], $displayable_image_types, true ) ) {
@@ -917,10 +944,12 @@
  *
  * @since 2.9.0
  *
- * @param string $attachment_id Attachment ID.
- * @param string $mime_type Image mime type.
- * @param string $size Optional. Image size, defaults to 'full'.
- * @return resource|false The resulting image resource on success, false on failure.
+ * @param int          $attachment_id Attachment ID.
+ * @param string       $mime_type     Image mime type.
+ * @param string|int[] $size          Optional. Image size. Accepts any registered image size name, or an array
+ *                                    of width and height values in pixels (in that order). Default 'full'.
+ * @return resource|GdImage|false The resulting image resource or GdImage instance on success,
+ *                                false on failure.
  */
 function load_image_to_edit( $attachment_id, $mime_type, $size = 'full' ) {
 	$filepath = _load_image_to_edit_path( $attachment_id, $size );
@@ -938,41 +967,52 @@
 		case 'image/gif':
 			$image = imagecreatefromgif( $filepath );
 			break;
+		case 'image/webp':
+			$image = false;
+			if ( function_exists( 'imagecreatefromwebp' ) ) {
+				$image = imagecreatefromwebp( $filepath );
+			}
+			break;
 		default:
 			$image = false;
 			break;
 	}
-	if ( is_resource( $image ) ) {
+
+	if ( is_gd_image( $image ) ) {
 		/**
 		 * Filters the current image being loaded for editing.
 		 *
 		 * @since 2.9.0
 		 *
-		 * @param resource $image         Current image.
-		 * @param string   $attachment_id Attachment ID.
-		 * @param string   $size          Image size.
+		 * @param resource|GdImage $image         Current image.
+		 * @param int              $attachment_id Attachment ID.
+		 * @param string|int[]     $size          Requested image size. Can be any registered image size name, or
+		 *                                        an array of width and height values in pixels (in that order).
 		 */
 		$image = apply_filters( 'load_image_to_edit', $image, $attachment_id, $size );
+
 		if ( function_exists( 'imagealphablending' ) && function_exists( 'imagesavealpha' ) ) {
 			imagealphablending( $image, false );
 			imagesavealpha( $image, true );
 		}
 	}
+
 	return $image;
 }
 
 /**
- * Retrieve the path or url of an attachment's attached file.
+ * Retrieve the path or URL of an attachment's attached file.
  *
  * If the attached file is not present on the local filesystem (usually due to replication plugins),
- * then the url of the file is returned if url fopen is supported.
+ * then the URL of the file is returned if `allow_url_fopen` is supported.
  *
  * @since 3.4.0
  * @access private
  *
- * @param string $attachment_id Attachment ID.
- * @param string $size Optional. Image size, defaults to 'full'.
- * @return string|false File path or url on success, false on failure.
+ * @param int          $attachment_id Attachment ID.
+ * @param string|int[] $size          Optional. Image size. Accepts any registered image size name, or an array
+ *                                    of width and height values in pixels (in that order). Default 'full'.
+ * @return string|false File path or URL on success, false on failure.
  */
 function _load_image_to_edit_path( $attachment_id, $size = 'full' ) {
 	$filepath = get_attached_file( $attachment_id );
@@ -985,30 +1025,32 @@
 				$filepath = path_join( dirname( $filepath ), $data['file'] );
 
 				/**
-				 * Filters the path to the current image.
+				 * Filters the path to an attachment's file when editing the image.
 				 *
 				 * The filter is evaluated for all image sizes except 'full'.
 				 *
 				 * @since 3.1.0
 				 *
-				 * @param string $path          Path to the current image.
-				 * @param string $attachment_id Attachment ID.
-				 * @param string $size          Size of the image.
+				 * @param string       $path          Path to the current image.
+				 * @param int          $attachment_id Attachment ID.
+				 * @param string|int[] $size          Requested image size. Can be any registered image size name, or
+				 *                                    an array of width and height values in pixels (in that order).
 				 */
 				$filepath = apply_filters( 'load_image_to_edit_filesystempath', $filepath, $attachment_id, $size );
 			}
 		}
 	} elseif ( function_exists( 'fopen' ) && ini_get( 'allow_url_fopen' ) ) {
 		/**
-		 * Filters the image URL if not in the local filesystem.
+		 * Filters the path to an attachment's URL when editing the image.
 		 *
-		 * The filter is only evaluated if fopen is enabled on the server.
+		 * The filter is only evaluated if the file isn't stored locally and `allow_url_fopen` is enabled on the server.
 		 *
 		 * @since 3.1.0
 		 *
-		 * @param string $image_url     Current image URL.
-		 * @param string $attachment_id Attachment ID.
-		 * @param string $size          Size of the image.
+		 * @param string|false $image_url     Current image URL.
+		 * @param int          $attachment_id Attachment ID.
+		 * @param string|int[] $size          Requested image size. Can be any registered image size name, or
+		 *                                    an array of width and height values in pixels (in that order).
 		 */
 		$filepath = apply_filters( 'load_image_to_edit_attachmenturl', wp_get_attachment_url( $attachment_id ), $attachment_id, $size );
 	}
@@ -1018,9 +1060,10 @@
 	 *
 	 * @since 2.9.0
 	 *
-	 * @param string|bool $filepath      File path or URL to current image, or false.
-	 * @param string      $attachment_id Attachment ID.
-	 * @param string      $size          Size of the image.
+	 * @param string|false $filepath      File path or URL to current image, or false.
+	 * @param int          $attachment_id Attachment ID.
+	 * @param string|int[] $size          Requested image size. Can be any registered image size name, or
+	 *                                    an array of width and height values in pixels (in that order).
 	 */
 	return apply_filters( 'load_image_to_edit_path', $filepath, $attachment_id, $size );
 }
@@ -1031,7 +1074,7 @@
  * @since 3.4.0
  * @access private
  *
- * @param string $attachment_id Attachment ID.
+ * @param int $attachment_id Attachment ID.
  * @return string|false New file path on success, false on failure.
  */
 function _copy_image_file( $attachment_id ) {