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. |
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 * |