WordPress Version: 6.1
/**
* Generates attachment meta data and create image sub-sizes for images.
*
* @since 2.1.0
* @since 6.0.0 The `$filesize` value was added to the returned array.
*
* @param int $attachment_id Attachment ID to process.
* @param string $file Filepath of the attached image.
* @return array Metadata for attachment.
*/
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 (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');
}