wp/wp-admin/includes/image.php
changeset 7 cf61fcea0001
parent 5 5e2f62d02dcd
child 9 177826044cd9
equal deleted inserted replaced
6:490d5cc509ed 7:cf61fcea0001
    26 	$src_file = $src;
    26 	$src_file = $src;
    27 	if ( is_numeric( $src ) ) { // Handle int as attachment ID
    27 	if ( is_numeric( $src ) ) { // Handle int as attachment ID
    28 		$src_file = get_attached_file( $src );
    28 		$src_file = get_attached_file( $src );
    29 
    29 
    30 		if ( ! file_exists( $src_file ) ) {
    30 		if ( ! file_exists( $src_file ) ) {
    31 			// If the file doesn't exist, attempt a url fopen on the src link.
    31 			// If the file doesn't exist, attempt a URL fopen on the src link.
    32 			// This can occur with certain file replication plugins.
    32 			// This can occur with certain file replication plugins.
    33 			$src = _load_image_to_edit_path( $src, 'full' );
    33 			$src = _load_image_to_edit_path( $src, 'full' );
    34 		} else {
    34 		} else {
    35 			$src = $src_file;
    35 			$src = $src_file;
    36 		}
    36 		}
    74 function wp_generate_attachment_metadata( $attachment_id, $file ) {
    74 function wp_generate_attachment_metadata( $attachment_id, $file ) {
    75 	$attachment = get_post( $attachment_id );
    75 	$attachment = get_post( $attachment_id );
    76 
    76 
    77 	$metadata = array();
    77 	$metadata = array();
    78 	$support = false;
    78 	$support = false;
    79 	if ( preg_match('!^image/!', get_post_mime_type( $attachment )) && file_is_displayable_image($file) ) {
    79 	$mime_type = get_post_mime_type( $attachment );
       
    80 
       
    81 	if ( preg_match( '!^image/!', $mime_type ) && file_is_displayable_image( $file ) ) {
    80 		$imagesize = getimagesize( $file );
    82 		$imagesize = getimagesize( $file );
    81 		$metadata['width'] = $imagesize[0];
    83 		$metadata['width'] = $imagesize[0];
    82 		$metadata['height'] = $imagesize[1];
    84 		$metadata['height'] = $imagesize[1];
    83 
    85 
    84 		// Make the file path relative to the upload dir.
    86 		// Make the file path relative to the upload dir.
    85 		$metadata['file'] = _wp_relative_upload_path($file);
    87 		$metadata['file'] = _wp_relative_upload_path($file);
    86 
    88 
    87 		// Make thumbnails and other intermediate sizes.
    89 		// Make thumbnails and other intermediate sizes.
    88 		global $_wp_additional_image_sizes;
    90 		$_wp_additional_image_sizes = wp_get_additional_image_sizes();
    89 
    91 
    90 		$sizes = array();
    92 		$sizes = array();
    91 		foreach ( get_intermediate_image_sizes() as $s ) {
    93 		foreach ( get_intermediate_image_sizes() as $s ) {
    92 			$sizes[$s] = array( 'width' => '', 'height' => '', 'crop' => false );
    94 			$sizes[$s] = array( 'width' => '', 'height' => '', 'crop' => false );
    93 			if ( isset( $_wp_additional_image_sizes[$s]['width'] ) )
    95 			if ( isset( $_wp_additional_image_sizes[$s]['width'] ) ) {
    94 				$sizes[$s]['width'] = intval( $_wp_additional_image_sizes[$s]['width'] ); // For theme-added sizes
    96 				// For theme-added sizes
    95 			else
    97 				$sizes[$s]['width'] = intval( $_wp_additional_image_sizes[$s]['width'] );
    96 				$sizes[$s]['width'] = get_option( "{$s}_size_w" ); // For default sizes set in options
    98 			} else {
    97 			if ( isset( $_wp_additional_image_sizes[$s]['height'] ) )
    99 				// For default sizes set in options
    98 				$sizes[$s]['height'] = intval( $_wp_additional_image_sizes[$s]['height'] ); // For theme-added sizes
   100 				$sizes[$s]['width'] = get_option( "{$s}_size_w" );
    99 			else
   101 			}
   100 				$sizes[$s]['height'] = get_option( "{$s}_size_h" ); // For default sizes set in options
   102 
   101 			if ( isset( $_wp_additional_image_sizes[$s]['crop'] ) )
   103 			if ( isset( $_wp_additional_image_sizes[$s]['height'] ) ) {
   102 				$sizes[$s]['crop'] = $_wp_additional_image_sizes[$s]['crop']; // For theme-added sizes
   104 				// For theme-added sizes
   103 			else
   105 				$sizes[$s]['height'] = intval( $_wp_additional_image_sizes[$s]['height'] );
   104 				$sizes[$s]['crop'] = get_option( "{$s}_crop" ); // For default sizes set in options
   106 			} else {
       
   107 				// For default sizes set in options
       
   108 				$sizes[$s]['height'] = get_option( "{$s}_size_h" );
       
   109 			}
       
   110 
       
   111 			if ( isset( $_wp_additional_image_sizes[$s]['crop'] ) ) {
       
   112 				// For theme-added sizes
       
   113 				$sizes[$s]['crop'] = $_wp_additional_image_sizes[$s]['crop'];
       
   114 			} else {
       
   115 				// For default sizes set in options
       
   116 				$sizes[$s]['crop'] = get_option( "{$s}_crop" );
       
   117 			}
   105 		}
   118 		}
   106 
   119 
   107 		/**
   120 		/**
   108 		 * Filter the image sizes automatically generated when uploading an image.
   121 		 * Filters the image sizes automatically generated when uploading an image.
   109 		 *
   122 		 *
   110 		 * @since 2.9.0
   123 		 * @since 2.9.0
   111 		 *
   124 		 * @since 4.4.0 Added the `$metadata` argument.
   112 		 * @param array $sizes An associative array of image sizes.
   125 		 *
       
   126 		 * @param array $sizes    An associative array of image sizes.
       
   127 		 * @param array $metadata An associative array of image metadata: width, height, file.
   113 		 */
   128 		 */
   114 		$sizes = apply_filters( 'intermediate_image_sizes_advanced', $sizes );
   129 		$sizes = apply_filters( 'intermediate_image_sizes_advanced', $sizes, $metadata );
   115 
   130 
   116 		if ( $sizes ) {
   131 		if ( $sizes ) {
   117 			$editor = wp_get_image_editor( $file );
   132 			$editor = wp_get_image_editor( $file );
   118 
   133 
   119 			if ( ! is_wp_error( $editor ) )
   134 			if ( ! is_wp_error( $editor ) )
   168 					'post_mime_type' => $metadata['image']['mime'],
   183 					'post_mime_type' => $metadata['image']['mime'],
   169 					'post_type' => 'attachment',
   184 					'post_type' => 'attachment',
   170 					'post_content' => '',
   185 					'post_content' => '',
   171 				);
   186 				);
   172 				/**
   187 				/**
   173 				 * Filter the parameters for the attachment thumbnail creation.
   188 				 * Filters the parameters for the attachment thumbnail creation.
   174 				 *
   189 				 *
   175 				 * @since 3.9.0
   190 				 * @since 3.9.0
   176 				 *
   191 				 *
   177 				 * @param array $image_attachment An array of parameters to create the thumbnail.
   192 				 * @param array $image_attachment An array of parameters to create the thumbnail.
   178 				 * @param array $metadata         Current attachment metadata.
   193 				 * @param array $metadata         Current attachment metadata.
   186 				wp_update_attachment_metadata( $sub_attachment_id, $attach_data );
   201 				wp_update_attachment_metadata( $sub_attachment_id, $attach_data );
   187 				update_post_meta( $attachment_id, '_thumbnail_id', $sub_attachment_id );
   202 				update_post_meta( $attachment_id, '_thumbnail_id', $sub_attachment_id );
   188 			}
   203 			}
   189 		}
   204 		}
   190 	}
   205 	}
       
   206 	// Try to create image thumbnails for PDFs
       
   207 	else if ( 'application/pdf' === $mime_type ) {
       
   208 		$fallback_sizes = array(
       
   209 			'thumbnail',
       
   210 			'medium',
       
   211 			'large',
       
   212 		);
       
   213 
       
   214 		/**
       
   215 		 * Filters the image sizes generated for non-image mime types.
       
   216 		 *
       
   217 		 * @since 4.7.0
       
   218 		 *
       
   219 		 * @param array $fallback_sizes An array of image size names.
       
   220 		 * @param array $metadata       Current attachment metadata.
       
   221 		 */
       
   222 		$fallback_sizes = apply_filters( 'fallback_intermediate_image_sizes', $fallback_sizes, $metadata );
       
   223 
       
   224 		$sizes = array();
       
   225 		$_wp_additional_image_sizes = wp_get_additional_image_sizes();
       
   226 
       
   227 		foreach ( $fallback_sizes as $s ) {
       
   228 			if ( isset( $_wp_additional_image_sizes[ $s ]['width'] ) ) {
       
   229 				$sizes[ $s ]['width'] = intval( $_wp_additional_image_sizes[ $s ]['width'] );
       
   230 			} else {
       
   231 				$sizes[ $s ]['width'] = get_option( "{$s}_size_w" );
       
   232 			}
       
   233 
       
   234 			if ( isset( $_wp_additional_image_sizes[ $s ]['height'] ) ) {
       
   235 				$sizes[ $s ]['height'] = intval( $_wp_additional_image_sizes[ $s ]['height'] );
       
   236 			} else {
       
   237 				$sizes[ $s ]['height'] = get_option( "{$s}_size_h" );
       
   238 			}
       
   239 
       
   240 			if ( isset( $_wp_additional_image_sizes[ $s ]['crop'] ) ) {
       
   241 				$sizes[ $s ]['crop'] = $_wp_additional_image_sizes[ $s ]['crop'];
       
   242 			} else {
       
   243 				// Force thumbnails to be soft crops.
       
   244 				if ( 'thumbnail' !== $s ) {
       
   245 					$sizes[ $s ]['crop'] = get_option( "{$s}_crop" );
       
   246 				}
       
   247 			}
       
   248 		}
       
   249 
       
   250 		// Only load PDFs in an image editor if we're processing sizes.
       
   251 		if ( ! empty( $sizes ) ) {
       
   252 			$editor = wp_get_image_editor( $file );
       
   253 
       
   254 			if ( ! is_wp_error( $editor ) ) { // No support for this type of file
       
   255 				/*
       
   256 				 * PDFs may have the same file filename as JPEGs.
       
   257 				 * Ensure the PDF preview image does not overwrite any JPEG images that already exist.
       
   258 				 */
       
   259 				$dirname = dirname( $file ) . '/';
       
   260 				$ext = '.' . pathinfo( $file, PATHINFO_EXTENSION );
       
   261 				$preview_file = $dirname . wp_unique_filename( $dirname, wp_basename( $file, $ext ) . '-pdf.jpg' );
       
   262 
       
   263 				$uploaded = $editor->save( $preview_file, 'image/jpeg' );
       
   264 				unset( $editor );
       
   265 
       
   266 				// Resize based on the full size image, rather than the source.
       
   267 				if ( ! is_wp_error( $uploaded ) ) {
       
   268 					$editor = wp_get_image_editor( $uploaded['path'] );
       
   269 					unset( $uploaded['path'] );
       
   270 
       
   271 					if ( ! is_wp_error( $editor ) ) {
       
   272 						$metadata['sizes'] = $editor->multi_resize( $sizes );
       
   273 						$metadata['sizes']['full'] = $uploaded;
       
   274 					}
       
   275 				}
       
   276 			}
       
   277 		}
       
   278 	}
   191 
   279 
   192 	// Remove the blob of binary data from the array.
   280 	// Remove the blob of binary data from the array.
   193 	if ( isset( $metadata['image']['data'] ) )
   281 	if ( $metadata ) {
   194 		unset( $metadata['image']['data'] );
   282 		unset( $metadata['image']['data'] );
       
   283 	}
   195 
   284 
   196 	/**
   285 	/**
   197 	 * Filter the generated attachment meta data.
   286 	 * Filters the generated attachment meta data.
   198 	 *
   287 	 *
   199 	 * @since 2.1.0
   288 	 * @since 2.1.0
   200 	 *
   289 	 *
   201 	 * @param array $metadata      An array of attachment meta data.
   290 	 * @param array $metadata      An array of attachment meta data.
   202 	 * @param int   $attachment_id Current attachment ID.
   291 	 * @param int   $attachment_id Current attachment ID.
   252  */
   341  */
   253 function wp_read_image_metadata( $file ) {
   342 function wp_read_image_metadata( $file ) {
   254 	if ( ! file_exists( $file ) )
   343 	if ( ! file_exists( $file ) )
   255 		return false;
   344 		return false;
   256 
   345 
   257 	list( , , $sourceImageType ) = getimagesize( $file );
   346 	list( , , $sourceImageType ) = @getimagesize( $file );
   258 
   347 
   259 	/*
   348 	/*
   260 	 * EXIF contains a bunch of data we'll probably never need formatted in ways
   349 	 * EXIF contains a bunch of data we'll probably never need formatted in ways
   261 	 * that are difficult to use. We'll normalize it and just extract the fields
   350 	 * that are difficult to use. We'll normalize it and just extract the fields
   262 	 * that are likely to be useful. Fractions and numbers are converted to
   351 	 * that are likely to be useful. Fractions and numbers are converted to
   272 		'focal_length' => 0,
   361 		'focal_length' => 0,
   273 		'iso' => 0,
   362 		'iso' => 0,
   274 		'shutter_speed' => 0,
   363 		'shutter_speed' => 0,
   275 		'title' => '',
   364 		'title' => '',
   276 		'orientation' => 0,
   365 		'orientation' => 0,
       
   366 		'keywords' => array(),
   277 	);
   367 	);
   278 
   368 
       
   369 	$iptc = array();
   279 	/*
   370 	/*
   280 	 * Read IPTC first, since it might contain data not available in exif such
   371 	 * Read IPTC first, since it might contain data not available in exif such
   281 	 * as caption, description etc.
   372 	 * as caption, description etc.
   282 	 */
   373 	 */
   283 	if ( is_callable( 'iptcparse' ) ) {
   374 	if ( is_callable( 'iptcparse' ) ) {
   284 		getimagesize( $file, $info );
   375 		@getimagesize( $file, $info );
   285 
   376 
   286 		if ( ! empty( $info['APP13'] ) ) {
   377 		if ( ! empty( $info['APP13'] ) ) {
   287 			$iptc = iptcparse( $info['APP13'] );
   378 			$iptc = @iptcparse( $info['APP13'] );
   288 
   379 
   289 			// Headline, "A brief synopsis of the caption."
   380 			// Headline, "A brief synopsis of the caption."
   290 			if ( ! empty( $iptc['2#105'][0] ) ) {
   381 			if ( ! empty( $iptc['2#105'][0] ) ) {
   291 				$meta['title'] = trim( $iptc['2#105'][0] );
   382 				$meta['title'] = trim( $iptc['2#105'][0] );
   292 			/*
   383 			/*
   320 			if ( ! empty( $iptc['2#055'][0] ) && ! empty( $iptc['2#060'][0] ) ) // created date and time
   411 			if ( ! empty( $iptc['2#055'][0] ) && ! empty( $iptc['2#060'][0] ) ) // created date and time
   321 				$meta['created_timestamp'] = strtotime( $iptc['2#055'][0] . ' ' . $iptc['2#060'][0] );
   412 				$meta['created_timestamp'] = strtotime( $iptc['2#055'][0] . ' ' . $iptc['2#060'][0] );
   322 
   413 
   323 			if ( ! empty( $iptc['2#116'][0] ) ) // copyright
   414 			if ( ! empty( $iptc['2#116'][0] ) ) // copyright
   324 				$meta['copyright'] = trim( $iptc['2#116'][0] );
   415 				$meta['copyright'] = trim( $iptc['2#116'][0] );
       
   416 
       
   417 			if ( ! empty( $iptc['2#025'][0] ) ) { // keywords array
       
   418 				$meta['keywords'] = array_values( $iptc['2#025'] );
       
   419 			}
   325 		 }
   420 		 }
   326 	}
   421 	}
   327 
   422 
   328 	/**
   423 	/**
   329 	 * Filter the image types to check for exif data.
   424 	 * Filters the image types to check for exif data.
   330 	 *
   425 	 *
   331 	 * @since 2.5.0
   426 	 * @since 2.5.0
   332 	 *
   427 	 *
   333 	 * @param array $image_types Image types to check for exif data.
   428 	 * @param array $image_types Image types to check for exif data.
   334 	 */
   429 	 */
   395 		if ( $meta[ $key ] && ! seems_utf8( $meta[ $key ] ) ) {
   490 		if ( $meta[ $key ] && ! seems_utf8( $meta[ $key ] ) ) {
   396 			$meta[ $key ] = utf8_encode( $meta[ $key ] );
   491 			$meta[ $key ] = utf8_encode( $meta[ $key ] );
   397 		}
   492 		}
   398 	}
   493 	}
   399 
   494 
   400 	foreach ( $meta as &$value ) {
   495 	foreach ( $meta['keywords'] as $key => $keyword ) {
   401 		if ( is_string( $value ) ) {
   496 		if ( ! seems_utf8( $keyword ) ) {
   402 			$value = wp_kses_post( $value );
   497 			$meta['keywords'][ $key ] = utf8_encode( $keyword );
   403 		}
   498 		}
   404 	}
   499 	}
       
   500 
       
   501 	$meta = wp_kses_post_deep( $meta );
   405 
   502 
   406 	/**
   503 	/**
   407 	 * Filter the array of meta data read from an image's exif data.
   504 	 * Filters the array of meta data read from an image's exif data.
   408 	 *
   505 	 *
   409 	 * @since 2.5.0
   506 	 * @since 2.5.0
       
   507 	 * @since 4.4.0 The `$iptc` parameter was added.
   410 	 *
   508 	 *
   411 	 * @param array  $meta            Image meta data.
   509 	 * @param array  $meta            Image meta data.
   412 	 * @param string $file            Path to image file.
   510 	 * @param string $file            Path to image file.
   413 	 * @param int    $sourceImageType Type of image.
   511 	 * @param int    $sourceImageType Type of image.
   414 	 */
   512 	 * @param array  $iptc            IPTC data.
   415 	return apply_filters( 'wp_read_image_metadata', $meta, $file, $sourceImageType );
   513 	 */
       
   514 	return apply_filters( 'wp_read_image_metadata', $meta, $file, $sourceImageType, $iptc );
   416 
   515 
   417 }
   516 }
   418 
   517 
   419 /**
   518 /**
   420  * Validate that file is an image.
   519  * Validate that file is an image.
   448 	} else {
   547 	} else {
   449 		$result = true;
   548 		$result = true;
   450 	}
   549 	}
   451 
   550 
   452 	/**
   551 	/**
   453 	 * Filter whether the current image is displayable in the browser.
   552 	 * Filters whether the current image is displayable in the browser.
   454 	 *
   553 	 *
   455 	 * @since 2.5.0
   554 	 * @since 2.5.0
   456 	 *
   555 	 *
   457 	 * @param bool   $result Whether the image can be displayed. Default true.
   556 	 * @param bool   $result Whether the image can be displayed. Default true.
   458 	 * @param string $path   Path to the image.
   557 	 * @param string $path   Path to the image.
   489 			$image = false;
   588 			$image = false;
   490 			break;
   589 			break;
   491 	}
   590 	}
   492 	if ( is_resource($image) ) {
   591 	if ( is_resource($image) ) {
   493 		/**
   592 		/**
   494 		 * Filter the current image being loaded for editing.
   593 		 * Filters the current image being loaded for editing.
   495 		 *
   594 		 *
   496 		 * @since 2.9.0
   595 		 * @since 2.9.0
   497 		 *
   596 		 *
   498 		 * @param resource $image         Current image.
   597 		 * @param resource $image         Current image.
   499 		 * @param string   $attachment_id Attachment ID.
   598 		 * @param string   $attachment_id Attachment ID.
   525 	$filepath = get_attached_file( $attachment_id );
   624 	$filepath = get_attached_file( $attachment_id );
   526 
   625 
   527 	if ( $filepath && file_exists( $filepath ) ) {
   626 	if ( $filepath && file_exists( $filepath ) ) {
   528 		if ( 'full' != $size && ( $data = image_get_intermediate_size( $attachment_id, $size ) ) ) {
   627 		if ( 'full' != $size && ( $data = image_get_intermediate_size( $attachment_id, $size ) ) ) {
   529 			/**
   628 			/**
   530 			 * Filter the path to the current image.
   629 			 * Filters the path to the current image.
   531 			 *
   630 			 *
   532 			 * The filter is evaluated for all image sizes except 'full'.
   631 			 * The filter is evaluated for all image sizes except 'full'.
   533 			 *
   632 			 *
   534 			 * @since 3.1.0
   633 			 * @since 3.1.0
   535 			 *
   634 			 *
   537 			 * @param string $attachment_id Attachment ID.
   636 			 * @param string $attachment_id Attachment ID.
   538 			 * @param string $size          Size of the image.
   637 			 * @param string $size          Size of the image.
   539 			 */
   638 			 */
   540 			$filepath = apply_filters( 'load_image_to_edit_filesystempath', path_join( dirname( $filepath ), $data['file'] ), $attachment_id, $size );
   639 			$filepath = apply_filters( 'load_image_to_edit_filesystempath', path_join( dirname( $filepath ), $data['file'] ), $attachment_id, $size );
   541 		}
   640 		}
   542 	} elseif ( function_exists( 'fopen' ) && function_exists( 'ini_get' ) && true == ini_get( 'allow_url_fopen' ) ) {
   641 	} elseif ( function_exists( 'fopen' ) && true == ini_get( 'allow_url_fopen' ) ) {
   543 		/**
   642 		/**
   544 		 * Filter the image URL if not in the local filesystem.
   643 		 * Filters the image URL if not in the local filesystem.
   545 		 *
   644 		 *
   546 		 * The filter is only evaluated if fopen is enabled on the server.
   645 		 * The filter is only evaluated if fopen is enabled on the server.
   547 		 *
   646 		 *
   548 		 * @since 3.1.0
   647 		 * @since 3.1.0
   549 		 *
   648 		 *
   553 		 */
   652 		 */
   554 		$filepath = apply_filters( 'load_image_to_edit_attachmenturl', wp_get_attachment_url( $attachment_id ), $attachment_id, $size );
   653 		$filepath = apply_filters( 'load_image_to_edit_attachmenturl', wp_get_attachment_url( $attachment_id ), $attachment_id, $size );
   555 	}
   654 	}
   556 
   655 
   557 	/**
   656 	/**
   558 	 * Filter the returned path or URL of the current image.
   657 	 * Filters the returned path or URL of the current image.
   559 	 *
   658 	 *
   560 	 * @since 2.9.0
   659 	 * @since 2.9.0
   561 	 *
   660 	 *
   562 	 * @param string|bool $filepath      File path or URL to current image, or false.
   661 	 * @param string|bool $filepath      File path or URL to current image, or false.
   563 	 * @param string      $attachment_id Attachment ID.
   662 	 * @param string      $attachment_id Attachment ID.