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 |
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'] ); |
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 |