Generates attachment meta data and create image sub-sizes for images.
Parameters
$attachment_id
intrequired- Attachment ID to process.
$file
stringrequired- Filepath of the attached image.
Source
function wp_generate_attachment_metadata( $attachment_id, $file ) {
$attachment = get_post( $attachment_id );
$metadata = array();
$support = false;
$mime_type = get_post_mime_type( $attachment );
if ( 'image/heic' === $mime_type || ( preg_match( '!^image/!', $mime_type ) && file_is_displayable_image( $file ) ) ) {
// Make thumbnails and other intermediate sizes.
$metadata = wp_create_image_subsizes( $file, $attachment_id );
} elseif ( wp_attachment_is( 'video', $attachment ) ) {
$metadata = wp_read_video_metadata( $file );
$support = current_theme_supports( 'post-thumbnails', 'attachment:video' ) || post_type_supports( 'attachment:video', 'thumbnail' );
} elseif ( wp_attachment_is( 'audio', $attachment ) ) {
$metadata = wp_read_audio_metadata( $file );
$support = current_theme_supports( 'post-thumbnails', 'attachment:audio' ) || post_type_supports( 'attachment:audio', 'thumbnail' );
}
/*
* wp_read_video_metadata() and wp_read_audio_metadata() return `false`
* if the attachment does not exist in the local filesystem,
* so make sure to convert the value to an array.
*/
if ( ! is_array( $metadata ) ) {
$metadata = array();
}
if ( $support && ! empty( $metadata['image']['data'] ) ) {
// Check for existing cover.
$hash = md5( $metadata['image']['data'] );
$posts = get_posts(
array(
'fields' => 'ids',
'post_type' => 'attachment',
'post_mime_type' => $metadata['image']['mime'],
'post_status' => 'inherit',
'posts_per_page' => 1,
'meta_key' => '_cover_hash',
'meta_value' => $hash,
)
);
$exists = reset( $posts );
if ( ! empty( $exists ) ) {
update_post_meta( $attachment_id, '_thumbnail_id', $exists );
} else {
$ext = '.jpg';
switch ( $metadata['image']['mime'] ) {
case 'image/gif':
$ext = '.gif';
break;
case 'image/png':
$ext = '.png';
break;
case 'image/webp':
$ext = '.webp';
break;
}
$basename = str_replace( '.', '-', wp_basename( $file ) ) . '-image' . $ext;
$uploaded = wp_upload_bits( $basename, '', $metadata['image']['data'] );
if ( false === $uploaded['error'] ) {
$image_attachment = array(
'post_mime_type' => $metadata['image']['mime'],
'post_type' => 'attachment',
'post_content' => '',
);
/**
* Filters the parameters for the attachment thumbnail creation.
*
* @since 3.9.0
*
* @param array $image_attachment An array of parameters to create the thumbnail.
* @param array $metadata Current attachment metadata.
* @param array $uploaded {
* Information about the newly-uploaded file.
*
* @type string $file Filename of the newly-uploaded file.
* @type string $url URL of the uploaded file.
* @type string $type File type.
* }
*/
$image_attachment = apply_filters( 'attachment_thumbnail_args', $image_attachment, $metadata, $uploaded );
$sub_attachment_id = wp_insert_attachment( $image_attachment, $uploaded['file'] );
add_post_meta( $sub_attachment_id, '_cover_hash', $hash );
$attach_data = wp_generate_attachment_metadata( $sub_attachment_id, $uploaded['file'] );
wp_update_attachment_metadata( $sub_attachment_id, $attach_data );
update_post_meta( $attachment_id, '_thumbnail_id', $sub_attachment_id );
}
}
} elseif ( 'application/pdf' === $mime_type ) {
// Try to create image thumbnails for PDFs.
$fallback_sizes = array(
'thumbnail',
'medium',
'large',
);
/**
* Filters the image sizes generated for non-image mime types.
*
* @since 4.7.0
*
* @param string[] $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 );
$registered_sizes = wp_get_registered_image_subsizes();
$merged_sizes = array_intersect_key( $registered_sizes, array_flip( $fallback_sizes ) );
// Force thumbnails to be soft crops.
if ( isset( $merged_sizes['thumbnail'] ) && is_array( $merged_sizes['thumbnail'] ) ) {
$merged_sizes['thumbnail']['crop'] = false;
}
// Only load PDFs in an image editor if we're processing sizes.
if ( ! empty( $merged_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 ) ) {
$image_file = $uploaded['path'];
unset( $uploaded['path'] );
$metadata['sizes'] = array(
'full' => $uploaded,
);
// Save the meta data before any image post-processing errors could happen.
wp_update_attachment_metadata( $attachment_id, $metadata );
// Create sub-sizes saving the image meta after each.
$metadata = _wp_make_subsizes( $merged_sizes, $image_file, $metadata, $attachment_id );
}
}
}
}
// Remove the blob of binary data from the array.
unset( $metadata['image']['data'] );
// Capture file size for cases where it has not been captured yet, such as PDFs.
if ( ! isset( $metadata['filesize'] ) && file_exists( $file ) ) {
$metadata['filesize'] = wp_filesize( $file );
}
/**
* Filters the generated attachment meta data.
*
* @since 2.1.0
* @since 5.3.0 The `$context` parameter was added.
*
* @param array $metadata An array of attachment meta data.
* @param int $attachment_id Current attachment ID.
* @param string $context Additional context. Can be 'create' when metadata was initially created for new attachment
* or 'update' when the metadata was updated.
*/
return apply_filters( 'wp_generate_attachment_metadata', $metadata, $attachment_id, 'create' );
}
Hooks
- apply_filters( ‘attachment_thumbnail_args’,
array $image_attachment ,array $metadata ,array $uploaded ) Filters the parameters for the attachment thumbnail creation.
- apply_filters( ‘fallback_intermediate_image_sizes’,
string[] $fallback_sizes ,array $metadata ) Filters the image sizes generated for non-image mime types.
- apply_filters( ‘wp_generate_attachment_metadata’,
array $metadata ,int $attachment_id ,string $context ) Filters the generated attachment meta data.
Example
To generate attachment metadata for attachment with parent post ID 37:
image.php
file – as this function relies on it. I.G:require_once ABSPATH . 'wp-admin/includes/image.php';