wp/wp-admin/includes/image.php
changeset 7 cf61fcea0001
parent 5 5e2f62d02dcd
child 9 177826044cd9
--- a/wp/wp-admin/includes/image.php	Tue Jun 09 11:14:17 2015 +0000
+++ b/wp/wp-admin/includes/image.php	Mon Oct 14 17:39:30 2019 +0200
@@ -28,7 +28,7 @@
 		$src_file = get_attached_file( $src );
 
 		if ( ! file_exists( $src_file ) ) {
-			// If the file doesn't exist, attempt a url fopen on the src link.
+			// If the file doesn't exist, attempt a URL fopen on the src link.
 			// This can occur with certain file replication plugins.
 			$src = _load_image_to_edit_path( $src, 'full' );
 		} else {
@@ -76,7 +76,9 @@
 
 	$metadata = array();
 	$support = false;
-	if ( preg_match('!^image/!', get_post_mime_type( $attachment )) && file_is_displayable_image($file) ) {
+	$mime_type = get_post_mime_type( $attachment );
+
+	if ( preg_match( '!^image/!', $mime_type ) && file_is_displayable_image( $file ) ) {
 		$imagesize = getimagesize( $file );
 		$metadata['width'] = $imagesize[0];
 		$metadata['height'] = $imagesize[1];
@@ -85,33 +87,46 @@
 		$metadata['file'] = _wp_relative_upload_path($file);
 
 		// Make thumbnails and other intermediate sizes.
-		global $_wp_additional_image_sizes;
+		$_wp_additional_image_sizes = wp_get_additional_image_sizes();
 
 		$sizes = array();
 		foreach ( get_intermediate_image_sizes() as $s ) {
 			$sizes[$s] = array( 'width' => '', 'height' => '', 'crop' => false );
-			if ( isset( $_wp_additional_image_sizes[$s]['width'] ) )
-				$sizes[$s]['width'] = intval( $_wp_additional_image_sizes[$s]['width'] ); // For theme-added sizes
-			else
-				$sizes[$s]['width'] = get_option( "{$s}_size_w" ); // For default sizes set in options
-			if ( isset( $_wp_additional_image_sizes[$s]['height'] ) )
-				$sizes[$s]['height'] = intval( $_wp_additional_image_sizes[$s]['height'] ); // For theme-added sizes
-			else
-				$sizes[$s]['height'] = get_option( "{$s}_size_h" ); // For default sizes set in options
-			if ( isset( $_wp_additional_image_sizes[$s]['crop'] ) )
-				$sizes[$s]['crop'] = $_wp_additional_image_sizes[$s]['crop']; // For theme-added sizes
-			else
-				$sizes[$s]['crop'] = get_option( "{$s}_crop" ); // For default sizes set in options
+			if ( isset( $_wp_additional_image_sizes[$s]['width'] ) ) {
+				// For theme-added sizes
+				$sizes[$s]['width'] = intval( $_wp_additional_image_sizes[$s]['width'] );
+			} else {
+				// For default sizes set in options
+				$sizes[$s]['width'] = get_option( "{$s}_size_w" );
+			}
+
+			if ( isset( $_wp_additional_image_sizes[$s]['height'] ) ) {
+				// For theme-added sizes
+				$sizes[$s]['height'] = intval( $_wp_additional_image_sizes[$s]['height'] );
+			} else {
+				// For default sizes set in options
+				$sizes[$s]['height'] = get_option( "{$s}_size_h" );
+			}
+
+			if ( isset( $_wp_additional_image_sizes[$s]['crop'] ) ) {
+				// For theme-added sizes
+				$sizes[$s]['crop'] = $_wp_additional_image_sizes[$s]['crop'];
+			} else {
+				// For default sizes set in options
+				$sizes[$s]['crop'] = get_option( "{$s}_crop" );
+			}
 		}
 
 		/**
-		 * Filter the image sizes automatically generated when uploading an image.
+		 * Filters the image sizes automatically generated when uploading an image.
 		 *
 		 * @since 2.9.0
+		 * @since 4.4.0 Added the `$metadata` argument.
 		 *
-		 * @param array $sizes An associative array of image sizes.
+		 * @param array $sizes    An associative array of image sizes.
+		 * @param array $metadata An associative array of image metadata: width, height, file.
 		 */
-		$sizes = apply_filters( 'intermediate_image_sizes_advanced', $sizes );
+		$sizes = apply_filters( 'intermediate_image_sizes_advanced', $sizes, $metadata );
 
 		if ( $sizes ) {
 			$editor = wp_get_image_editor( $file );
@@ -170,7 +185,7 @@
 					'post_content' => '',
 				);
 				/**
-				 * Filter the parameters for the attachment thumbnail creation.
+				 * Filters the parameters for the attachment thumbnail creation.
 				 *
 				 * @since 3.9.0
 				 *
@@ -188,13 +203,87 @@
 			}
 		}
 	}
+	// Try to create image thumbnails for PDFs
+	else if ( 'application/pdf' === $mime_type ) {
+		$fallback_sizes = array(
+			'thumbnail',
+			'medium',
+			'large',
+		);
+
+		/**
+		 * Filters the image sizes generated for non-image mime types.
+		 *
+		 * @since 4.7.0
+		 *
+		 * @param array $fallback_sizes An array of image size names.
+		 * @param array $metadata       Current attachment metadata.
+		 */
+		$fallback_sizes = apply_filters( 'fallback_intermediate_image_sizes', $fallback_sizes, $metadata );
+
+		$sizes = array();
+		$_wp_additional_image_sizes = wp_get_additional_image_sizes();
+
+		foreach ( $fallback_sizes as $s ) {
+			if ( isset( $_wp_additional_image_sizes[ $s ]['width'] ) ) {
+				$sizes[ $s ]['width'] = intval( $_wp_additional_image_sizes[ $s ]['width'] );
+			} else {
+				$sizes[ $s ]['width'] = get_option( "{$s}_size_w" );
+			}
+
+			if ( isset( $_wp_additional_image_sizes[ $s ]['height'] ) ) {
+				$sizes[ $s ]['height'] = intval( $_wp_additional_image_sizes[ $s ]['height'] );
+			} else {
+				$sizes[ $s ]['height'] = get_option( "{$s}_size_h" );
+			}
+
+			if ( isset( $_wp_additional_image_sizes[ $s ]['crop'] ) ) {
+				$sizes[ $s ]['crop'] = $_wp_additional_image_sizes[ $s ]['crop'];
+			} else {
+				// Force thumbnails to be soft crops.
+				if ( 'thumbnail' !== $s ) {
+					$sizes[ $s ]['crop'] = get_option( "{$s}_crop" );
+				}
+			}
+		}
+
+		// Only load PDFs in an image editor if we're processing sizes.
+		if ( ! empty( $sizes ) ) {
+			$editor = wp_get_image_editor( $file );
+
+			if ( ! is_wp_error( $editor ) ) { // No support for this type of file
+				/*
+				 * PDFs may have the same file filename as JPEGs.
+				 * Ensure the PDF preview image does not overwrite any JPEG images that already exist.
+				 */
+				$dirname = dirname( $file ) . '/';
+				$ext = '.' . pathinfo( $file, PATHINFO_EXTENSION );
+				$preview_file = $dirname . wp_unique_filename( $dirname, wp_basename( $file, $ext ) . '-pdf.jpg' );
+
+				$uploaded = $editor->save( $preview_file, 'image/jpeg' );
+				unset( $editor );
+
+				// Resize based on the full size image, rather than the source.
+				if ( ! is_wp_error( $uploaded ) ) {
+					$editor = wp_get_image_editor( $uploaded['path'] );
+					unset( $uploaded['path'] );
+
+					if ( ! is_wp_error( $editor ) ) {
+						$metadata['sizes'] = $editor->multi_resize( $sizes );
+						$metadata['sizes']['full'] = $uploaded;
+					}
+				}
+			}
+		}
+	}
 
 	// Remove the blob of binary data from the array.
-	if ( isset( $metadata['image']['data'] ) )
+	if ( $metadata ) {
 		unset( $metadata['image']['data'] );
+	}
 
 	/**
-	 * Filter the generated attachment meta data.
+	 * Filters the generated attachment meta data.
 	 *
 	 * @since 2.1.0
 	 *
@@ -254,7 +343,7 @@
 	if ( ! file_exists( $file ) )
 		return false;
 
-	list( , , $sourceImageType ) = getimagesize( $file );
+	list( , , $sourceImageType ) = @getimagesize( $file );
 
 	/*
 	 * EXIF contains a bunch of data we'll probably never need formatted in ways
@@ -274,17 +363,19 @@
 		'shutter_speed' => 0,
 		'title' => '',
 		'orientation' => 0,
+		'keywords' => array(),
 	);
 
+	$iptc = 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 );
+		@getimagesize( $file, $info );
 
 		if ( ! empty( $info['APP13'] ) ) {
-			$iptc = iptcparse( $info['APP13'] );
+			$iptc = @iptcparse( $info['APP13'] );
 
 			// Headline, "A brief synopsis of the caption."
 			if ( ! empty( $iptc['2#105'][0] ) ) {
@@ -322,11 +413,15 @@
 
 			if ( ! empty( $iptc['2#116'][0] ) ) // copyright
 				$meta['copyright'] = trim( $iptc['2#116'][0] );
+
+			if ( ! empty( $iptc['2#025'][0] ) ) { // keywords array
+				$meta['keywords'] = array_values( $iptc['2#025'] );
+			}
 		 }
 	}
 
 	/**
-	 * Filter the image types to check for exif data.
+	 * Filters the image types to check for exif data.
 	 *
 	 * @since 2.5.0
 	 *
@@ -397,22 +492,26 @@
 		}
 	}
 
-	foreach ( $meta as &$value ) {
-		if ( is_string( $value ) ) {
-			$value = wp_kses_post( $value );
+	foreach ( $meta['keywords'] as $key => $keyword ) {
+		if ( ! seems_utf8( $keyword ) ) {
+			$meta['keywords'][ $key ] = utf8_encode( $keyword );
 		}
 	}
 
+	$meta = wp_kses_post_deep( $meta );
+
 	/**
-	 * Filter the array of meta data read from an image's exif data.
+	 * Filters the array of meta data read from an image's exif data.
 	 *
 	 * @since 2.5.0
+	 * @since 4.4.0 The `$iptc` parameter was added.
 	 *
 	 * @param array  $meta            Image meta data.
 	 * @param string $file            Path to image file.
 	 * @param int    $sourceImageType Type of image.
+	 * @param array  $iptc            IPTC data.
 	 */
-	return apply_filters( 'wp_read_image_metadata', $meta, $file, $sourceImageType );
+	return apply_filters( 'wp_read_image_metadata', $meta, $file, $sourceImageType, $iptc );
 
 }
 
@@ -450,7 +549,7 @@
 	}
 
 	/**
-	 * Filter whether the current image is displayable in the browser.
+	 * Filters whether the current image is displayable in the browser.
 	 *
 	 * @since 2.5.0
 	 *
@@ -491,7 +590,7 @@
 	}
 	if ( is_resource($image) ) {
 		/**
-		 * Filter the current image being loaded for editing.
+		 * Filters the current image being loaded for editing.
 		 *
 		 * @since 2.9.0
 		 *
@@ -527,7 +626,7 @@
 	if ( $filepath && file_exists( $filepath ) ) {
 		if ( 'full' != $size && ( $data = image_get_intermediate_size( $attachment_id, $size ) ) ) {
 			/**
-			 * Filter the path to the current image.
+			 * Filters the path to the current image.
 			 *
 			 * The filter is evaluated for all image sizes except 'full'.
 			 *
@@ -539,9 +638,9 @@
 			 */
 			$filepath = apply_filters( 'load_image_to_edit_filesystempath', path_join( dirname( $filepath ), $data['file'] ), $attachment_id, $size );
 		}
-	} elseif ( function_exists( 'fopen' ) && function_exists( 'ini_get' ) && true == ini_get( 'allow_url_fopen' ) ) {
+	} elseif ( function_exists( 'fopen' ) && true == ini_get( 'allow_url_fopen' ) ) {
 		/**
-		 * Filter the image URL if not in the local filesystem.
+		 * Filters the image URL if not in the local filesystem.
 		 *
 		 * The filter is only evaluated if fopen is enabled on the server.
 		 *
@@ -555,7 +654,7 @@
 	}
 
 	/**
-	 * Filter the returned path or URL of the current image.
+	 * Filters the returned path or URL of the current image.
 	 *
 	 * @since 2.9.0
 	 *