Make WordPress Core


Ignore:
Timestamp:
10/28/2015 05:40:04 AM (11 years ago)
Author:
azaozz
Message:

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.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/media.php

    r35405 r35412  
    814814                // Generate srcset and sizes if not already present.
    815815                if ( empty( $attr['srcset'] ) ) {
    816                         $srcset = wp_get_attachment_image_srcset( $attachment_id, $size );
    817                         $sizes  = wp_get_attachment_image_sizes( $attachment_id, $size, $width );
    818 
    819                         if ( $srcset && $sizes ) {
    820                                 $attr['srcset'] = $srcset;
    821 
    822                                 if ( empty( $attr['sizes'] ) ) {
     816                        $image_meta = wp_get_attachment_metadata( $attachment_id );
     817                        $size_array = array( absint( $width ), absint( $height ) );
     818                        $sources = wp_calculate_image_srcset( $src, $size_array, $image_meta, $attachment_id );
     819
     820                        if ( count( $sources ) > 1 ) {
     821                                $attr['srcset'] = wp_image_srcset_attr( $sources, $size_array, $image_meta, $attachment_id );
     822
     823                                if ( empty( $attr['sizes'] ) && ( $sizes = wp_get_attachment_image_sizes( $size_array, $image_meta, $attachment_id ) ) ) {
    823824                                        $attr['sizes'] = $sizes;
    824825                                }
     
    865866
    866867/**
    867  * Retrieves an array of URLs and pixel widths representing sizes of an image.
    868  *
    869  * The purpose is to populate a source set when creating responsive image markup.
     868 * Private, do not use
     869 */
     870function _wp_upload_dir_baseurl() {
     871        static $baseurl = null;
     872
     873        if ( ! $baseurl ) {
     874                $uploads_dir = wp_upload_dir();
     875                $baseurl = $uploads_dir['baseurl'];
     876        }
     877
     878        return $baseurl;
     879}
     880
     881/**
     882 * Private, do not use
     883 */
     884function _wp_get_image_size_from_meta( $size, $image_meta ) {
     885        if ( $size === 'full' ) {
     886                return array(
     887                        absint( $image_meta['width'] ),
     888                        absint( $image_meta['height'] ),
     889                );
     890        } elseif ( ! empty( $image_meta['sizes'][$size] ) ) {
     891                return array(
     892                        absint( $image_meta['sizes'][$size]['width'] ),
     893                        absint( $image_meta['sizes'][$size]['height'] ),
     894                );
     895        }
     896
     897        return false;
     898}
     899
     900/**
     901 * Retrieves the value for an image attachment's 'srcset' attribute.
    870902 *
    871903 * @since 4.4.0
    872904 *
    873  * @param int          $attachment_id Image attachment ID.
     905
     906 * @param int          $attachment_id Optional. Image attachment ID.
    874907 * @param array|string $size          Image size. Accepts any valid image size, or an array of width and height
    875908 *                                    values in pixels (in that order). Default 'medium'.
     909 * @param array        $image_meta    Optional. The image meta data.
     910 * @return string|bool A 'srcset' value string or false.
     911 */
     912function wp_get_attachment_image_srcset( $attachment_id, $size = 'medium', $image_meta = null ) {
     913        if ( ! $image = wp_get_attachment_image_src( $attachment_id, $size ) ) {
     914                return false;
     915        }
     916
     917        if ( ! is_array( $image_meta ) ) {
     918                $image_meta = get_post_meta( $attachment_id, '_wp_attachment_metadata', true );
     919        }
     920
     921        $image_url = $image[0];
     922        $size_array = array(
     923                absint( $image[1] ),
     924                absint( $image[2] )
     925        );
     926
     927        // Calculate the sources for the srcset.
     928        $sources = wp_calculate_image_srcset( $image_url, $size_array, $image_meta, $attachment_id );
     929
     930        // Only return a srcset value if there is more than one source.
     931        if ( count( $sources ) < 2 ) {
     932                return false;
     933        }
     934
     935        return wp_image_srcset_attr( $sources, $size_array, $image_meta, $attachment_id );
     936}
     937
     938
     939/**
     940 * A helper function to concatenate and filter the srcset attribute value.
     941 *
     942 * @since 4.4.0
     943 *
     944 * @param array   $sources       The array containing image sizes data as returned by wp_calculate_image_srcset().
     945 * @param array   $size_array    Array of width and height values in pixels (in that order).
     946 * @param array   $image_meta    The image meta data.
     947 * @param int     $attachment_id The image attachment post id to pass to the filter.
     948 * @return string The srcset attribute value.
     949 */
     950function wp_image_srcset_attr( $sources, $size_array, $image_meta, $attachment_id ) {
     951        $srcset = '';
     952
     953        foreach ( $sources as $source ) {
     954                $srcset .= $source['url'] . ' ' . $source['value'] . $source['descriptor'] . ', ';
     955        }
     956
     957        /**
     958         * Filter the output of wp_get_attachment_image_srcset().
     959         *
     960         * @since 4.4.0
     961         *
     962         * @param string       $srcset        A source set formatted for a `srcset` attribute.
     963         * @param int          $attachment_id Image attachment ID.
     964         * @param array|string $size          Image size. Accepts any valid image size, or an array of width and height
     965         *                                    values in pixels (in that order). Default 'medium'.
     966         * @param array        $image_meta    The image meta data.
     967         */
     968        return apply_filters( 'wp_get_attachment_image_srcset', rtrim( $srcset, ', ' ), $attachment_id, $size_array, $image_meta );
     969}
     970
     971/**
     972 * A helper function to caclulate the image sources to include in a srcset attribute.
     973 *
     974 * @since 4.4.0
     975 *
     976 * @param string $image_name    The file name, path, URL or partial path or URL of the image being matched.
     977 * @param array  $size_array    Array of width and height values in pixels (in that order).
     978 * @param array  $image_meta    The image meta data.
     979 * @param int    $attachment_id Optional. The image attachment post id to pass to the filter.
    876980 * @return array|bool $sources {
    877981 *     Array image candidate values containing a URL, descriptor type, and
     
    887991 *
    888992 */
    889 function wp_get_attachment_image_srcset_array( $attachment_id, $size = 'medium' ) {
    890         // Get the intermediate size.
    891         $image = image_get_intermediate_size( $attachment_id, $size );
    892 
    893         // Get the post meta.
    894         $img_meta = wp_get_attachment_metadata( $attachment_id );
    895         if ( ! is_array( $img_meta ) ) {
     993function wp_calculate_image_srcset( $image_name, $size_array, $image_meta, $attachment_id = 0 ) {
     994        if ( empty( $image_meta['sizes'] ) ) {
    896995                return false;
    897996        }
    898997
    899         // Extract the height and width from the intermediate or the full size.
    900         $img_width  = ( $image ) ? $image['width']  : $img_meta['width'];
    901         $img_height = ( $image ) ? $image['height'] : $img_meta['height'];
    902 
    903         // Bail early if the width isn't greater than zero.
    904         if ( ! $img_width > 0 ) {
     998        $image_sizes = $image_meta['sizes'];
     999
     1000        // Get the height and width for the image.
     1001        $image_width = (int) $size_array[0];
     1002        $image_height = (int) $size_array[1];
     1003
     1004        // Bail early if error/no width.
     1005        if ( $image_width < 1 ) {
    9051006                return false;
    9061007        }
    9071008
    908         // Use the URL from the intermediate size or build the url from the metadata.
    909         if ( ! empty( $image['url'] ) ) {
    910                 $img_url = $image['url'];
    911         } else {
    912                 $uploads_dir = wp_upload_dir();
    913                 $img_file = ( $image ) ? path_join( dirname( $img_meta['file'] ) , $image['file'] ) : $img_meta['file'];
    914                 $img_url = $uploads_dir['baseurl'] . '/' . $img_file;
    915         }
    916 
    917         $img_sizes = $img_meta['sizes'];
    918 
    9191009        // Add full size to the img_sizes array.
    920         $img_sizes['full'] = array(
    921                 'width'  => $img_meta['width'],
    922                 'height' => $img_meta['height'],
    923                 'file'   => wp_basename( $img_meta['file'] )
     1010        $image_sizes['full'] = array(
     1011                'width'  => $image_meta['width'],
     1012                'height' => $image_meta['height'],
     1013                'file'   => wp_basename( $image_meta['file'] ),
    9241014        );
    9251015
     1016        $image_baseurl = _wp_upload_dir_baseurl();
     1017        $dirname = dirname( $image_meta['file'] );
     1018
     1019        if ( $dirname !== '.' ) {
     1020                $image_baseurl = path_join( $image_baseurl, $dirname );
     1021        }
     1022
    9261023        // Calculate the image aspect ratio.
    927         $img_ratio = $img_height / $img_width;
     1024        $image_ratio = $image_height / $image_width;
    9281025
    9291026        /*
     
    9321029         * out images that are leftovers from previous versions.
    9331030         */
    934         $img_edited = preg_match( '/-e[0-9]{13}/', $img_url, $img_edit_hash );
    935 
    936         /**
    937          * Filter the maximum width included in a srcset attribute.
     1031        $image_edited = preg_match( '/-e[0-9]{13}/', $image_name, $image_edit_hash );
     1032
     1033        /**
     1034         * Filter the maximum width included in a 'srcset' attribute.
    9381035         *
    9391036         * @since 4.4.0
    9401037         *
    941          * @param array|string $size Size of image, either array or string.
    942          */
    943         $max_srcset_width = apply_filters( 'max_srcset_image_width', 1600, $size );
     1038         * @param int          $max_width  The maximum width to include in the 'srcset'. Default '1600'.
     1039         * @param array|string $size_array Array of width and height values in pixels (in that order).
     1040         */
     1041        $max_srcset_width = apply_filters( 'max_srcset_image_width', 1600, $size_array );
     1042
     1043        // Array to hold URL candidates.
     1044        $sources = array();
    9441045
    9451046        /*
    946          * Set up arrays to hold url candidates and matched image sources so
    947          * we can avoid duplicates without looping through the full sources array
    948          */
    949         $candidates = $sources = array();
    950 
    951         /*
    952          * Loop through available images and only use images that are resized
    953          * versions of the same rendition.
    954          */
    955         foreach ( $img_sizes as $img ) {
    956 
    957                 // Filter out images that are leftovers from previous renditions.
    958                 if ( $img_edited && ! strpos( $img['file'], $img_edit_hash[0] ) ) {
     1047         * Loop through available images. Only use images that are resized
     1048         * versions of the same edit.
     1049         */
     1050        foreach ( $image_sizes as $image ) {
     1051
     1052                // Filter out images that are from previous edits.
     1053                if ( $image_edited && ! strpos( $image['file'], $image_edit_hash[0] ) ) {
    9591054                        continue;
    9601055                }
    9611056
    9621057                // Filter out images that are wider than $max_srcset_width.
    963                 if ( $max_srcset_width && $img['width'] > $max_srcset_width ) {
     1058                if ( $max_srcset_width && $image['width'] > $max_srcset_width ) {
    9641059                        continue;
    9651060                }
    9661061
    967                 $candidate_url = path_join( dirname( $img_url ), $img['file'] );
     1062                $candidate_url = $image['file'];
    9681063
    9691064                // Calculate the new image ratio.
    970                 if ( $img['width'] ) {
    971                         $img_ratio_compare = $img['height'] / $img['width'];
     1065                if ( $image['width'] ) {
     1066                        $image_ratio_compare = $image['height'] / $image['width'];
    9721067                } else {
    973                         $img_ratio_compare = 0;
     1068                        $image_ratio_compare = 0;
    9741069                }
    9751070
    9761071                // If the new ratio differs by less than 0.01, use it.
    977                 if ( abs( $img_ratio - $img_ratio_compare ) < 0.01 && ! in_array( $candidate_url, $candidates ) ) {
    978                         // Add the URL to our list of candidates.
    979                         $candidates[] = $candidate_url;
    980 
    981                         // Add the url, descriptor, and value to the sources array to be returned.
    982                         $sources[] = array(
    983                                 'url'        => $candidate_url,
     1072                if ( abs( $image_ratio - $image_ratio_compare ) < 0.01 && ! array_key_exists( $candidate_url, $sources ) ) {
     1073                        // Add the URL, descriptor, and value to the sources array to be returned.
     1074                        $sources[ $image['width'] ] = array(
     1075                                'url'        => path_join( $image_baseurl, $candidate_url ),
    9841076                                'descriptor' => 'w',
    985                                 'value'      => $img['width'],
     1077                                'value'      => $image['width'],
    9861078                        );
    9871079                }
     
    9931085         * @since 4.4.0
    9941086         *
    995          * @param array        $sources       An array of image urls and widths.
     1087         * @param array        $sources       An array of image URLs and widths.
    9961088         * @param int          $attachment_id Attachment ID for image.
    9971089         * @param array|string $size          Image size. Accepts any valid image size, or an array of width and height
    9981090         *                                    values in pixels (in that order). Default 'medium'.
    999          */
    1000         return apply_filters( 'wp_get_attachment_image_srcset_array', $sources, $attachment_id, $size );
    1001 }
    1002 
    1003 /**
    1004  * Retrieves the value for an image attachment's 'srcset' attribute.
     1091         * @param array        $image_meta    The image meta data.
     1092
     1093         */
     1094        return apply_filters( 'wp_get_attachment_image_srcset_array', array_values( $sources ), $attachment_id, $size_array, $image_meta );
     1095}
     1096
     1097/**
     1098 * Create `sizes` attribute value for an image.
    10051099 *
    10061100 * @since 4.4.0
    10071101 *
    1008  * @param int          $attachment_id Image attachment ID.
    1009  * @param array|string $size          Image size. Accepts any valid image size, or an array of width and height
    1010  *                                    values in pixels (in that order). Default 'medium'.
    1011  * @return string|bool A 'srcset' value string or false.
    1012  */
    1013 function wp_get_attachment_image_srcset( $attachment_id, $size = 'medium' ) {
    1014         $srcset_array = wp_get_attachment_image_srcset_array( $attachment_id, $size );
    1015 
    1016         // Only return a srcset value if there is more than one source.
    1017         if ( count( $srcset_array ) <= 1 ) {
     1102 * @param array|string $size          Image size. Accepts any valid image size name (thumbnail, medium, etc.),
     1103 *                                    or an array of width and height values in pixels (in that order).
     1104 * @param array        $image_meta    Optional. The image meta data.
     1105 * @param int          $attachment_id Optional. Image attachment ID. Either $image_meta or $attachment_id is needed
     1106 *                                    when using image size name.
     1107 *
     1108 * @return string|bool A valid source size value for use in a 'sizes' attribute or false.
     1109 */
     1110function wp_get_attachment_image_sizes( $size, $image_meta = null, $attachment_id = 0 ) {
     1111        $width = 0;
     1112
     1113        if ( is_numeric( $size ) ) {
     1114                $width = absint( $size );
     1115        } elseif ( is_array( $size ) ) {
     1116                $width = absint( $size[0] );
     1117        } elseif ( is_string( $size ) ) {
     1118                if ( ! $image_meta && $attachment_id ) {
     1119                        $image_meta = wp_get_attachment_metadata( $attachment_id );
     1120                }
     1121
     1122                if ( $image_meta ) {
     1123                        $width = _wp_get_image_size_from_meta( $size, $image_meta );
     1124                        if ( $width ) {
     1125                                $width = $width[0];
     1126                        }
     1127                }
     1128        }
     1129
     1130        if ( ! $width ) {
    10181131                return false;
    10191132        }
    10201133
    1021         $srcset = '';
    1022         foreach ( $srcset_array as $source ) {
    1023                 $srcset .= $source['url'] . ' ' . $source['value'] . $source['descriptor'] . ', ';
    1024         }
    1025 
    1026         /**
    1027          * Filter the output of wp_get_attachment_image_srcset().
     1134        // Setup the default sizes attribute.
     1135        $sizes = sprintf( '(max-width: %1$dpx) 100vw, %1$dpx', (int) $width );
     1136
     1137        /**
     1138         * Filter the output of wp_get_attachment_image_sizes().
    10281139         *
    10291140         * @since 4.4.0
    10301141         *
    1031          * @param string       $srcset        A source set formated for a `srcset` attribute.
    1032          * @param int          $attachment_id Attachment ID for image.
     1142         * @param string       $sizes         A source size value for use in a 'sizes' attribute.
    10331143         * @param array|string $size          Image size. Accepts any valid image size, or an array of width and height
    10341144         *                                    values in pixels (in that order). Default 'medium'.
    1035          */
    1036         return apply_filters( 'wp_get_attachment_image_srcset', rtrim( $srcset, ', ' ), $attachment_id, $size );
    1037 }
    1038 
    1039 /**
    1040  * Retrieves a source size attribute for an image from an array of values.
     1145         * @param array        $image_meta    The image meta data.
     1146         * @param int          $attachment_id Post ID of the original image.
     1147         */
     1148        return apply_filters( 'wp_get_attachment_image_sizes', $sizes, $size, $image_meta, $attachment_id );
     1149}
     1150
     1151/**
     1152 * Filters 'img' elements in post content to add 'srcset' and 'sizes' attributes.
    10411153 *
    10421154 * @since 4.4.0
    10431155 *
    1044  * @param int          $attachment_id Image attachment ID.
    1045  * @param array|string $size          Image size. Accepts any valid image size, or an array of width and height
    1046  *                                    values in pixels (in that order). Default 'medium'.
    1047  * @param int          $width         Optional. Display width of the image.
    1048  * @return string|bool A valid source size value for use in a 'sizes' attribute or false.
    1049  */
    1050 function wp_get_attachment_image_sizes( $attachment_id, $size = 'medium', $width = null ) {
    1051         // Try to get the image width from the $width parameter.
    1052         if ( is_numeric( $width ) ) {
    1053                 $img_width = (int) $width;
    1054         // Next, see if a width value was passed in the $size parameter.
    1055         } elseif ( is_array( $size ) ) {
    1056                 $img_width = $size[0];
    1057         // Finally, use the $size name to return the width of the image.
    1058         } else {
    1059                 $image = image_get_intermediate_size( $attachment_id, $size );
    1060                 $img_width = $image ? $image['width'] : false;
    1061         }
    1062 
    1063         // Bail early if $img_width isn't set.
    1064         if ( ! $img_width ) {
    1065                 return false;
    1066         }
    1067 
    1068         // Setup the default sizes attribute.
    1069         $sizes = sprintf( '(max-width: %1$dpx) 100vw, %1$dpx', $img_width );
    1070 
    1071         /**
    1072          * Filter the output of wp_get_attachment_image_sizes().
    1073          *
    1074          * @since 4.4.0
    1075          *
    1076          * @param string       $sizes         A source size value for use in a 'sizes' attribute.
    1077          * @param int          $attachment_id Post ID of the original image.
    1078          * @param array|string $size          Image size. Accepts any valid image size, or an array of width and height
    1079          *                                    values in pixels (in that order). Default 'medium'.
    1080          * @param int          $width         Display width of the image.
    1081          */
    1082         return apply_filters( 'wp_get_attachment_image_sizes', $sizes, $attachment_id, $size, $width );
    1083 }
    1084 
    1085 /**
    1086  * Filters 'img' elements in post content to add 'srcset' and 'sizes' attributes.
    1087  *
    1088  * @since 4.4.0
    1089  *
    1090  * @see wp_img_add_srcset_and_sizes()
     1156 * @see wp_image_add_srcset_and_sizes()
    10911157 *
    10921158 * @param string $content The raw post content to be filtered.
     
    10961162        $images = get_media_embedded_in_content( $content, 'img' );
    10971163
    1098         $attachment_ids = array();
     1164        $selected_images = $attachment_ids = array();
    10991165
    11001166        foreach( $images as $image ) {
    1101                 if ( preg_match( '/wp-image-([0-9]+)/i', $image, $class_id ) ) {
    1102                         $attachment_id = (int) $class_id[1];
    1103                         if ( $attachment_id ) {
    1104                                 $attachment_ids[] = $attachment_id;
    1105                         }
    1106                 }
    1107         }
    1108 
    1109         if ( 0 < count( $attachment_ids ) ) {
     1167                if ( false === strpos( $image, ' srcset="' ) && preg_match( '/wp-image-([0-9]+)/i', $image, $class_id ) &&
     1168                        ( $attachment_id = absint( $class_id[1] ) ) ) {
     1169
     1170                        // If exactly the same image tag is used more than once, overwrite it.
     1171                        // All identical tags will be replaced later with str_replace().
     1172                        $selected_images[ $image ] = $attachment_id;
     1173                        // Overwrite the ID when the same image is included more than once.
     1174                        $attachment_ids[ $attachment_id ] = true;
     1175                }
     1176        }
     1177
     1178        if ( count( $attachment_ids ) > 1 ) {
    11101179                /*
    1111                  * Warm object caches for use with wp_get_attachment_metadata.
     1180                 * Warm object cache for use with get_post_meta().
    11121181                 *
    11131182                 * To avoid making a database call for each image, a single query
    11141183                 * warms the object cache with the meta information for all images.
    11151184                 */
    1116                 _prime_post_caches( $attachment_ids, false, true );
    1117         }
    1118 
    1119         foreach( $images as $image ) {
    1120                 $content = str_replace( $image, wp_img_add_srcset_and_sizes( $image ), $content );
     1185                update_meta_cache( 'post', array_keys( $attachment_ids ) );
     1186        }
     1187
     1188        foreach ( $selected_images as $image => $attachment_id ) {
     1189                $image_meta = get_post_meta( $attachment_id, '_wp_attachment_metadata', true );
     1190                $content = str_replace( $image, wp_image_add_srcset_and_sizes( $image, $image_meta, $attachment_id ), $content );
    11211191        }
    11221192
     
    11321202 * @see wp_get_attachment_image_sizes()
    11331203 *
    1134  * @param string $image An HTML 'img' element to be filtered.
     1204 * @param string $image         An HTML 'img' element to be filtered.
     1205 * @param array  $image_meta    The image meta data.
     1206 * @param int    $attachment_id Image attachment ID.
    11351207 * @return string Converted 'img' element with `srcset` and `sizes` attributes added.
    11361208 */
    1137 function wp_img_add_srcset_and_sizes( $image ) {
    1138         // Return early if a 'srcset' attribute already exists.
    1139         if ( false !== strpos( $image, ' srcset="' ) ) {
     1209function wp_image_add_srcset_and_sizes( $image, $image_meta, $attachment_id ) {
     1210        // Ensure the image meta exists
     1211        if ( empty( $image_meta['sizes'] ) ) {
    11401212                return $image;
    11411213        }
    11421214
    1143         // Parse id, size, width, and height from the `img` element.
    1144         $id     = preg_match( '/wp-image-([0-9]+)/i', $image, $match_id     ) ? (int) $match_id[1]     : false;
    1145         $size   = preg_match( '/size-([^\s|"]+)/i',   $image, $match_size   ) ? $match_size[1]         : false;
    1146         $width  = preg_match( '/ width="([0-9]+)"/',  $image, $match_width  ) ? (int) $match_width[1]  : false;
    1147 
    1148         if ( $id && ! $size ) {
    1149                 $height = preg_match( '/ height="([0-9]+)"/', $image, $match_height ) ? (int) $match_height[1] : false;
    1150 
    1151                 if ( $width && $height ) {
    1152                         $size = array( $width, $height );
    1153                 }
    1154         }
    1155 
    1156         /*
    1157          * If attempts to parse the size value failed, attempt to use the image
    1158          * metadata to match the 'src' against the available sizes for an attachment.
    1159          */
    1160         if ( $id && ! $size ) {
    1161                 $meta = wp_get_attachment_metadata( $id );
    1162 
    1163                 // Parse the image src value from the img element.
    1164                 $src = preg_match( '/src="([^"]+)"/', $image, $match_src ) ? $match_src[1] : false;
    1165 
    1166                 // Return early if the metadata does not exist or the src value is empty.
    1167                 if ( ! $meta || ! $src ) {
    1168                         return $image;
    1169                 }
    1170 
     1215        $src = preg_match( '/src="([^"]+)"/', $image, $match_src ) ? $match_src[1] : '';
     1216        list( $src ) = explode( '?', $src );
     1217
     1218        // Return early if we coudn't get the image source.
     1219        if ( ! $src ) {
     1220                return $image;
     1221        }
     1222
     1223        // Bail early when an image has been inserted and later edited.
     1224        if ( preg_match( '/-e[0-9]{13}/', $image_meta['file'], $img_edit_hash ) &&
     1225                strpos( wp_basename( $src ), $img_edit_hash[0] ) === false ) {
     1226
     1227                return $image;
     1228        }
     1229
     1230        $width  = preg_match( '/ width="([0-9]+)"/',  $image, $match_width  ) ? (int) $match_width[1]  : 0;
     1231        $height = preg_match( '/ height="([0-9]+)"/', $image, $match_height ) ? (int) $match_height[1] : 0;
     1232
     1233        if ( ! $width || ! $height ) {
    11711234                /*
    1172                  * First, see if the file is the full size image. If not, loop through
    1173                  * the intermediate sizes until we find a file that matches.
     1235                 * If attempts to parse the size value failed, attempt to use the image
     1236                 * metadata to match the image file name from 'src' against the available sizes for an attachment.
    11741237                 */
    11751238                $image_filename = wp_basename( $src );
    11761239
    1177                 if ( $image_filename === basename( $meta['file'] ) ) {
    1178                         $size = 'full';
     1240                if ( $image_filename === wp_basename( $image_meta['file'] ) ) {
     1241                        $width = (int) $image_meta['width'];
     1242                        $height = (int) $image_meta['height'];
    11791243                } else {
    1180                         foreach( $meta['sizes'] as $image_size => $image_size_data ) {
     1244                        foreach( $image_meta['sizes'] as $image_size_data ) {
    11811245                                if ( $image_filename === $image_size_data['file'] ) {
    1182                                         $size = $image_size;
     1246                                        $width = (int) $image_size_data['width'];
     1247                                        $height = (int) $image_size_data['height'];
    11831248                                        break;
    11841249                                }
    11851250                        }
    11861251                }
    1187 
    1188         }
    1189 
    1190         // If ID and size exist, try for 'srcset' and 'sizes' and update the markup.
    1191         if ( $id && $size ) {
    1192                 $srcset = wp_get_attachment_image_srcset( $id, $size );
    1193                 $sizes  = wp_get_attachment_image_sizes( $id, $size, $width );
    1194 
    1195                 if ( $srcset && $sizes ) {
    1196                         // Format the srcset and sizes string and escape attributes.
    1197                         $srcset_and_sizes = sprintf( ' srcset="%s" sizes="%s"', esc_attr( $srcset ), esc_attr( $sizes) );
    1198 
    1199                         // Add srcset and sizes attributes to the image markup.
    1200                         $image = preg_replace( '/<img ([^>]+)[\s?][\/?]>/', '<img $1' . $srcset_and_sizes . ' />', $image );
    1201                 }
     1252        }
     1253
     1254        if ( ! $width || ! $height ) {
     1255                return $image;
     1256        }
     1257
     1258        $size_array = array( $width, $height );
     1259        $sources = wp_calculate_image_srcset( $src, $size_array, $image_meta, $attachment_id );
     1260
     1261        $srcset = $sizes = '';
     1262        // Only calculate srcset and sizes values if there is more than one source.
     1263        if ( count( $sources ) > 1 ) {
     1264                $srcset = wp_image_srcset_attr( $sources, $size_array, $image_meta, $attachment_id );
     1265                $sizes = wp_get_attachment_image_sizes( $size_array, $image_meta, $attachment_id );
     1266        }
     1267
     1268        if ( $srcset && $sizes ) {
     1269                // Format the srcset and sizes string and escape attributes.
     1270                $srcset_and_sizes = sprintf( ' srcset="%s" sizes="%s"', esc_attr( $srcset ), esc_attr( $sizes ) );
     1271
     1272                // Add srcset and sizes attributes to the image markup.
     1273                $image = preg_replace( '/<img ([^>]+?)[\/ ]*>/', '<img $1' . $srcset_and_sizes . ' />', $image );
    12021274        }
    12031275
Note: See TracChangeset for help on using the changeset viewer.