wp/wp-admin/includes/image.php
changeset 9 177826044cd9
parent 7 cf61fcea0001
child 16 a86126ab1dd4
equal deleted inserted replaced
8:c7c34916027a 9:177826044cd9
    35 			$src = $src_file;
    35 			$src = $src_file;
    36 		}
    36 		}
    37 	}
    37 	}
    38 
    38 
    39 	$editor = wp_get_image_editor( $src );
    39 	$editor = wp_get_image_editor( $src );
    40 	if ( is_wp_error( $editor ) )
    40 	if ( is_wp_error( $editor ) ) {
    41 		return $editor;
    41 		return $editor;
       
    42 	}
    42 
    43 
    43 	$src = $editor->crop( $src_x, $src_y, $src_w, $src_h, $dst_w, $dst_h, $src_abs );
    44 	$src = $editor->crop( $src_x, $src_y, $src_w, $src_h, $dst_w, $dst_h, $src_abs );
    44 	if ( is_wp_error( $src ) )
    45 	if ( is_wp_error( $src ) ) {
    45 		return $src;
    46 		return $src;
    46 
    47 	}
    47 	if ( ! $dst_file )
    48 
    48 		$dst_file = str_replace( basename( $src_file ), 'cropped-' . basename( $src_file ), $src_file );
    49 	if ( ! $dst_file ) {
       
    50 		$dst_file = str_replace( wp_basename( $src_file ), 'cropped-' . wp_basename( $src_file ), $src_file );
       
    51 	}
    49 
    52 
    50 	/*
    53 	/*
    51 	 * The directory containing the original file may no longer exist when
    54 	 * The directory containing the original file may no longer exist when
    52 	 * using a replication plugin.
    55 	 * using a replication plugin.
    53 	 */
    56 	 */
    54 	wp_mkdir_p( dirname( $dst_file ) );
    57 	wp_mkdir_p( dirname( $dst_file ) );
    55 
    58 
    56 	$dst_file = dirname( $dst_file ) . '/' . wp_unique_filename( dirname( $dst_file ), basename( $dst_file ) );
    59 	$dst_file = dirname( $dst_file ) . '/' . wp_unique_filename( dirname( $dst_file ), wp_basename( $dst_file ) );
    57 
    60 
    58 	$result = $editor->save( $dst_file );
    61 	$result = $editor->save( $dst_file );
    59 	if ( is_wp_error( $result ) )
    62 	if ( is_wp_error( $result ) ) {
    60 		return $result;
    63 		return $result;
       
    64 	}
    61 
    65 
    62 	return $dst_file;
    66 	return $dst_file;
    63 }
    67 }
    64 
    68 
    65 /**
    69 /**
    72  * @return mixed Metadata for attachment.
    76  * @return mixed Metadata for attachment.
    73  */
    77  */
    74 function wp_generate_attachment_metadata( $attachment_id, $file ) {
    78 function wp_generate_attachment_metadata( $attachment_id, $file ) {
    75 	$attachment = get_post( $attachment_id );
    79 	$attachment = get_post( $attachment_id );
    76 
    80 
    77 	$metadata = array();
    81 	$metadata  = array();
    78 	$support = false;
    82 	$support   = false;
    79 	$mime_type = get_post_mime_type( $attachment );
    83 	$mime_type = get_post_mime_type( $attachment );
    80 
    84 
    81 	if ( preg_match( '!^image/!', $mime_type ) && file_is_displayable_image( $file ) ) {
    85 	if ( preg_match( '!^image/!', $mime_type ) && file_is_displayable_image( $file ) ) {
    82 		$imagesize = getimagesize( $file );
    86 		$imagesize          = getimagesize( $file );
    83 		$metadata['width'] = $imagesize[0];
    87 		$metadata['width']  = $imagesize[0];
    84 		$metadata['height'] = $imagesize[1];
    88 		$metadata['height'] = $imagesize[1];
    85 
    89 
    86 		// Make the file path relative to the upload dir.
    90 		// Make the file path relative to the upload dir.
    87 		$metadata['file'] = _wp_relative_upload_path($file);
    91 		$metadata['file'] = _wp_relative_upload_path( $file );
    88 
    92 
    89 		// Make thumbnails and other intermediate sizes.
    93 		// Make thumbnails and other intermediate sizes.
    90 		$_wp_additional_image_sizes = wp_get_additional_image_sizes();
    94 		$_wp_additional_image_sizes = wp_get_additional_image_sizes();
    91 
    95 
    92 		$sizes = array();
    96 		$sizes = array();
    93 		foreach ( get_intermediate_image_sizes() as $s ) {
    97 		foreach ( get_intermediate_image_sizes() as $s ) {
    94 			$sizes[$s] = array( 'width' => '', 'height' => '', 'crop' => false );
    98 			$sizes[ $s ] = array(
    95 			if ( isset( $_wp_additional_image_sizes[$s]['width'] ) ) {
    99 				'width'  => '',
       
   100 				'height' => '',
       
   101 				'crop'   => false,
       
   102 			);
       
   103 			if ( isset( $_wp_additional_image_sizes[ $s ]['width'] ) ) {
    96 				// For theme-added sizes
   104 				// For theme-added sizes
    97 				$sizes[$s]['width'] = intval( $_wp_additional_image_sizes[$s]['width'] );
   105 				$sizes[ $s ]['width'] = intval( $_wp_additional_image_sizes[ $s ]['width'] );
    98 			} else {
   106 			} else {
    99 				// For default sizes set in options
   107 				// For default sizes set in options
   100 				$sizes[$s]['width'] = get_option( "{$s}_size_w" );
   108 				$sizes[ $s ]['width'] = get_option( "{$s}_size_w" );
   101 			}
   109 			}
   102 
   110 
   103 			if ( isset( $_wp_additional_image_sizes[$s]['height'] ) ) {
   111 			if ( isset( $_wp_additional_image_sizes[ $s ]['height'] ) ) {
   104 				// For theme-added sizes
   112 				// For theme-added sizes
   105 				$sizes[$s]['height'] = intval( $_wp_additional_image_sizes[$s]['height'] );
   113 				$sizes[ $s ]['height'] = intval( $_wp_additional_image_sizes[ $s ]['height'] );
   106 			} else {
   114 			} else {
   107 				// For default sizes set in options
   115 				// For default sizes set in options
   108 				$sizes[$s]['height'] = get_option( "{$s}_size_h" );
   116 				$sizes[ $s ]['height'] = get_option( "{$s}_size_h" );
   109 			}
   117 			}
   110 
   118 
   111 			if ( isset( $_wp_additional_image_sizes[$s]['crop'] ) ) {
   119 			if ( isset( $_wp_additional_image_sizes[ $s ]['crop'] ) ) {
   112 				// For theme-added sizes
   120 				// For theme-added sizes
   113 				$sizes[$s]['crop'] = $_wp_additional_image_sizes[$s]['crop'];
   121 				$sizes[ $s ]['crop'] = $_wp_additional_image_sizes[ $s ]['crop'];
   114 			} else {
   122 			} else {
   115 				// For default sizes set in options
   123 				// For default sizes set in options
   116 				$sizes[$s]['crop'] = get_option( "{$s}_crop" );
   124 				$sizes[ $s ]['crop'] = get_option( "{$s}_crop" );
   117 			}
   125 			}
   118 		}
   126 		}
   119 
   127 
   120 		/**
   128 		/**
   121 		 * Filters the image sizes automatically generated when uploading an image.
   129 		 * Filters the image sizes automatically generated when uploading an image.
   122 		 *
   130 		 *
   123 		 * @since 2.9.0
   131 		 * @since 2.9.0
   124 		 * @since 4.4.0 Added the `$metadata` argument.
   132 		 * @since 4.4.0 Added the `$metadata` argument.
   125 		 *
   133 		 * @since 5.1.0 Added the `$attachment_id` argument.
   126 		 * @param array $sizes    An associative array of image sizes.
   134 		 *
   127 		 * @param array $metadata An associative array of image metadata: width, height, file.
   135 		 * @param array $sizes         An associative array of image sizes.
       
   136 		 * @param array $metadata      An associative array of image metadata: width, height, file.
       
   137 		 * @param int   $attachment_id Current attachment ID.
   128 		 */
   138 		 */
   129 		$sizes = apply_filters( 'intermediate_image_sizes_advanced', $sizes, $metadata );
   139 		$sizes = apply_filters( 'intermediate_image_sizes_advanced', $sizes, $metadata, $attachment_id );
   130 
   140 
   131 		if ( $sizes ) {
   141 		if ( $sizes ) {
   132 			$editor = wp_get_image_editor( $file );
   142 			$editor = wp_get_image_editor( $file );
   133 
   143 
   134 			if ( ! is_wp_error( $editor ) )
   144 			if ( ! is_wp_error( $editor ) ) {
   135 				$metadata['sizes'] = $editor->multi_resize( $sizes );
   145 				$metadata['sizes'] = $editor->multi_resize( $sizes );
       
   146 			}
   136 		} else {
   147 		} else {
   137 			$metadata['sizes'] = array();
   148 			$metadata['sizes'] = array();
   138 		}
   149 		}
   139 
   150 
   140 		// Fetch additional metadata from EXIF/IPTC.
   151 		// Fetch additional metadata from EXIF/IPTC.
   141 		$image_meta = wp_read_image_metadata( $file );
   152 		$image_meta = wp_read_image_metadata( $file );
   142 		if ( $image_meta )
   153 		if ( $image_meta ) {
   143 			$metadata['image_meta'] = $image_meta;
   154 			$metadata['image_meta'] = $image_meta;
   144 
   155 		}
   145 	} elseif ( wp_attachment_is( 'video', $attachment ) ) {
   156 	} elseif ( wp_attachment_is( 'video', $attachment ) ) {
   146 		$metadata = wp_read_video_metadata( $file );
   157 		$metadata = wp_read_video_metadata( $file );
   147 		$support = current_theme_supports( 'post-thumbnails', 'attachment:video' ) || post_type_supports( 'attachment:video', 'thumbnail' );
   158 		$support  = current_theme_supports( 'post-thumbnails', 'attachment:video' ) || post_type_supports( 'attachment:video', 'thumbnail' );
   148 	} elseif ( wp_attachment_is( 'audio', $attachment ) ) {
   159 	} elseif ( wp_attachment_is( 'audio', $attachment ) ) {
   149 		$metadata = wp_read_audio_metadata( $file );
   160 		$metadata = wp_read_audio_metadata( $file );
   150 		$support = current_theme_supports( 'post-thumbnails', 'attachment:audio' ) || post_type_supports( 'attachment:audio', 'thumbnail' );
   161 		$support  = current_theme_supports( 'post-thumbnails', 'attachment:audio' ) || post_type_supports( 'attachment:audio', 'thumbnail' );
   151 	}
   162 	}
   152 
   163 
   153 	if ( $support && ! empty( $metadata['image']['data'] ) ) {
   164 	if ( $support && ! empty( $metadata['image']['data'] ) ) {
   154 		// Check for existing cover.
   165 		// Check for existing cover.
   155 		$hash = md5( $metadata['image']['data'] );
   166 		$hash   = md5( $metadata['image']['data'] );
   156 		$posts = get_posts( array(
   167 		$posts  = get_posts(
   157 			'fields' => 'ids',
   168 			array(
   158 			'post_type' => 'attachment',
   169 				'fields'         => 'ids',
   159 			'post_mime_type' => $metadata['image']['mime'],
   170 				'post_type'      => 'attachment',
   160 			'post_status' => 'inherit',
   171 				'post_mime_type' => $metadata['image']['mime'],
   161 			'posts_per_page' => 1,
   172 				'post_status'    => 'inherit',
   162 			'meta_key' => '_cover_hash',
   173 				'posts_per_page' => 1,
   163 			'meta_value' => $hash
   174 				'meta_key'       => '_cover_hash',
   164 		) );
   175 				'meta_value'     => $hash,
       
   176 			)
       
   177 		);
   165 		$exists = reset( $posts );
   178 		$exists = reset( $posts );
   166 
   179 
   167 		if ( ! empty( $exists ) ) {
   180 		if ( ! empty( $exists ) ) {
   168 			update_post_meta( $attachment_id, '_thumbnail_id', $exists );
   181 			update_post_meta( $attachment_id, '_thumbnail_id', $exists );
   169 		} else {
   182 		} else {
   170 			$ext = '.jpg';
   183 			$ext = '.jpg';
   171 			switch ( $metadata['image']['mime'] ) {
   184 			switch ( $metadata['image']['mime'] ) {
   172 			case 'image/gif':
   185 				case 'image/gif':
   173 				$ext = '.gif';
   186 					$ext = '.gif';
   174 				break;
   187 					break;
   175 			case 'image/png':
   188 				case 'image/png':
   176 				$ext = '.png';
   189 					$ext = '.png';
   177 				break;
   190 					break;
   178 			}
   191 			}
   179 			$basename = str_replace( '.', '-', basename( $file ) ) . '-image' . $ext;
   192 			$basename = str_replace( '.', '-', wp_basename( $file ) ) . '-image' . $ext;
   180 			$uploaded = wp_upload_bits( $basename, '', $metadata['image']['data'] );
   193 			$uploaded = wp_upload_bits( $basename, '', $metadata['image']['data'] );
   181 			if ( false === $uploaded['error'] ) {
   194 			if ( false === $uploaded['error'] ) {
   182 				$image_attachment = array(
   195 				$image_attachment = array(
   183 					'post_mime_type' => $metadata['image']['mime'],
   196 					'post_mime_type' => $metadata['image']['mime'],
   184 					'post_type' => 'attachment',
   197 					'post_type'      => 'attachment',
   185 					'post_content' => '',
   198 					'post_content'   => '',
   186 				);
   199 				);
   187 				/**
   200 				/**
   188 				 * Filters the parameters for the attachment thumbnail creation.
   201 				 * Filters the parameters for the attachment thumbnail creation.
   189 				 *
   202 				 *
   190 				 * @since 3.9.0
   203 				 * @since 3.9.0
   200 				$attach_data = wp_generate_attachment_metadata( $sub_attachment_id, $uploaded['file'] );
   213 				$attach_data = wp_generate_attachment_metadata( $sub_attachment_id, $uploaded['file'] );
   201 				wp_update_attachment_metadata( $sub_attachment_id, $attach_data );
   214 				wp_update_attachment_metadata( $sub_attachment_id, $attach_data );
   202 				update_post_meta( $attachment_id, '_thumbnail_id', $sub_attachment_id );
   215 				update_post_meta( $attachment_id, '_thumbnail_id', $sub_attachment_id );
   203 			}
   216 			}
   204 		}
   217 		}
   205 	}
   218 	} elseif ( 'application/pdf' === $mime_type ) {
   206 	// Try to create image thumbnails for PDFs
   219 		// Try to create image thumbnails for PDFs.
   207 	else if ( 'application/pdf' === $mime_type ) {
   220 
   208 		$fallback_sizes = array(
   221 		$fallback_sizes = array(
   209 			'thumbnail',
   222 			'thumbnail',
   210 			'medium',
   223 			'medium',
   211 			'large',
   224 			'large',
   212 		);
   225 		);
   219 		 * @param array $fallback_sizes An array of image size names.
   232 		 * @param array $fallback_sizes An array of image size names.
   220 		 * @param array $metadata       Current attachment metadata.
   233 		 * @param array $metadata       Current attachment metadata.
   221 		 */
   234 		 */
   222 		$fallback_sizes = apply_filters( 'fallback_intermediate_image_sizes', $fallback_sizes, $metadata );
   235 		$fallback_sizes = apply_filters( 'fallback_intermediate_image_sizes', $fallback_sizes, $metadata );
   223 
   236 
   224 		$sizes = array();
   237 		$sizes                      = array();
   225 		$_wp_additional_image_sizes = wp_get_additional_image_sizes();
   238 		$_wp_additional_image_sizes = wp_get_additional_image_sizes();
   226 
   239 
   227 		foreach ( $fallback_sizes as $s ) {
   240 		foreach ( $fallback_sizes as $s ) {
   228 			if ( isset( $_wp_additional_image_sizes[ $s ]['width'] ) ) {
   241 			if ( isset( $_wp_additional_image_sizes[ $s ]['width'] ) ) {
   229 				$sizes[ $s ]['width'] = intval( $_wp_additional_image_sizes[ $s ]['width'] );
   242 				$sizes[ $s ]['width'] = intval( $_wp_additional_image_sizes[ $s ]['width'] );
   254 			if ( ! is_wp_error( $editor ) ) { // No support for this type of file
   267 			if ( ! is_wp_error( $editor ) ) { // No support for this type of file
   255 				/*
   268 				/*
   256 				 * PDFs may have the same file filename as JPEGs.
   269 				 * PDFs may have the same file filename as JPEGs.
   257 				 * Ensure the PDF preview image does not overwrite any JPEG images that already exist.
   270 				 * Ensure the PDF preview image does not overwrite any JPEG images that already exist.
   258 				 */
   271 				 */
   259 				$dirname = dirname( $file ) . '/';
   272 				$dirname      = dirname( $file ) . '/';
   260 				$ext = '.' . pathinfo( $file, PATHINFO_EXTENSION );
   273 				$ext          = '.' . pathinfo( $file, PATHINFO_EXTENSION );
   261 				$preview_file = $dirname . wp_unique_filename( $dirname, wp_basename( $file, $ext ) . '-pdf.jpg' );
   274 				$preview_file = $dirname . wp_unique_filename( $dirname, wp_basename( $file, $ext ) . '-pdf.jpg' );
   262 
   275 
   263 				$uploaded = $editor->save( $preview_file, 'image/jpeg' );
   276 				$uploaded = $editor->save( $preview_file, 'image/jpeg' );
   264 				unset( $editor );
   277 				unset( $editor );
   265 
   278 
   267 				if ( ! is_wp_error( $uploaded ) ) {
   280 				if ( ! is_wp_error( $uploaded ) ) {
   268 					$editor = wp_get_image_editor( $uploaded['path'] );
   281 					$editor = wp_get_image_editor( $uploaded['path'] );
   269 					unset( $uploaded['path'] );
   282 					unset( $uploaded['path'] );
   270 
   283 
   271 					if ( ! is_wp_error( $editor ) ) {
   284 					if ( ! is_wp_error( $editor ) ) {
   272 						$metadata['sizes'] = $editor->multi_resize( $sizes );
   285 						$metadata['sizes']         = $editor->multi_resize( $sizes );
   273 						$metadata['sizes']['full'] = $uploaded;
   286 						$metadata['sizes']['full'] = $uploaded;
   274 					}
   287 					}
   275 				}
   288 				}
   276 			}
   289 			}
   277 		}
   290 		}
   299  * @since 2.5.0
   312  * @since 2.5.0
   300  *
   313  *
   301  * @param string $str
   314  * @param string $str
   302  * @return int|float
   315  * @return int|float
   303  */
   316  */
   304 function wp_exif_frac2dec($str) {
   317 function wp_exif_frac2dec( $str ) {
   305 	@list( $n, $d ) = explode( '/', $str );
   318 	@list( $n, $d ) = explode( '/', $str );
   306 	if ( !empty($d) )
   319 	if ( ! empty( $d ) ) {
   307 		return $n / $d;
   320 		return $n / $d;
       
   321 	}
   308 	return $str;
   322 	return $str;
   309 }
   323 }
   310 
   324 
   311 /**
   325 /**
   312  * Convert the exif date format to a unix timestamp.
   326  * Convert the exif date format to a unix timestamp.
   314  * @since 2.5.0
   328  * @since 2.5.0
   315  *
   329  *
   316  * @param string $str
   330  * @param string $str
   317  * @return int
   331  * @return int
   318  */
   332  */
   319 function wp_exif_date2ts($str) {
   333 function wp_exif_date2ts( $str ) {
   320 	@list( $date, $time ) = explode( ' ', trim($str) );
   334 	@list( $date, $time ) = explode( ' ', trim( $str ) );
   321 	@list( $y, $m, $d ) = explode( ':', $date );
   335 	@list( $y, $m, $d )   = explode( ':', $date );
   322 
   336 
   323 	return strtotime( "{$y}-{$m}-{$d} {$time}" );
   337 	return strtotime( "{$y}-{$m}-{$d} {$time}" );
   324 }
   338 }
   325 
   339 
   326 /**
   340 /**
   338  *
   352  *
   339  * @param string $file
   353  * @param string $file
   340  * @return bool|array False on failure. Image metadata array on success.
   354  * @return bool|array False on failure. Image metadata array on success.
   341  */
   355  */
   342 function wp_read_image_metadata( $file ) {
   356 function wp_read_image_metadata( $file ) {
   343 	if ( ! file_exists( $file ) )
   357 	if ( ! file_exists( $file ) ) {
   344 		return false;
   358 		return false;
   345 
   359 	}
   346 	list( , , $sourceImageType ) = @getimagesize( $file );
   360 
       
   361 	list( , , $image_type ) = @getimagesize( $file );
   347 
   362 
   348 	/*
   363 	/*
   349 	 * EXIF contains a bunch of data we'll probably never need formatted in ways
   364 	 * EXIF contains a bunch of data we'll probably never need formatted in ways
   350 	 * that are difficult to use. We'll normalize it and just extract the fields
   365 	 * that are difficult to use. We'll normalize it and just extract the fields
   351 	 * that are likely to be useful. Fractions and numbers are converted to
   366 	 * that are likely to be useful. Fractions and numbers are converted to
   352 	 * floats, dates to unix timestamps, and everything else to strings.
   367 	 * floats, dates to unix timestamps, and everything else to strings.
   353 	 */
   368 	 */
   354 	$meta = array(
   369 	$meta = array(
   355 		'aperture' => 0,
   370 		'aperture'          => 0,
   356 		'credit' => '',
   371 		'credit'            => '',
   357 		'camera' => '',
   372 		'camera'            => '',
   358 		'caption' => '',
   373 		'caption'           => '',
   359 		'created_timestamp' => 0,
   374 		'created_timestamp' => 0,
   360 		'copyright' => '',
   375 		'copyright'         => '',
   361 		'focal_length' => 0,
   376 		'focal_length'      => 0,
   362 		'iso' => 0,
   377 		'iso'               => 0,
   363 		'shutter_speed' => 0,
   378 		'shutter_speed'     => 0,
   364 		'title' => '',
   379 		'title'             => '',
   365 		'orientation' => 0,
   380 		'orientation'       => 0,
   366 		'keywords' => array(),
   381 		'keywords'          => array(),
   367 	);
   382 	);
   368 
   383 
   369 	$iptc = array();
   384 	$iptc = array();
   370 	/*
   385 	/*
   371 	 * Read IPTC first, since it might contain data not available in exif such
   386 	 * Read IPTC first, since it might contain data not available in exif such
   378 			$iptc = @iptcparse( $info['APP13'] );
   393 			$iptc = @iptcparse( $info['APP13'] );
   379 
   394 
   380 			// Headline, "A brief synopsis of the caption."
   395 			// Headline, "A brief synopsis of the caption."
   381 			if ( ! empty( $iptc['2#105'][0] ) ) {
   396 			if ( ! empty( $iptc['2#105'][0] ) ) {
   382 				$meta['title'] = trim( $iptc['2#105'][0] );
   397 				$meta['title'] = trim( $iptc['2#105'][0] );
   383 			/*
   398 				/*
   384 			 * Title, "Many use the Title field to store the filename of the image,
   399 				* Title, "Many use the Title field to store the filename of the image,
   385 			 * though the field may be used in many ways."
   400 				* though the field may be used in many ways."
   386 			 */
   401 				*/
   387 			} elseif ( ! empty( $iptc['2#005'][0] ) ) {
   402 			} elseif ( ! empty( $iptc['2#005'][0] ) ) {
   388 				$meta['title'] = trim( $iptc['2#005'][0] );
   403 				$meta['title'] = trim( $iptc['2#005'][0] );
   389 			}
   404 			}
   390 
   405 
   391 			if ( ! empty( $iptc['2#120'][0] ) ) { // description / legacy caption
   406 			if ( ! empty( $iptc['2#120'][0] ) ) { // description / legacy caption
   401 				}
   416 				}
   402 
   417 
   403 				$meta['caption'] = $caption;
   418 				$meta['caption'] = $caption;
   404 			}
   419 			}
   405 
   420 
   406 			if ( ! empty( $iptc['2#110'][0] ) ) // credit
   421 			if ( ! empty( $iptc['2#110'][0] ) ) { // credit
   407 				$meta['credit'] = trim( $iptc['2#110'][0] );
   422 				$meta['credit'] = trim( $iptc['2#110'][0] );
   408 			elseif ( ! empty( $iptc['2#080'][0] ) ) // creator / legacy byline
   423 			} elseif ( ! empty( $iptc['2#080'][0] ) ) { // creator / legacy byline
   409 				$meta['credit'] = trim( $iptc['2#080'][0] );
   424 				$meta['credit'] = trim( $iptc['2#080'][0] );
   410 
   425 			}
   411 			if ( ! empty( $iptc['2#055'][0] ) && ! empty( $iptc['2#060'][0] ) ) // created date and time
   426 
       
   427 			if ( ! empty( $iptc['2#055'][0] ) && ! empty( $iptc['2#060'][0] ) ) { // created date and time
   412 				$meta['created_timestamp'] = strtotime( $iptc['2#055'][0] . ' ' . $iptc['2#060'][0] );
   428 				$meta['created_timestamp'] = strtotime( $iptc['2#055'][0] . ' ' . $iptc['2#060'][0] );
   413 
   429 			}
   414 			if ( ! empty( $iptc['2#116'][0] ) ) // copyright
   430 
       
   431 			if ( ! empty( $iptc['2#116'][0] ) ) { // copyright
   415 				$meta['copyright'] = trim( $iptc['2#116'][0] );
   432 				$meta['copyright'] = trim( $iptc['2#116'][0] );
       
   433 			}
   416 
   434 
   417 			if ( ! empty( $iptc['2#025'][0] ) ) { // keywords array
   435 			if ( ! empty( $iptc['2#025'][0] ) ) { // keywords array
   418 				$meta['keywords'] = array_values( $iptc['2#025'] );
   436 				$meta['keywords'] = array_values( $iptc['2#025'] );
   419 			}
   437 			}
   420 		 }
   438 		}
   421 	}
   439 	}
       
   440 
       
   441 	$exif = array();
   422 
   442 
   423 	/**
   443 	/**
   424 	 * Filters the image types to check for exif data.
   444 	 * Filters the image types to check for exif data.
   425 	 *
   445 	 *
   426 	 * @since 2.5.0
   446 	 * @since 2.5.0
   427 	 *
   447 	 *
   428 	 * @param array $image_types Image types to check for exif data.
   448 	 * @param array $image_types Image types to check for exif data.
   429 	 */
   449 	 */
   430 	if ( is_callable( 'exif_read_data' ) && in_array( $sourceImageType, apply_filters( 'wp_read_image_metadata_types', array( IMAGETYPE_JPEG, IMAGETYPE_TIFF_II, IMAGETYPE_TIFF_MM ) ) ) ) {
   450 	$exif_image_types = apply_filters( 'wp_read_image_metadata_types', array( IMAGETYPE_JPEG, IMAGETYPE_TIFF_II, IMAGETYPE_TIFF_MM ) );
       
   451 
       
   452 	if ( is_callable( 'exif_read_data' ) && in_array( $image_type, $exif_image_types ) ) {
   431 		$exif = @exif_read_data( $file );
   453 		$exif = @exif_read_data( $file );
   432 
   454 
   433 		if ( ! empty( $exif['ImageDescription'] ) ) {
   455 		if ( ! empty( $exif['ImageDescription'] ) ) {
   434 			mbstring_binary_safe_encoding();
   456 			mbstring_binary_safe_encoding();
   435 			$description_length = strlen( $exif['ImageDescription'] );
   457 			$description_length = strlen( $exif['ImageDescription'] );
   452 		}
   474 		}
   453 
   475 
   454 		if ( empty( $meta['credit'] ) ) {
   476 		if ( empty( $meta['credit'] ) ) {
   455 			if ( ! empty( $exif['Artist'] ) ) {
   477 			if ( ! empty( $exif['Artist'] ) ) {
   456 				$meta['credit'] = trim( $exif['Artist'] );
   478 				$meta['credit'] = trim( $exif['Artist'] );
   457 			} elseif ( ! empty($exif['Author'] ) ) {
   479 			} elseif ( ! empty( $exif['Author'] ) ) {
   458 				$meta['credit'] = trim( $exif['Author'] );
   480 				$meta['credit'] = trim( $exif['Author'] );
   459 			}
   481 			}
   460 		}
   482 		}
   461 
   483 
   462 		if ( empty( $meta['copyright'] ) && ! empty( $exif['Copyright'] ) ) {
   484 		if ( empty( $meta['copyright'] ) && ! empty( $exif['Copyright'] ) ) {
   503 	/**
   525 	/**
   504 	 * Filters the array of meta data read from an image's exif data.
   526 	 * Filters the array of meta data read from an image's exif data.
   505 	 *
   527 	 *
   506 	 * @since 2.5.0
   528 	 * @since 2.5.0
   507 	 * @since 4.4.0 The `$iptc` parameter was added.
   529 	 * @since 4.4.0 The `$iptc` parameter was added.
   508 	 *
   530 	 * @since 5.0.0 The `$exif` parameter was added.
   509 	 * @param array  $meta            Image meta data.
   531 	 *
   510 	 * @param string $file            Path to image file.
   532 	 * @param array  $meta       Image meta data.
   511 	 * @param int    $sourceImageType Type of image.
   533 	 * @param string $file       Path to image file.
   512 	 * @param array  $iptc            IPTC data.
   534 	 * @param int    $image_type Type of image, one of the `IMAGETYPE_XXX` constants.
       
   535 	 * @param array  $iptc       IPTC data.
       
   536 	 * @param array  $exif       EXIF data.
   513 	 */
   537 	 */
   514 	return apply_filters( 'wp_read_image_metadata', $meta, $file, $sourceImageType, $iptc );
   538 	return apply_filters( 'wp_read_image_metadata', $meta, $file, $image_type, $iptc, $exif );
   515 
   539 
   516 }
   540 }
   517 
   541 
   518 /**
   542 /**
   519  * Validate that file is an image.
   543  * Validate that file is an image.
   521  * @since 2.5.0
   545  * @since 2.5.0
   522  *
   546  *
   523  * @param string $path File path to test if valid image.
   547  * @param string $path File path to test if valid image.
   524  * @return bool True if valid image, false if not valid image.
   548  * @return bool True if valid image, false if not valid image.
   525  */
   549  */
   526 function file_is_valid_image($path) {
   550 function file_is_valid_image( $path ) {
   527 	$size = @getimagesize($path);
   551 	$size = @getimagesize( $path );
   528 	return !empty($size);
   552 	return ! empty( $size );
   529 }
   553 }
   530 
   554 
   531 /**
   555 /**
   532  * Validate that file is suitable for displaying within a web page.
   556  * Validate that file is suitable for displaying within a web page.
   533  *
   557  *
   534  * @since 2.5.0
   558  * @since 2.5.0
   535  *
   559  *
   536  * @param string $path File path to test.
   560  * @param string $path File path to test.
   537  * @return bool True if suitable, false if not suitable.
   561  * @return bool True if suitable, false if not suitable.
   538  */
   562  */
   539 function file_is_displayable_image($path) {
   563 function file_is_displayable_image( $path ) {
   540 	$displayable_image_types = array( IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG, IMAGETYPE_BMP );
   564 	$displayable_image_types = array( IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG, IMAGETYPE_BMP );
       
   565 
       
   566 	// IMAGETYPE_ICO is only defined in PHP 5.3+.
       
   567 	if ( defined( 'IMAGETYPE_ICO' ) ) {
       
   568 		$displayable_image_types[] = IMAGETYPE_ICO;
       
   569 	}
   541 
   570 
   542 	$info = @getimagesize( $path );
   571 	$info = @getimagesize( $path );
   543 	if ( empty( $info ) ) {
   572 	if ( empty( $info ) ) {
   544 		$result = false;
   573 		$result = false;
   545 	} elseif ( ! in_array( $info[2], $displayable_image_types ) ) {
   574 	} elseif ( ! in_array( $info[2], $displayable_image_types ) ) {
   569  * @param string $size Optional. Image size, defaults to 'full'.
   598  * @param string $size Optional. Image size, defaults to 'full'.
   570  * @return resource|false The resulting image resource on success, false on failure.
   599  * @return resource|false The resulting image resource on success, false on failure.
   571  */
   600  */
   572 function load_image_to_edit( $attachment_id, $mime_type, $size = 'full' ) {
   601 function load_image_to_edit( $attachment_id, $mime_type, $size = 'full' ) {
   573 	$filepath = _load_image_to_edit_path( $attachment_id, $size );
   602 	$filepath = _load_image_to_edit_path( $attachment_id, $size );
   574 	if ( empty( $filepath ) )
   603 	if ( empty( $filepath ) ) {
   575 		return false;
   604 		return false;
       
   605 	}
   576 
   606 
   577 	switch ( $mime_type ) {
   607 	switch ( $mime_type ) {
   578 		case 'image/jpeg':
   608 		case 'image/jpeg':
   579 			$image = imagecreatefromjpeg($filepath);
   609 			$image = imagecreatefromjpeg( $filepath );
   580 			break;
   610 			break;
   581 		case 'image/png':
   611 		case 'image/png':
   582 			$image = imagecreatefrompng($filepath);
   612 			$image = imagecreatefrompng( $filepath );
   583 			break;
   613 			break;
   584 		case 'image/gif':
   614 		case 'image/gif':
   585 			$image = imagecreatefromgif($filepath);
   615 			$image = imagecreatefromgif( $filepath );
   586 			break;
   616 			break;
   587 		default:
   617 		default:
   588 			$image = false;
   618 			$image = false;
   589 			break;
   619 			break;
   590 	}
   620 	}
   591 	if ( is_resource($image) ) {
   621 	if ( is_resource( $image ) ) {
   592 		/**
   622 		/**
   593 		 * Filters the current image being loaded for editing.
   623 		 * Filters the current image being loaded for editing.
   594 		 *
   624 		 *
   595 		 * @since 2.9.0
   625 		 * @since 2.9.0
   596 		 *
   626 		 *
   597 		 * @param resource $image         Current image.
   627 		 * @param resource $image         Current image.
   598 		 * @param string   $attachment_id Attachment ID.
   628 		 * @param string   $attachment_id Attachment ID.
   599 		 * @param string   $size          Image size.
   629 		 * @param string   $size          Image size.
   600 		 */
   630 		 */
   601 		$image = apply_filters( 'load_image_to_edit', $image, $attachment_id, $size );
   631 		$image = apply_filters( 'load_image_to_edit', $image, $attachment_id, $size );
   602 		if ( function_exists('imagealphablending') && function_exists('imagesavealpha') ) {
   632 		if ( function_exists( 'imagealphablending' ) && function_exists( 'imagesavealpha' ) ) {
   603 			imagealphablending($image, false);
   633 			imagealphablending( $image, false );
   604 			imagesavealpha($image, true);
   634 			imagesavealpha( $image, true );
   605 		}
   635 		}
   606 	}
   636 	}
   607 	return $image;
   637 	return $image;
   608 }
   638 }
   609 
   639 
   674  * @param string $attachment_id Attachment ID.
   704  * @param string $attachment_id Attachment ID.
   675  * @return string|false New file path on success, false on failure.
   705  * @return string|false New file path on success, false on failure.
   676  */
   706  */
   677 function _copy_image_file( $attachment_id ) {
   707 function _copy_image_file( $attachment_id ) {
   678 	$dst_file = $src_file = get_attached_file( $attachment_id );
   708 	$dst_file = $src_file = get_attached_file( $attachment_id );
   679 	if ( ! file_exists( $src_file ) )
   709 	if ( ! file_exists( $src_file ) ) {
   680 		$src_file = _load_image_to_edit_path( $attachment_id );
   710 		$src_file = _load_image_to_edit_path( $attachment_id );
       
   711 	}
   681 
   712 
   682 	if ( $src_file ) {
   713 	if ( $src_file ) {
   683 		$dst_file = str_replace( basename( $dst_file ), 'copy-' . basename( $dst_file ), $dst_file );
   714 		$dst_file = str_replace( wp_basename( $dst_file ), 'copy-' . wp_basename( $dst_file ), $dst_file );
   684 		$dst_file = dirname( $dst_file ) . '/' . wp_unique_filename( dirname( $dst_file ), basename( $dst_file ) );
   715 		$dst_file = dirname( $dst_file ) . '/' . wp_unique_filename( dirname( $dst_file ), wp_basename( $dst_file ) );
   685 
   716 
   686 		/*
   717 		/*
   687 		 * The directory containing the original file may no longer
   718 		 * The directory containing the original file may no longer
   688 		 * exist when using a replication plugin.
   719 		 * exist when using a replication plugin.
   689 		 */
   720 		 */
   690 		wp_mkdir_p( dirname( $dst_file ) );
   721 		wp_mkdir_p( dirname( $dst_file ) );
   691 
   722 
   692 		if ( ! @copy( $src_file, $dst_file ) )
   723 		if ( ! @copy( $src_file, $dst_file ) ) {
   693 			$dst_file = false;
   724 			$dst_file = false;
       
   725 		}
   694 	} else {
   726 	} else {
   695 		$dst_file = false;
   727 		$dst_file = false;
   696 	}
   728 	}
   697 
   729 
   698 	return $dst_file;
   730 	return $dst_file;