Responsive images:
- Introduce `wp_calculate_image_srcset()` that replaces `wp_get_attachment_image_srcset_array()` and is used as lower level function for retrieving the srcset data as array. - Use the new function when generating `srcset` and `sizes` on the front-end. This is faster as no (other) image API functions are used. - Change the `wp_get_attachment_image_srcset()`. Now it is meant for use in templates and is no longer used in core. - A few logic fixes and improvements. - Some names changed to be (hopefully) more descriptive. - Fixed/updated tests. Props joemcgill, jaspermdegroot, azaozz. See #34430. Built from https://develop.svn.wordpress.org/trunk@35412 git-svn-id: http://core.svn.wordpress.org/trunk@35376 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
parent
8d0f76bc11
commit
61d21cc0d9
|
@ -813,13 +813,14 @@ function wp_get_attachment_image($attachment_id, $size = 'thumbnail', $icon = fa
|
||||||
|
|
||||||
// Generate srcset and sizes if not already present.
|
// Generate srcset and sizes if not already present.
|
||||||
if ( empty( $attr['srcset'] ) ) {
|
if ( empty( $attr['srcset'] ) ) {
|
||||||
$srcset = wp_get_attachment_image_srcset( $attachment_id, $size );
|
$image_meta = wp_get_attachment_metadata( $attachment_id );
|
||||||
$sizes = wp_get_attachment_image_sizes( $attachment_id, $size, $width );
|
$size_array = array( absint( $width ), absint( $height ) );
|
||||||
|
$sources = wp_calculate_image_srcset( $src, $size_array, $image_meta, $attachment_id );
|
||||||
|
|
||||||
if ( $srcset && $sizes ) {
|
if ( count( $sources ) > 1 ) {
|
||||||
$attr['srcset'] = $srcset;
|
$attr['srcset'] = wp_image_srcset_attr( $sources, $size_array, $image_meta, $attachment_id );
|
||||||
|
|
||||||
if ( empty( $attr['sizes'] ) ) {
|
if ( empty( $attr['sizes'] ) && ( $sizes = wp_get_attachment_image_sizes( $size_array, $image_meta, $attachment_id ) ) ) {
|
||||||
$attr['sizes'] = $sizes;
|
$attr['sizes'] = $sizes;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -864,15 +865,118 @@ function wp_get_attachment_image_url( $attachment_id, $size = 'thumbnail', $icon
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves an array of URLs and pixel widths representing sizes of an image.
|
* Private, do not use
|
||||||
*
|
*/
|
||||||
* The purpose is to populate a source set when creating responsive image markup.
|
function _wp_upload_dir_baseurl() {
|
||||||
|
static $baseurl = null;
|
||||||
|
|
||||||
|
if ( ! $baseurl ) {
|
||||||
|
$uploads_dir = wp_upload_dir();
|
||||||
|
$baseurl = $uploads_dir['baseurl'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $baseurl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Private, do not use
|
||||||
|
*/
|
||||||
|
function _wp_get_image_size_from_meta( $size, $image_meta ) {
|
||||||
|
if ( $size === 'full' ) {
|
||||||
|
return array(
|
||||||
|
absint( $image_meta['width'] ),
|
||||||
|
absint( $image_meta['height'] ),
|
||||||
|
);
|
||||||
|
} elseif ( ! empty( $image_meta['sizes'][$size] ) ) {
|
||||||
|
return array(
|
||||||
|
absint( $image_meta['sizes'][$size]['width'] ),
|
||||||
|
absint( $image_meta['sizes'][$size]['height'] ),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the value for an image attachment's 'srcset' attribute.
|
||||||
*
|
*
|
||||||
* @since 4.4.0
|
* @since 4.4.0
|
||||||
*
|
*
|
||||||
|
|
||||||
|
* @param int $attachment_id Optional. Image attachment ID.
|
||||||
|
* @param array|string $size Image size. Accepts any valid image size, or an array of width and height
|
||||||
|
* values in pixels (in that order). Default 'medium'.
|
||||||
|
* @param array $image_meta Optional. The image meta data.
|
||||||
|
* @return string|bool A 'srcset' value string or false.
|
||||||
|
*/
|
||||||
|
function wp_get_attachment_image_srcset( $attachment_id, $size = 'medium', $image_meta = null ) {
|
||||||
|
if ( ! $image = wp_get_attachment_image_src( $attachment_id, $size ) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! is_array( $image_meta ) ) {
|
||||||
|
$image_meta = get_post_meta( $attachment_id, '_wp_attachment_metadata', true );
|
||||||
|
}
|
||||||
|
|
||||||
|
$image_url = $image[0];
|
||||||
|
$size_array = array(
|
||||||
|
absint( $image[1] ),
|
||||||
|
absint( $image[2] )
|
||||||
|
);
|
||||||
|
|
||||||
|
// Calculate the sources for the srcset.
|
||||||
|
$sources = wp_calculate_image_srcset( $image_url, $size_array, $image_meta, $attachment_id );
|
||||||
|
|
||||||
|
// Only return a srcset value if there is more than one source.
|
||||||
|
if ( count( $sources ) < 2 ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return wp_image_srcset_attr( $sources, $size_array, $image_meta, $attachment_id );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A helper function to concatenate and filter the srcset attribute value.
|
||||||
|
*
|
||||||
|
* @since 4.4.0
|
||||||
|
*
|
||||||
|
* @param array $sources The array containing image sizes data as returned by wp_calculate_image_srcset().
|
||||||
|
* @param array $size_array Array of width and height values in pixels (in that order).
|
||||||
|
* @param array $image_meta The image meta data.
|
||||||
|
* @param int $attachment_id The image attachment post id to pass to the filter.
|
||||||
|
* @return string The srcset attribute value.
|
||||||
|
*/
|
||||||
|
function wp_image_srcset_attr( $sources, $size_array, $image_meta, $attachment_id ) {
|
||||||
|
$srcset = '';
|
||||||
|
|
||||||
|
foreach ( $sources as $source ) {
|
||||||
|
$srcset .= $source['url'] . ' ' . $source['value'] . $source['descriptor'] . ', ';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter the output of wp_get_attachment_image_srcset().
|
||||||
|
*
|
||||||
|
* @since 4.4.0
|
||||||
|
*
|
||||||
|
* @param string $srcset A source set formatted for a `srcset` attribute.
|
||||||
* @param int $attachment_id Image attachment ID.
|
* @param int $attachment_id Image attachment ID.
|
||||||
* @param array|string $size Image size. Accepts any valid image size, or an array of width and height
|
* @param array|string $size Image size. Accepts any valid image size, or an array of width and height
|
||||||
* values in pixels (in that order). Default 'medium'.
|
* values in pixels (in that order). Default 'medium'.
|
||||||
|
* @param array $image_meta The image meta data.
|
||||||
|
*/
|
||||||
|
return apply_filters( 'wp_get_attachment_image_srcset', rtrim( $srcset, ', ' ), $attachment_id, $size_array, $image_meta );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A helper function to caclulate the image sources to include in a srcset attribute.
|
||||||
|
*
|
||||||
|
* @since 4.4.0
|
||||||
|
*
|
||||||
|
* @param string $image_name The file name, path, URL or partial path or URL of the image being matched.
|
||||||
|
* @param array $size_array Array of width and height values in pixels (in that order).
|
||||||
|
* @param array $image_meta The image meta data.
|
||||||
|
* @param int $attachment_id Optional. The image attachment post id to pass to the filter.
|
||||||
* @return array|bool $sources {
|
* @return array|bool $sources {
|
||||||
* Array image candidate values containing a URL, descriptor type, and
|
* Array image candidate values containing a URL, descriptor type, and
|
||||||
* descriptor value. False if none exist.
|
* descriptor value. False if none exist.
|
||||||
|
@ -886,103 +990,91 @@ function wp_get_attachment_image_url( $attachment_id, $size = 'thumbnail', $icon
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
function wp_get_attachment_image_srcset_array( $attachment_id, $size = 'medium' ) {
|
function wp_calculate_image_srcset( $image_name, $size_array, $image_meta, $attachment_id = 0 ) {
|
||||||
// Get the intermediate size.
|
if ( empty( $image_meta['sizes'] ) ) {
|
||||||
$image = image_get_intermediate_size( $attachment_id, $size );
|
|
||||||
|
|
||||||
// Get the post meta.
|
|
||||||
$img_meta = wp_get_attachment_metadata( $attachment_id );
|
|
||||||
if ( ! is_array( $img_meta ) ) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract the height and width from the intermediate or the full size.
|
$image_sizes = $image_meta['sizes'];
|
||||||
$img_width = ( $image ) ? $image['width'] : $img_meta['width'];
|
|
||||||
$img_height = ( $image ) ? $image['height'] : $img_meta['height'];
|
|
||||||
|
|
||||||
// Bail early if the width isn't greater than zero.
|
// Get the height and width for the image.
|
||||||
if ( ! $img_width > 0 ) {
|
$image_width = (int) $size_array[0];
|
||||||
|
$image_height = (int) $size_array[1];
|
||||||
|
|
||||||
|
// Bail early if error/no width.
|
||||||
|
if ( $image_width < 1 ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use the URL from the intermediate size or build the url from the metadata.
|
|
||||||
if ( ! empty( $image['url'] ) ) {
|
|
||||||
$img_url = $image['url'];
|
|
||||||
} else {
|
|
||||||
$uploads_dir = wp_upload_dir();
|
|
||||||
$img_file = ( $image ) ? path_join( dirname( $img_meta['file'] ) , $image['file'] ) : $img_meta['file'];
|
|
||||||
$img_url = $uploads_dir['baseurl'] . '/' . $img_file;
|
|
||||||
}
|
|
||||||
|
|
||||||
$img_sizes = $img_meta['sizes'];
|
|
||||||
|
|
||||||
// Add full size to the img_sizes array.
|
// Add full size to the img_sizes array.
|
||||||
$img_sizes['full'] = array(
|
$image_sizes['full'] = array(
|
||||||
'width' => $img_meta['width'],
|
'width' => $image_meta['width'],
|
||||||
'height' => $img_meta['height'],
|
'height' => $image_meta['height'],
|
||||||
'file' => wp_basename( $img_meta['file'] )
|
'file' => wp_basename( $image_meta['file'] ),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$image_baseurl = _wp_upload_dir_baseurl();
|
||||||
|
$dirname = dirname( $image_meta['file'] );
|
||||||
|
|
||||||
|
if ( $dirname !== '.' ) {
|
||||||
|
$image_baseurl = path_join( $image_baseurl, $dirname );
|
||||||
|
}
|
||||||
|
|
||||||
// Calculate the image aspect ratio.
|
// Calculate the image aspect ratio.
|
||||||
$img_ratio = $img_height / $img_width;
|
$image_ratio = $image_height / $image_width;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Images that have been edited in WordPress after being uploaded will
|
* Images that have been edited in WordPress after being uploaded will
|
||||||
* contain a unique hash. Look for that hash and use it later to filter
|
* contain a unique hash. Look for that hash and use it later to filter
|
||||||
* out images that are leftovers from previous versions.
|
* out images that are leftovers from previous versions.
|
||||||
*/
|
*/
|
||||||
$img_edited = preg_match( '/-e[0-9]{13}/', $img_url, $img_edit_hash );
|
$image_edited = preg_match( '/-e[0-9]{13}/', $image_name, $image_edit_hash );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Filter the maximum width included in a srcset attribute.
|
* Filter the maximum width included in a 'srcset' attribute.
|
||||||
*
|
*
|
||||||
* @since 4.4.0
|
* @since 4.4.0
|
||||||
*
|
*
|
||||||
* @param array|string $size Size of image, either array or string.
|
* @param int $max_width The maximum width to include in the 'srcset'. Default '1600'.
|
||||||
|
* @param array|string $size_array Array of width and height values in pixels (in that order).
|
||||||
*/
|
*/
|
||||||
$max_srcset_width = apply_filters( 'max_srcset_image_width', 1600, $size );
|
$max_srcset_width = apply_filters( 'max_srcset_image_width', 1600, $size_array );
|
||||||
|
|
||||||
|
// Array to hold URL candidates.
|
||||||
|
$sources = array();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set up arrays to hold url candidates and matched image sources so
|
* Loop through available images. Only use images that are resized
|
||||||
* we can avoid duplicates without looping through the full sources array
|
* versions of the same edit.
|
||||||
*/
|
*/
|
||||||
$candidates = $sources = array();
|
foreach ( $image_sizes as $image ) {
|
||||||
|
|
||||||
/*
|
// Filter out images that are from previous edits.
|
||||||
* Loop through available images and only use images that are resized
|
if ( $image_edited && ! strpos( $image['file'], $image_edit_hash[0] ) ) {
|
||||||
* versions of the same rendition.
|
|
||||||
*/
|
|
||||||
foreach ( $img_sizes as $img ) {
|
|
||||||
|
|
||||||
// Filter out images that are leftovers from previous renditions.
|
|
||||||
if ( $img_edited && ! strpos( $img['file'], $img_edit_hash[0] ) ) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Filter out images that are wider than $max_srcset_width.
|
// Filter out images that are wider than $max_srcset_width.
|
||||||
if ( $max_srcset_width && $img['width'] > $max_srcset_width ) {
|
if ( $max_srcset_width && $image['width'] > $max_srcset_width ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$candidate_url = path_join( dirname( $img_url ), $img['file'] );
|
$candidate_url = $image['file'];
|
||||||
|
|
||||||
// Calculate the new image ratio.
|
// Calculate the new image ratio.
|
||||||
if ( $img['width'] ) {
|
if ( $image['width'] ) {
|
||||||
$img_ratio_compare = $img['height'] / $img['width'];
|
$image_ratio_compare = $image['height'] / $image['width'];
|
||||||
} else {
|
} else {
|
||||||
$img_ratio_compare = 0;
|
$image_ratio_compare = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the new ratio differs by less than 0.01, use it.
|
// If the new ratio differs by less than 0.01, use it.
|
||||||
if ( abs( $img_ratio - $img_ratio_compare ) < 0.01 && ! in_array( $candidate_url, $candidates ) ) {
|
if ( abs( $image_ratio - $image_ratio_compare ) < 0.01 && ! array_key_exists( $candidate_url, $sources ) ) {
|
||||||
// Add the URL to our list of candidates.
|
// Add the URL, descriptor, and value to the sources array to be returned.
|
||||||
$candidates[] = $candidate_url;
|
$sources[ $image['width'] ] = array(
|
||||||
|
'url' => path_join( $image_baseurl, $candidate_url ),
|
||||||
// Add the url, descriptor, and value to the sources array to be returned.
|
|
||||||
$sources[] = array(
|
|
||||||
'url' => $candidate_url,
|
|
||||||
'descriptor' => 'w',
|
'descriptor' => 'w',
|
||||||
'value' => $img['width'],
|
'value' => $image['width'],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -992,81 +1084,55 @@ function wp_get_attachment_image_srcset_array( $attachment_id, $size = 'medium'
|
||||||
*
|
*
|
||||||
* @since 4.4.0
|
* @since 4.4.0
|
||||||
*
|
*
|
||||||
* @param array $sources An array of image urls and widths.
|
* @param array $sources An array of image URLs and widths.
|
||||||
* @param int $attachment_id Attachment ID for image.
|
* @param int $attachment_id Attachment ID for image.
|
||||||
* @param array|string $size Image size. Accepts any valid image size, or an array of width and height
|
* @param array|string $size Image size. Accepts any valid image size, or an array of width and height
|
||||||
* values in pixels (in that order). Default 'medium'.
|
* values in pixels (in that order). Default 'medium'.
|
||||||
|
* @param array $image_meta The image meta data.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
return apply_filters( 'wp_get_attachment_image_srcset_array', $sources, $attachment_id, $size );
|
return apply_filters( 'wp_get_attachment_image_srcset_array', array_values( $sources ), $attachment_id, $size_array, $image_meta );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the value for an image attachment's 'srcset' attribute.
|
* Create `sizes` attribute value for an image.
|
||||||
*
|
*
|
||||||
* @since 4.4.0
|
* @since 4.4.0
|
||||||
*
|
*
|
||||||
* @param int $attachment_id Image attachment ID.
|
* @param array|string $size Image size. Accepts any valid image size name (thumbnail, medium, etc.),
|
||||||
* @param array|string $size Image size. Accepts any valid image size, or an array of width and height
|
* or an array of width and height values in pixels (in that order).
|
||||||
* values in pixels (in that order). Default 'medium'.
|
* @param array $image_meta Optional. The image meta data.
|
||||||
* @return string|bool A 'srcset' value string or false.
|
* @param int $attachment_id Optional. Image attachment ID. Either $image_meta or $attachment_id is needed
|
||||||
*/
|
* when using image size name.
|
||||||
function wp_get_attachment_image_srcset( $attachment_id, $size = 'medium' ) {
|
|
||||||
$srcset_array = wp_get_attachment_image_srcset_array( $attachment_id, $size );
|
|
||||||
|
|
||||||
// Only return a srcset value if there is more than one source.
|
|
||||||
if ( count( $srcset_array ) <= 1 ) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$srcset = '';
|
|
||||||
foreach ( $srcset_array as $source ) {
|
|
||||||
$srcset .= $source['url'] . ' ' . $source['value'] . $source['descriptor'] . ', ';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Filter the output of wp_get_attachment_image_srcset().
|
|
||||||
*
|
*
|
||||||
* @since 4.4.0
|
|
||||||
*
|
|
||||||
* @param string $srcset A source set formated for a `srcset` attribute.
|
|
||||||
* @param int $attachment_id Attachment ID for image.
|
|
||||||
* @param array|string $size Image size. Accepts any valid image size, or an array of width and height
|
|
||||||
* values in pixels (in that order). Default 'medium'.
|
|
||||||
*/
|
|
||||||
return apply_filters( 'wp_get_attachment_image_srcset', rtrim( $srcset, ', ' ), $attachment_id, $size );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves a source size attribute for an image from an array of values.
|
|
||||||
*
|
|
||||||
* @since 4.4.0
|
|
||||||
*
|
|
||||||
* @param int $attachment_id Image attachment ID.
|
|
||||||
* @param array|string $size Image size. Accepts any valid image size, or an array of width and height
|
|
||||||
* values in pixels (in that order). Default 'medium'.
|
|
||||||
* @param int $width Optional. Display width of the image.
|
|
||||||
* @return string|bool A valid source size value for use in a 'sizes' attribute or false.
|
* @return string|bool A valid source size value for use in a 'sizes' attribute or false.
|
||||||
*/
|
*/
|
||||||
function wp_get_attachment_image_sizes( $attachment_id, $size = 'medium', $width = null ) {
|
function wp_get_attachment_image_sizes( $size, $image_meta = null, $attachment_id = 0 ) {
|
||||||
// Try to get the image width from the $width parameter.
|
$width = 0;
|
||||||
if ( is_numeric( $width ) ) {
|
|
||||||
$img_width = (int) $width;
|
if ( is_numeric( $size ) ) {
|
||||||
// Next, see if a width value was passed in the $size parameter.
|
$width = absint( $size );
|
||||||
} elseif ( is_array( $size ) ) {
|
} elseif ( is_array( $size ) ) {
|
||||||
$img_width = $size[0];
|
$width = absint( $size[0] );
|
||||||
// Finally, use the $size name to return the width of the image.
|
} elseif ( is_string( $size ) ) {
|
||||||
} else {
|
if ( ! $image_meta && $attachment_id ) {
|
||||||
$image = image_get_intermediate_size( $attachment_id, $size );
|
$image_meta = wp_get_attachment_metadata( $attachment_id );
|
||||||
$img_width = $image ? $image['width'] : false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bail early if $img_width isn't set.
|
if ( $image_meta ) {
|
||||||
if ( ! $img_width ) {
|
$width = _wp_get_image_size_from_meta( $size, $image_meta );
|
||||||
|
if ( $width ) {
|
||||||
|
$width = $width[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! $width ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup the default sizes attribute.
|
// Setup the default sizes attribute.
|
||||||
$sizes = sprintf( '(max-width: %1$dpx) 100vw, %1$dpx', $img_width );
|
$sizes = sprintf( '(max-width: %1$dpx) 100vw, %1$dpx', (int) $width );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Filter the output of wp_get_attachment_image_sizes().
|
* Filter the output of wp_get_attachment_image_sizes().
|
||||||
|
@ -1074,12 +1140,12 @@ function wp_get_attachment_image_sizes( $attachment_id, $size = 'medium', $width
|
||||||
* @since 4.4.0
|
* @since 4.4.0
|
||||||
*
|
*
|
||||||
* @param string $sizes A source size value for use in a 'sizes' attribute.
|
* @param string $sizes A source size value for use in a 'sizes' attribute.
|
||||||
* @param int $attachment_id Post ID of the original image.
|
|
||||||
* @param array|string $size Image size. Accepts any valid image size, or an array of width and height
|
* @param array|string $size Image size. Accepts any valid image size, or an array of width and height
|
||||||
* values in pixels (in that order). Default 'medium'.
|
* values in pixels (in that order). Default 'medium'.
|
||||||
* @param int $width Display width of the image.
|
* @param array $image_meta The image meta data.
|
||||||
|
* @param int $attachment_id Post ID of the original image.
|
||||||
*/
|
*/
|
||||||
return apply_filters( 'wp_get_attachment_image_sizes', $sizes, $attachment_id, $size, $width );
|
return apply_filters( 'wp_get_attachment_image_sizes', $sizes, $size, $image_meta, $attachment_id );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1087,7 +1153,7 @@ function wp_get_attachment_image_sizes( $attachment_id, $size = 'medium', $width
|
||||||
*
|
*
|
||||||
* @since 4.4.0
|
* @since 4.4.0
|
||||||
*
|
*
|
||||||
* @see wp_img_add_srcset_and_sizes()
|
* @see wp_image_add_srcset_and_sizes()
|
||||||
*
|
*
|
||||||
* @param string $content The raw post content to be filtered.
|
* @param string $content The raw post content to be filtered.
|
||||||
* @return string Converted content with 'srcset' and 'sizes' attributes added to images.
|
* @return string Converted content with 'srcset' and 'sizes' attributes added to images.
|
||||||
|
@ -1095,29 +1161,33 @@ function wp_get_attachment_image_sizes( $attachment_id, $size = 'medium', $width
|
||||||
function wp_make_content_images_responsive( $content ) {
|
function wp_make_content_images_responsive( $content ) {
|
||||||
$images = get_media_embedded_in_content( $content, 'img' );
|
$images = get_media_embedded_in_content( $content, 'img' );
|
||||||
|
|
||||||
$attachment_ids = array();
|
$selected_images = $attachment_ids = array();
|
||||||
|
|
||||||
foreach( $images as $image ) {
|
foreach( $images as $image ) {
|
||||||
if ( preg_match( '/wp-image-([0-9]+)/i', $image, $class_id ) ) {
|
if ( false === strpos( $image, ' srcset="' ) && preg_match( '/wp-image-([0-9]+)/i', $image, $class_id ) &&
|
||||||
$attachment_id = (int) $class_id[1];
|
( $attachment_id = absint( $class_id[1] ) ) ) {
|
||||||
if ( $attachment_id ) {
|
|
||||||
$attachment_ids[] = $attachment_id;
|
// If exactly the same image tag is used more than once, overwrite it.
|
||||||
}
|
// All identical tags will be replaced later with str_replace().
|
||||||
|
$selected_images[ $image ] = $attachment_id;
|
||||||
|
// Overwrite the ID when the same image is included more than once.
|
||||||
|
$attachment_ids[ $attachment_id ] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( 0 < count( $attachment_ids ) ) {
|
if ( count( $attachment_ids ) > 1 ) {
|
||||||
/*
|
/*
|
||||||
* Warm object caches for use with wp_get_attachment_metadata.
|
* Warm object cache for use with get_post_meta().
|
||||||
*
|
*
|
||||||
* To avoid making a database call for each image, a single query
|
* To avoid making a database call for each image, a single query
|
||||||
* warms the object cache with the meta information for all images.
|
* warms the object cache with the meta information for all images.
|
||||||
*/
|
*/
|
||||||
_prime_post_caches( $attachment_ids, false, true );
|
update_meta_cache( 'post', array_keys( $attachment_ids ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach( $images as $image ) {
|
foreach ( $selected_images as $image => $attachment_id ) {
|
||||||
$content = str_replace( $image, wp_img_add_srcset_and_sizes( $image ), $content );
|
$image_meta = get_post_meta( $attachment_id, '_wp_attachment_metadata', true );
|
||||||
|
$content = str_replace( $image, wp_image_add_srcset_and_sizes( $image, $image_meta, $attachment_id ), $content );
|
||||||
}
|
}
|
||||||
|
|
||||||
return $content;
|
return $content;
|
||||||
|
@ -1132,73 +1202,75 @@ function wp_make_content_images_responsive( $content ) {
|
||||||
* @see wp_get_attachment_image_sizes()
|
* @see wp_get_attachment_image_sizes()
|
||||||
*
|
*
|
||||||
* @param string $image An HTML 'img' element to be filtered.
|
* @param string $image An HTML 'img' element to be filtered.
|
||||||
|
* @param array $image_meta The image meta data.
|
||||||
|
* @param int $attachment_id Image attachment ID.
|
||||||
* @return string Converted 'img' element with `srcset` and `sizes` attributes added.
|
* @return string Converted 'img' element with `srcset` and `sizes` attributes added.
|
||||||
*/
|
*/
|
||||||
function wp_img_add_srcset_and_sizes( $image ) {
|
function wp_image_add_srcset_and_sizes( $image, $image_meta, $attachment_id ) {
|
||||||
// Return early if a 'srcset' attribute already exists.
|
// Ensure the image meta exists
|
||||||
if ( false !== strpos( $image, ' srcset="' ) ) {
|
if ( empty( $image_meta['sizes'] ) ) {
|
||||||
return $image;
|
return $image;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse id, size, width, and height from the `img` element.
|
$src = preg_match( '/src="([^"]+)"/', $image, $match_src ) ? $match_src[1] : '';
|
||||||
$id = preg_match( '/wp-image-([0-9]+)/i', $image, $match_id ) ? (int) $match_id[1] : false;
|
list( $src ) = explode( '?', $src );
|
||||||
$size = preg_match( '/size-([^\s|"]+)/i', $image, $match_size ) ? $match_size[1] : false;
|
|
||||||
$width = preg_match( '/ width="([0-9]+)"/', $image, $match_width ) ? (int) $match_width[1] : false;
|
|
||||||
|
|
||||||
if ( $id && ! $size ) {
|
// Return early if we coudn't get the image source.
|
||||||
$height = preg_match( '/ height="([0-9]+)"/', $image, $match_height ) ? (int) $match_height[1] : false;
|
if ( ! $src ) {
|
||||||
|
return $image;
|
||||||
if ( $width && $height ) {
|
|
||||||
$size = array( $width, $height );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Bail early when an image has been inserted and later edited.
|
||||||
|
if ( preg_match( '/-e[0-9]{13}/', $image_meta['file'], $img_edit_hash ) &&
|
||||||
|
strpos( wp_basename( $src ), $img_edit_hash[0] ) === false ) {
|
||||||
|
|
||||||
|
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
|
* If attempts to parse the size value failed, attempt to use the image
|
||||||
* metadata to match the 'src' against the available sizes for an attachment.
|
* metadata to match the image file name from 'src' against the available sizes for an attachment.
|
||||||
*/
|
|
||||||
if ( $id && ! $size ) {
|
|
||||||
$meta = wp_get_attachment_metadata( $id );
|
|
||||||
|
|
||||||
// Parse the image src value from the img element.
|
|
||||||
$src = preg_match( '/src="([^"]+)"/', $image, $match_src ) ? $match_src[1] : false;
|
|
||||||
|
|
||||||
// Return early if the metadata does not exist or the src value is empty.
|
|
||||||
if ( ! $meta || ! $src ) {
|
|
||||||
return $image;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* First, see if the file is the full size image. If not, loop through
|
|
||||||
* the intermediate sizes until we find a file that matches.
|
|
||||||
*/
|
*/
|
||||||
$image_filename = wp_basename( $src );
|
$image_filename = wp_basename( $src );
|
||||||
|
|
||||||
if ( $image_filename === basename( $meta['file'] ) ) {
|
if ( $image_filename === wp_basename( $image_meta['file'] ) ) {
|
||||||
$size = 'full';
|
$width = (int) $image_meta['width'];
|
||||||
|
$height = (int) $image_meta['height'];
|
||||||
} else {
|
} else {
|
||||||
foreach( $meta['sizes'] as $image_size => $image_size_data ) {
|
foreach( $image_meta['sizes'] as $image_size_data ) {
|
||||||
if ( $image_filename === $image_size_data['file'] ) {
|
if ( $image_filename === $image_size_data['file'] ) {
|
||||||
$size = $image_size;
|
$width = (int) $image_size_data['width'];
|
||||||
|
$height = (int) $image_size_data['height'];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If ID and size exist, try for 'srcset' and 'sizes' and update the markup.
|
if ( ! $width || ! $height ) {
|
||||||
if ( $id && $size ) {
|
return $image;
|
||||||
$srcset = wp_get_attachment_image_srcset( $id, $size );
|
}
|
||||||
$sizes = wp_get_attachment_image_sizes( $id, $size, $width );
|
|
||||||
|
$size_array = array( $width, $height );
|
||||||
|
$sources = wp_calculate_image_srcset( $src, $size_array, $image_meta, $attachment_id );
|
||||||
|
|
||||||
|
$srcset = $sizes = '';
|
||||||
|
// Only calculate srcset and sizes values if there is more than one source.
|
||||||
|
if ( count( $sources ) > 1 ) {
|
||||||
|
$srcset = wp_image_srcset_attr( $sources, $size_array, $image_meta, $attachment_id );
|
||||||
|
$sizes = wp_get_attachment_image_sizes( $size_array, $image_meta, $attachment_id );
|
||||||
|
}
|
||||||
|
|
||||||
if ( $srcset && $sizes ) {
|
if ( $srcset && $sizes ) {
|
||||||
// Format the srcset and sizes string and escape attributes.
|
// Format the srcset and sizes string and escape attributes.
|
||||||
$srcset_and_sizes = sprintf( ' srcset="%s" sizes="%s"', esc_attr( $srcset ), esc_attr( $sizes) );
|
$srcset_and_sizes = sprintf( ' srcset="%s" sizes="%s"', esc_attr( $srcset ), esc_attr( $sizes ) );
|
||||||
|
|
||||||
// Add srcset and sizes attributes to the image markup.
|
// Add srcset and sizes attributes to the image markup.
|
||||||
$image = preg_replace( '/<img ([^>]+)[\s?][\/?]>/', '<img $1' . $srcset_and_sizes . ' />', $image );
|
$image = preg_replace( '/<img ([^>]+?)[\/ ]*>/', '<img $1' . $srcset_and_sizes . ' />', $image );
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $image;
|
return $image;
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
*
|
*
|
||||||
* @global string $wp_version
|
* @global string $wp_version
|
||||||
*/
|
*/
|
||||||
$wp_version = '4.4-beta1-35411';
|
$wp_version = '4.4-beta1-35412';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.
|
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.
|
||||||
|
|
Loading…
Reference in New Issue