WordPress Version: 4.4
/**
* Adds 'srcset' and 'sizes' attributes to an existing 'img' element.
*
* @since 4.4.0
*
* @see wp_calculate_image_srcset()
* @see wp_calculate_image_sizes()
*
* @param string $image An HTML 'img' element to be filtered.
* @param array $image_meta The image meta data as returned by 'wp_get_attachment_metadata()'.
* @param int $attachment_id Image attachment ID.
* @return string Converted 'img' element with 'srcset' and 'sizes' attributes added.
*/
function wp_image_add_srcset_and_sizes($image, $image_meta, $attachment_id)
{
// Ensure the image meta exists.
if (empty($image_meta['sizes'])) {
return $image;
}
$image_src = preg_match('/src="([^"]+)"/', $image, $match_src) ? $match_src[1] : '';
list($image_src) = explode('?', $image_src);
// Return early if we couldn't get the image source.
if (!$image_src) {
return $image;
}
// Bail early if an image has been inserted and later edited.
if (preg_match('/-e[0-9]{13}/', $image_meta['file'], $img_edit_hash) && strpos(wp_basename($image_src), $img_edit_hash[0]) === false) {
return $image;
}
$base_url = trailingslashit(_wp_upload_dir_baseurl());
$image_base_url = $base_url;
$dirname = dirname($image_meta['file']);
if ($dirname !== '.') {
$image_base_url .= trailingslashit($dirname);
}
$all_sizes = wp_list_pluck($image_meta['sizes'], 'file');
foreach ($all_sizes as $key => $file) {
$all_sizes[$key] = $image_base_url . $file;
}
// Add the original image.
$all_sizes[] = $base_url . $image_meta['file'];
// Bail early if the image src doesn't match any of the known image sizes.
if (!in_array($image_src, $all_sizes)) {
return $image;
}
$width = preg_match('/ width="([0-9]+)"/', $image, $match_width) ? (int) $match_width[1] : 0;
$height = preg_match('/ height="([0-9]+)"/', $image, $match_height) ? (int) $match_height[1] : 0;
if (!$width || !$height) {
/*
* If attempts to parse the size value failed, attempt to use the image meta data to match
* the image file name from 'src' against the available sizes for an attachment.
*/
$image_filename = wp_basename($image_src);
if ($image_filename === wp_basename($image_meta['file'])) {
$width = (int) $image_meta['width'];
$height = (int) $image_meta['height'];
} else {
foreach ($image_meta['sizes'] as $image_size_data) {
if ($image_filename === $image_size_data['file']) {
$width = (int) $image_size_data['width'];
$height = (int) $image_size_data['height'];
break;
}
}
}
}
if (!$width || !$height) {
return $image;
}
$size_array = array($width, $height);
$srcset = wp_calculate_image_srcset($size_array, $image_src, $image_meta, $attachment_id);
if ($srcset) {
// Check if there is already a 'sizes' attribute.
$sizes = strpos($image, ' sizes=');
if (!$sizes) {
$sizes = wp_calculate_image_sizes($size_array, $image_src, $image_meta, $attachment_id);
}
}
if ($srcset && $sizes) {
// Format the 'srcset' and 'sizes' string and escape attributes.
$attr = sprintf(' srcset="%s"', esc_attr($srcset));
if (is_string($sizes)) {
$attr .= sprintf(' sizes="%s"', esc_attr($sizes));
}
// Add 'srcset' and 'sizes' attributes to the image markup.
$image = preg_replace('/<img ([^>]+?)[\/ ]*>/', '<img $1' . $attr . ' />', $image);
}
return $image;
}