Ticket #34430: 34430.5.diff
File 34430.5.diff, 34.8 KB (added by , 8 years ago) |
---|
-
src/wp-includes/media.php
diff --git src/wp-includes/media.php src/wp-includes/media.php index 30df322..ee4a860 100644
function wp_get_attachment_image($attachment_id, $size = 'thumbnail', $icon = fa 813 813 814 814 // Generate srcset and sizes if not already present. 815 815 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 ); 816 $image_meta = wp_get_attachment_metadata( $attachment_id ); 817 $size_array = array( absint( $width ), absint( $height ) ); 818 $srcset = _wp_calculate_image_srcset( $src, $size_array, $image_meta ); 818 819 819 if ( $srcset && $sizes) {820 if ( $srcset ) { 820 821 $attr['srcset'] = $srcset; 821 822 822 if ( empty( $attr['sizes'] ) ) {823 if ( empty( $attr['sizes'] ) && ( $sizes = wp_get_attachment_image_sizes( $size_array, $image_meta, $attachment_id ) ) ) { 823 824 $attr['sizes'] = $sizes; 824 825 } 825 826 } … … function wp_get_attachment_image_url( $attachment_id, $size = 'thumbnail', $icon 864 865 } 865 866 866 867 /** 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 */ 870 function _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 */ 884 function _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. 870 902 * 871 903 * @since 4.4.0 872 904 * 873 * @param int $attachment_id Image attachment ID. 905 906 * @param int $attachment_id Optional. Image attachment ID. 874 907 * @param array|string $size Image size. Accepts any valid image size, or an array of width and height 875 908 * 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 */ 912 function 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 $srcset = ''; 936 foreach ( $sources as $source ) { 937 $srcset .= $source['url'] . ' ' . $source['value'] . $source['descriptor'] . ', '; 938 } 939 940 /** 941 * Filter the output of wp_get_attachment_image_srcset(). 942 * 943 * @since 4.4.0 944 * 945 * @param string $srcset A source set formatted for a `srcset` attribute. 946 * @param int $attachment_id Image attachment ID. 947 * @param array|string $size Image size. Accepts any valid image size, or an array of width and height 948 * values in pixels (in that order). Default 'medium'. 949 * @param array $image_meta The image meta data. 950 */ 951 return apply_filters( 'wp_get_attachment_image_srcset', rtrim( $srcset, ', ' ), $attachment_id, $size, $image_meta ); 952 } 953 954 /** 955 * A helper function to caclulate the image sources to include in a srcset attribute. 956 * 957 * @since 4.4.0 958 * 959 * @param string $image_url The URL of the image being matched. 960 * @param array $size_array Array of width and height values in pixels (in that order). 961 * @param array $image_meta The image meta data. 962 * @param int $attachment_id Optional. The image id to pass to the filter. 876 963 * @return array|bool $sources { 877 964 * Array image candidate values containing a URL, descriptor type, and 878 965 * descriptor value. False if none exist. … … function wp_get_attachment_image_url( $attachment_id, $size = 'thumbnail', $icon 886 973 * } 887 974 * 888 975 */ 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 ) ) { 976 function _wp_calculate_image_srcset( $image_url, $size_array, $image_meta, $attachment_id = 0 ) { 977 if ( empty( $image_meta['sizes'] ) ) { 896 978 return false; 897 979 } 898 980 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']; 981 $image_sizes = $image_meta['sizes']; 902 982 903 // Bail early if the width isn't greater than zero. 904 if ( ! $img_width > 0 ) { 905 return false; 906 } 983 // Get the height and width for the image. 984 $image_width = (int) $size_array[0]; 985 $image_height = (int) $size_array[1]; 907 986 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; 987 // Bail early if error/no width. 988 if ( $image_width < 1 ) { 989 return false; 915 990 } 916 991 917 $img_sizes = $img_meta['sizes'];918 919 992 // Add full size to the img_sizes array. 920 $im g_sizes['full'] = array(921 'width' => $im g_meta['width'],922 'height' => $im g_meta['height'],923 'file' => wp_basename( $im g_meta['file'] )993 $image_sizes['full'] = array( 994 'width' => $image_meta['width'], 995 'height' => $image_meta['height'], 996 'file' => wp_basename( $image_meta['file'] ), 924 997 ); 925 998 999 $image_baseurl = _wp_upload_dir_baseurl(); 1000 $dirname = dirname( $image_meta['file'] ); 1001 1002 if ( $dirname !== '.' ) { 1003 $image_baseurl = path_join( $image_baseurl, $dirname ); 1004 } 1005 926 1006 // Calculate the image aspect ratio. 927 $im g_ratio = $img_height / $img_width;1007 $image_ratio = $image_height / $image_width; 928 1008 929 1009 /* 930 1010 * Images that have been edited in WordPress after being uploaded will 931 1011 * contain a unique hash. Look for that hash and use it later to filter 932 1012 * out images that are leftovers from previous versions. 933 1013 */ 934 $im g_edited = preg_match( '/-e[0-9]{13}/', $img_url, $img_edit_hash );1014 $image_edited = preg_match( '/-e[0-9]{13}/', $image_url, $image_edit_hash ); 935 1015 936 1016 /** 937 * Filter the maximum width included in a srcsetattribute.1017 * Filter the maximum width included in a 'srcset' attribute. 938 1018 * 939 1019 * @since 4.4.0 940 1020 * 941 * @param array|string $size Size of image, either array or string. 1021 * @param int $max_width The maximum width to include in the 'srcset'. Default '1600'. 1022 * @param array|string $size_array Array of width and height values in pixels (in that order). 942 1023 */ 943 $max_srcset_width = apply_filters( 'max_srcset_image_width', 1600, $size );1024 $max_srcset_width = apply_filters( 'max_srcset_image_width', 1600, $size_array ); 944 1025 945 /* 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(); 1026 // Array to hold URL candidates. 1027 $sources = array(); 950 1028 951 1029 /* 952 * Loop through available images and only use images that are resized953 * versions of the same rendition.1030 * Loop through available images. Only use images that are resized 1031 * versions of the same edit. 954 1032 */ 955 foreach ( $im g_sizes as $img) {1033 foreach ( $image_sizes as $image ) { 956 1034 957 // Filter out images that are leftovers from previous renditions.958 if ( $im g_edited && ! strpos( $img['file'], $img_edit_hash[0] ) ) {1035 // Filter out images that are from previous edits. 1036 if ( $image_edited && ! strpos( $image['file'], $image_edit_hash[0] ) ) { 959 1037 continue; 960 1038 } 961 1039 962 1040 // Filter out images that are wider than $max_srcset_width. 963 if ( $max_srcset_width && $im g['width'] > $max_srcset_width ) {1041 if ( $max_srcset_width && $image['width'] > $max_srcset_width ) { 964 1042 continue; 965 1043 } 966 1044 967 $candidate_url = path_join( dirname( $img_url ), $img['file'] );1045 $candidate_url = $image['file']; 968 1046 969 1047 // Calculate the new image ratio. 970 if ( $im g['width'] ) {971 $im g_ratio_compare = $img['height'] / $img['width'];1048 if ( $image['width'] ) { 1049 $image_ratio_compare = $image['height'] / $image['width']; 972 1050 } else { 973 $im g_ratio_compare = 0;1051 $image_ratio_compare = 0; 974 1052 } 975 1053 976 1054 // 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, 1055 if ( abs( $image_ratio - $image_ratio_compare ) < 0.01 && ! array_key_exists( $candidate_url, $sources ) ) { 1056 // Add the URL, descriptor, and value to the sources array to be returned. 1057 $sources[ $image['width'] ] = array( 1058 'url' => path_join( $image_baseurl, $candidate_url ), 984 1059 'descriptor' => 'w', 985 'value' => $im g['width'],1060 'value' => $image['width'], 986 1061 ); 987 1062 } 988 1063 } … … function wp_get_attachment_image_srcset_array( $attachment_id, $size = 'medium' 992 1067 * 993 1068 * @since 4.4.0 994 1069 * 995 * @param array $sources An array of image urls and widths.1070 * @param array $sources An array of image URLs and widths. 996 1071 * @param int $attachment_id Attachment ID for image. 997 1072 * @param array|string $size Image size. Accepts any valid image size, or an array of width and height 998 1073 * 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. 1005 * 1006 * @since 4.4.0 1007 * 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 ) { 1018 return false; 1019 } 1020 1021 $srcset = ''; 1022 foreach ( $srcset_array as $source ) { 1023 $srcset .= $source['url'] . ' ' . $source['value'] . $source['descriptor'] . ', '; 1024 } 1074 * @param array $image_meta The image meta data. 1025 1075 1026 /**1027 * Filter the output of wp_get_attachment_image_srcset().1028 *1029 * @since 4.4.01030 *1031 * @param string $srcset A source set formated for a `srcset` attribute.1032 * @param int $attachment_id Attachment ID for image.1033 * @param array|string $size Image size. Accepts any valid image size, or an array of width and height1034 * values in pixels (in that order). Default 'medium'.1035 1076 */ 1036 return apply_filters( 'wp_get_attachment_image_srcset ', rtrim( $srcset, ', ' ), $attachment_id, $size);1077 return apply_filters( 'wp_get_attachment_image_srcset_array', array_values( $sources ), $attachment_id, $size_array, $image_meta ); 1037 1078 } 1038 1079 1039 1080 /** 1040 * Retrieves a source size attribute for an image from an array of values.1081 * Create `sizes` attribute value for an image. 1041 1082 * 1042 1083 * @since 4.4.0 1043 1084 * 1044 * @param int $attachment_id Image attachment ID.1045 1085 * @param array|string $size Image size. Accepts any valid image size, or an array of width and height 1046 1086 * values in pixels (in that order). Default 'medium'. 1047 * @param int $width Optional. Display width of the image. 1087 * @param array $image_meta Optional. The image meta data. 1088 * @param int $attachment_id Optional. Image attachment ID. 1089 * 1048 1090 * @return string|bool A valid source size value for use in a 'sizes' attribute or false. 1049 1091 */ 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.1092 function wp_get_attachment_image_sizes( $size, $image_meta = null, $attachment_id = 0 ) { 1093 $width = 0; 1094 1095 if ( is_numeric( $size ) ) { 1096 $width = absint( $size ); 1055 1097 } 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; 1098 $width = absint( $size[0] ); 1099 } 1100 1101 if ( ! $width && ( $image_meta || $attachment_id ) ) { 1102 $image_meta = ( $image_meta ) ? $image_meta : wp_get_attachment_metadata( $attachment_id ); 1103 $width = _wp_get_image_size_from_meta( $size, $image_meta )[0]; 1061 1104 } 1062 1105 1063 // Bail early if $img_width isn't set. 1064 if ( ! $img_width ) { 1106 if ( ! $width ) { 1065 1107 return false; 1066 1108 } 1067 1109 1068 1110 // Setup the default sizes attribute. 1069 $sizes = sprintf( '(max-width: %1$dpx) 100vw, %1$dpx', $img_width );1111 $sizes = sprintf( '(max-width: %1$dpx) 100vw, %1$dpx', (int) $width ); 1070 1112 1071 1113 /** 1072 1114 * Filter the output of wp_get_attachment_image_sizes(). … … function wp_get_attachment_image_sizes( $attachment_id, $size = 'medium', $width 1074 1116 * @since 4.4.0 1075 1117 * 1076 1118 * @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 1119 * @param array|string $size Image size. Accepts any valid image size, or an array of width and height 1079 1120 * values in pixels (in that order). Default 'medium'. 1080 * @param int $width Display width of the image. 1121 * @param array $image_meta The image meta data. 1122 * @param int $attachment_id Post ID of the original image. 1081 1123 */ 1082 return apply_filters( 'wp_get_attachment_image_sizes', $sizes, $ attachment_id, $size, $width);1124 return apply_filters( 'wp_get_attachment_image_sizes', $sizes, $size, $image_meta, $attachment_id ); 1083 1125 } 1084 1126 1085 1127 /** … … function wp_get_attachment_image_sizes( $attachment_id, $size = 'medium', $width 1087 1129 * 1088 1130 * @since 4.4.0 1089 1131 * 1090 * @see wp_im g_add_srcset_and_sizes()1132 * @see wp_image_add_srcset_and_sizes() 1091 1133 * 1092 1134 * @param string $content The raw post content to be filtered. 1093 1135 * @return string Converted content with 'srcset' and 'sizes' attributes added to images. … … function wp_get_attachment_image_sizes( $attachment_id, $size = 'medium', $width 1095 1137 function wp_make_content_images_responsive( $content ) { 1096 1138 $images = get_media_embedded_in_content( $content, 'img' ); 1097 1139 1098 $ attachment_ids = array();1140 $selected_images = array(); 1099 1141 1100 1142 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 } 1143 if ( false === strpos( $image, ' srcset="' ) && preg_match( '/wp-image-([0-9]+)/i', $image, $class_id ) && 1144 ( $attachment_id = absint( $class_id[1] ) ) ) { 1145 1146 $selected_images[$image] = $attachment_id; 1106 1147 } 1107 1148 } 1108 1149 1109 if ( 0 < count( $attachment_ids )) {1150 if ( count( $selected_images ) > 1 ) { 1110 1151 /* 1111 * Warm object cache s for use with wp_get_attachment_metadata.1152 * Warm object cache for use with get_post_meta(). 1112 1153 * 1113 1154 * To avoid making a database call for each image, a single query 1114 1155 * warms the object cache with the meta information for all images. 1115 1156 */ 1116 _prime_post_caches( $attachment_ids, false, true);1157 update_meta_cache( 'post', array_unique( array_values( ( $selected_images ) ) ) ); 1117 1158 } 1118 1159 1119 foreach( $images as $image ) { 1120 $content = str_replace( $image, wp_img_add_srcset_and_sizes( $image ), $content ); 1160 foreach ( $selected_images as $image => $attachment_id ) { 1161 $image_meta = get_post_meta( $attachment_id, '_wp_attachment_metadata', true ); 1162 $content = str_replace( $image, wp_image_add_srcset_and_sizes( $image, $image_meta, $attachment_id ), $content ); 1121 1163 } 1122 1164 1123 1165 return $content; … … function wp_make_content_images_responsive( $content ) { 1131 1173 * @see wp_get_attachment_image_srcset() 1132 1174 * @see wp_get_attachment_image_sizes() 1133 1175 * 1134 * @param string $image An HTML 'img' element to be filtered. 1176 * @param string $image An HTML 'img' element to be filtered. 1177 * @param array $image_meta The image meta data. 1178 * @param int $attachment_id Image attachment ID. 1135 1179 * @return string Converted 'img' element with `srcset` and `sizes` attributes added. 1136 1180 */ 1137 function wp_im g_add_srcset_and_sizes( $image) {1138 // Return early if a 'srcset' attribute already exists.1139 if ( false !== strpos( $image, ' srcset="') ) {1181 function wp_image_add_srcset_and_sizes( $image, $image_meta, $attachment_id ) { 1182 // Ensure the image meta exists 1183 if ( empty( $image_meta['sizes'] ) ) { 1140 1184 return $image; 1141 1185 } 1142 1186 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; 1187 $src = preg_match( '/src="([^"]+)"/', $image, $match_src ) ? $match_src[1] : ''; 1188 list( $src ) = explode( '?', $src ); 1147 1189 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 } 1190 // Return early if we coudn't get the image source. 1191 if ( ! $src ) { 1192 return $image; 1154 1193 } 1155 1194 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 ); 1195 // Bail early when an image has been inserted and later edited. 1196 // We don't have the previous image meta to generate srcset. 1197 if ( preg_match( '/-e[0-9]{13}/', $image_meta['file'], $img_edit_hash ) && 1198 strpos( wp_basename( $src ), $img_edit_hash[0] ) === false ) { 1162 1199 1163 // Parse the image src value from the img element.1164 $src = preg_match( '/src="([^"]+)"/', $image, $match_src ) ? $match_src[1] : false;1200 return $image; 1201 } 1165 1202 1166 // Return early if the metadata does not exist or the src value is empty. 1167 if ( ! $meta || ! $src ) { 1168 return $image; 1169 } 1203 $width = preg_match( '/ width="([0-9]+)"/', $image, $match_width ) ? (int) $match_width[1] : 0; 1204 $height = preg_match( '/ height="([0-9]+)"/', $image, $match_height ) ? (int) $match_height[1] : 0; 1170 1205 1206 if ( ! $width || ! $height ) { 1171 1207 /* 1172 * First, see if the file is the full size image. If not, loop through1173 * the intermediate sizes until we find a file that matches.1208 * If attempts to parse the size value failed, attempt to use the image 1209 * metadata to match the 'src' against the available sizes for an attachment. 1174 1210 */ 1175 1211 $image_filename = wp_basename( $src ); 1176 1212 1177 if ( $image_filename === basename( $meta['file'] ) ) { 1178 $size = 'full'; 1213 if ( $image_filename === basename( $image_meta['file'] ) ) { 1214 $width = (int) $image_meta['width']; 1215 $height = (int) $image_meta['height']; 1179 1216 } else { 1180 foreach( $ meta['sizes'] as $image_size =>$image_size_data ) {1217 foreach( $image_meta['sizes'] as $image_size_data ) { 1181 1218 if ( $image_filename === $image_size_data['file'] ) { 1182 $size = $image_size; 1219 $width = (int) $image_size_data['width']; 1220 $height = (int) $image_size_data['height']; 1183 1221 break; 1184 1222 } 1185 1223 } 1186 1224 } 1187 1188 1225 } 1189 1226 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 ); 1227 if ( ! $width || ! $height ) { 1228 return $image; 1229 } 1194 1230 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) ); 1231 $size_array = array( $width, $height ); 1232 $sources = _wp_calculate_image_srcset( $src, $size_array, $image_meta, $attachment_id ); 1198 1233 1199 // Add srcset and sizes attributes to the image markup. 1200 $image = preg_replace( '/<img ([^>]+)[\s?][\/?]>/', '<img $1' . $srcset_and_sizes . ' />', $image ); 1234 // Only calculate srcset and sizes values if there is more than one source. 1235 $srcset = $sizes = false; 1236 if ( count( $sources ) > 1 ) { 1237 $srcset = ''; 1238 foreach ( $sources as $source ) { 1239 $srcset .= $source['url'] . ' ' . $source['value'] . $source['descriptor'] . ', '; 1201 1240 } 1241 1242 /** 1243 * Filter the output of wp_get_attachment_image_srcset(). 1244 * 1245 * @since 4.4.0 1246 * 1247 * @see wp_get_attachment_image_srcset() 1248 * 1249 * @param string $srcset A source set formatted for a `srcset` attribute. 1250 * @param int $attachment_id Image attachment ID. 1251 * @param array|string $size Image size. Accepts any valid image size, or an array of width and height 1252 * values in pixels (in that order). Default 'medium'. 1253 * @param array $image_meta The image meta data. 1254 */ 1255 $srcset = apply_filters( 'wp_get_attachment_image_srcset', rtrim( $srcset, ', ' ), $attachment_id, $size_array, $image_meta ); 1256 1257 $sizes = wp_get_attachment_image_sizes( $attachment_id, $size_array, $image_meta ); 1258 } 1259 1260 1261 if ( $srcset && $sizes ) { 1262 // Format the srcset and sizes string and escape attributes. 1263 $srcset_and_sizes = sprintf( ' srcset="%s" sizes="%s"', esc_attr( $srcset ), esc_attr( $sizes ) ); 1264 1265 // Add srcset and sizes attributes to the image markup. 1266 $image = preg_replace( '/<img ([^>]+?)[\/ ]*>/', '<img $1' . $srcset_and_sizes . ' />', $image ); 1202 1267 } 1203 1268 1204 1269 return $image; -
tests/phpunit/tests/media.php
diff --git tests/phpunit/tests/media.php tests/phpunit/tests/media.php index b682b09..29e9da4 100644
EOF; 716 716 } 717 717 718 718 /** 719 * Helper function to get image size array from size "name" 720 */ 721 function _get_image_size_array_from_name( $size_name ) { 722 switch ( $size_name ) { 723 case 'thumbnail': 724 return array( 150, 150 ); 725 case 'medium': 726 return array( 300, 225 ); 727 case 'large': 728 return array( 1024, 768 ); 729 case 'full': 730 return array( 1600, 1200 ); // actual size of ../data/images/test-image-large.png 731 default: 732 return array( 800, 600 ); // soft-resized image 733 } 734 } 735 736 /** 719 737 * @ticket 33641 720 738 */ 721 function test_wp_ get_attachment_image_srcset_array() {739 function test_wp_calculate_image_srcset() { 722 740 $year_month = date('Y/m'); 723 $image = wp_get_attachment_metadata( self::$large_id );741 $image_meta = wp_get_attachment_metadata( self::$large_id ); 724 742 725 743 $expected = array( 726 744 array( 727 'url' => 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $year_month . '/' . $image ['sizes']['medium']['file'],745 'url' => 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $year_month . '/' . $image_meta['sizes']['medium']['file'], 728 746 'descriptor' => 'w', 729 'value' => $image ['sizes']['medium']['width'],747 'value' => $image_meta['sizes']['medium']['width'], 730 748 ), 731 749 array( 732 'url' => 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $year_month . '/' . $image ['sizes']['large']['file'],750 'url' => 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $year_month . '/' . $image_meta['sizes']['large']['file'], 733 751 'descriptor' => 'w', 734 'value' => $image ['sizes']['large']['width'],752 'value' => $image_meta['sizes']['large']['width'], 735 753 ), 736 754 array( 737 'url' => 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $image ['file'],755 'url' => 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $image_meta['file'], 738 756 'descriptor' => 'w', 739 'value' => $image ['width'],757 'value' => $image_meta['width'], 740 758 ), 741 759 ); 742 760 … … EOF; 744 762 $sizes = array( 'medium', 'large', 'full', 'yoav' ); 745 763 746 764 foreach ( $sizes as $size ) { 747 $this->assertSame( $expected, wp_get_attachment_image_srcset_array( self::$large_id, $size ) ); 765 $image_url = wp_get_attachment_image_url( self::$large_id, $size ); 766 $size_array = $this->_get_image_size_array_from_name( $size ); 767 $this->assertSame( $expected, _wp_calculate_image_srcset( self::$large_id, $size_array, $image_meta ) ); 748 768 } 749 769 } 750 770 751 771 /** 752 772 * @ticket 33641 753 773 */ 754 function test_wp_ get_attachment_image_srcset_array_no_date_uploads() {774 function test_wp_calculate_image_srcset_no_date_uploads() { 755 775 // Save the current setting for uploads folders 756 776 $uploads_use_yearmonth_folders = get_option( 'uploads_use_yearmonth_folders' ); 757 777 … … EOF; 762 782 $filename = DIR_TESTDATA . '/images/test-image-large.png'; 763 783 $id = self::factory()->attachment->create_upload_object( $filename ); 764 784 765 $image = wp_get_attachment_metadata( $id );785 $image_meta = wp_get_attachment_metadata( $id ); 766 786 767 787 $expected = array( 768 788 array( 769 'url' => 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $image ['sizes']['medium']['file'],789 'url' => 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $image_meta['sizes']['medium']['file'], 770 790 'descriptor' => 'w', 771 'value' => $image ['sizes']['medium']['width'],791 'value' => $image_meta['sizes']['medium']['width'], 772 792 ), 773 793 array( 774 'url' => 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $image ['sizes']['large']['file'],794 'url' => 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $image_meta['sizes']['large']['file'], 775 795 'descriptor' => 'w', 776 'value' => $image ['sizes']['large']['width'],796 'value' => $image_meta['sizes']['large']['width'], 777 797 ), 778 798 array( 779 'url' => 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $image ['file'],799 'url' => 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $image_meta['file'], 780 800 'descriptor' => 'w', 781 'value' => $image ['width'],801 'value' => $image_meta['width'], 782 802 ), 783 803 ); 784 804 … … EOF; 786 806 $sizes = array( 'medium', 'large', 'full', 'yoav' ); 787 807 788 808 foreach ( $sizes as $size ) { 789 $this->assertSame( $expected, wp_get_attachment_image_srcset_array( $id, $size ) ); 809 $size_array = $this->_get_image_size_array_from_name( $size ); 810 $image_url = wp_get_attachment_image_url( self::$large_id, $size ); 811 $this->assertSame( $expected, _wp_calculate_image_srcset( $image_url, $size_array, $image_meta ) ); 790 812 } 791 813 792 814 // Leave the uploads option the way you found it. … … EOF; 796 818 /** 797 819 * @ticket 33641 798 820 */ 799 function test_wp_ get_attachment_image_srcset_array_with_edits() {821 function test_wp_calculate_image_srcset_with_edits() { 800 822 // For this test we're going to mock metadata changes from an edit. 801 823 // Start by getting the attachment metadata. 802 $meta = wp_get_attachment_metadata( self::$large_id ); 824 $image_meta = wp_get_attachment_metadata( self::$large_id ); 825 $image_url = wp_get_attachment_image_url( self::$large_id ); 826 $size_array = $this->_get_image_size_array_from_name( 'medium' ); 803 827 804 828 // Copy hash generation method used in wp_save_image(). 805 829 $hash = 'e' . time() . rand(100, 999); 806 830 807 831 // Replace file paths for full and medium sizes with hashed versions. 808 $filename_base = basename( $meta['file'], '.png' ); 809 $meta['file'] = str_replace( $filename_base, $filename_base . '-' . $hash, $meta['file'] ); 810 $meta['sizes']['medium']['file'] = str_replace( $filename_base, $filename_base . '-' . $hash, $meta['sizes']['medium']['file'] ); 811 812 // Save edited metadata. 813 wp_update_attachment_metadata( self::$large_id, $meta ); 832 $filename_base = basename( $image_meta['file'], '.png' ); 833 $image_meta['file'] = str_replace( $filename_base, $filename_base . '-' . $hash, $image_meta['file'] ); 834 $image_meta['sizes']['medium']['file'] = str_replace( $filename_base, $filename_base . '-' . $hash, $image_meta['sizes']['medium']['file'] ); 835 $image_meta['sizes']['large']['file'] = str_replace( $filename_base, $filename_base . '-' . $hash, $image_meta['sizes']['large']['file'] ); 814 836 815 837 // Calculate a srcset array. 816 $sizes = wp_get_attachment_image_srcset_array( self::$large_id, 'medium');838 $sizes = _wp_calculate_image_srcset( $image_url, $size_array, $image_meta ); 817 839 818 840 // Test to confirm all sources in the array include the same edit hash. 819 841 foreach ( $sizes as $size ) { … … EOF; 824 846 /** 825 847 * @ticket 33641 826 848 */ 827 function test_wp_ get_attachment_image_srcset_array_false() {828 $sizes = wp_get_attachment_image_srcset_array( 99999, 'foo');849 function test_wp_calculate_image_srcset_false() { 850 $sizes = _wp_calculate_image_srcset( 'file.png', array( 400, 300 ), array() ); 829 851 830 852 // For canola.jpg we should return 831 853 $this->assertFalse( $sizes ); … … EOF; 834 856 /** 835 857 * @ticket 33641 836 858 */ 837 function test_wp_get_attachment_image_srcset_array_no_width() { 838 // Filter image_downsize() output. 839 add_filter( 'wp_generate_attachment_metadata', array( $this, '_test_wp_get_attachment_image_srcset_array_no_width_filter' ) ); 840 841 $old_meta = get_post_meta( self::$large_id, '_wp_attachment_metadata', true ); 859 function test_wp_calculate_image_srcset_no_width() { 842 860 $file = get_attached_file( self::$large_id ); 861 $image_url = wp_get_attachment_image_url( self::$large_id, 'medium' ); 862 $image_meta = wp_generate_attachment_metadata( self::$large_id, $file ); 843 863 844 $data = wp_generate_attachment_metadata( self::$large_id, $file ); 845 wp_update_attachment_metadata( self::$large_id, $data ); 846 847 $srcset = wp_get_attachment_image_srcset_array( self::$large_id, 'medium' ); 864 $size_array = array(0, 0); 848 865 849 update_post_meta( self::$large_id, '_wp_attachment_metadata', $old_meta );866 $srcset = _wp_calculate_image_srcset( $image_url, $size_array, $image_meta ); 850 867 851 868 // The srcset should be false. 852 869 $this->assertFalse( $srcset ); 853 870 } 854 871 855 872 /** 856 * Helper function to filter image_downsize and return zero values for width and height.857 */858 public function _test_wp_get_attachment_image_srcset_array_no_width_filter( $meta ) {859 remove_filter( 'wp_generate_attachment_metadata', array( $this, __FUNCTION__ ) );860 861 $meta['sizes']['medium']['width'] = 0;862 $meta['sizes']['medium']['height'] = 0;863 return $meta;864 }865 866 /**867 873 * @ticket 33641 868 874 */ 869 875 function test_wp_get_attachment_image_srcset() { 870 $sizes = wp_get_attachment_image_srcset( self::$large_id, 'full-size' ); 876 $image_meta = wp_get_attachment_metadata( self::$large_id ); 877 $size_array = array( 1600, 1200 ); // full size 878 879 $sizes = wp_get_attachment_image_srcset( self::$large_id, $size_array, $image_meta ); 871 880 872 $image = wp_get_attachment_metadata( self::$large_id );873 881 $year_month = date('Y/m'); 874 882 875 883 $expected = 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $year_month = date('Y/m') . '/' 876 . $image ['sizes']['medium']['file'] . ' ' . $image['sizes']['medium']['width'] . 'w, ';884 . $image_meta['sizes']['medium']['file'] . ' ' . $image_meta['sizes']['medium']['width'] . 'w, '; 877 885 $expected .= 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $year_month = date('Y/m') . '/' 878 . $image ['sizes']['large']['file'] . ' ' . $image['sizes']['large']['width'] . 'w, ';879 $expected .= 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $image ['file'] . ' ' . $image['width'] .'w';886 . $image_meta['sizes']['large']['file'] . ' ' . $image_meta['sizes']['large']['width'] . 'w, '; 887 $expected .= 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/' . $image_meta['file'] . ' ' . $image_meta['width'] .'w'; 880 888 881 889 $this->assertSame( $expected, $sizes ); 882 890 } … … EOF; 885 893 * @ticket 33641 886 894 */ 887 895 function test_wp_get_attachment_image_srcset_single_srcset() { 896 $image_meta = wp_get_attachment_metadata( self::$large_id ); 897 $size_array = array( 150, 150 ); 888 898 /* 889 899 * In our tests, thumbnails will only return a single srcset candidate, 890 900 * so we shouldn't return a srcset value in order to avoid unneeded markup. 891 901 */ 892 $sizes = wp_get_attachment_image_srcset( self::$large_id, 'thumbnail');902 $sizes = wp_get_attachment_image_srcset( self::$large_id, $size_array, $image_meta ); 893 903 894 904 $this->assertFalse( $sizes ); 895 905 } … … EOF; 899 909 */ 900 910 function test_wp_get_attachment_image_sizes() { 901 911 // Test sizes against the default WP sizes. 902 $intermediates = array('thumbnail', 'medium', 'large'); 912 $intermediates = array( 'thumbnail', 'medium', 'large' ); 913 $image_meta = wp_get_attachment_metadata( self::$large_id ); 903 914 904 foreach( $intermediates as $int ) { 905 $width = get_option( $int . '_size_w' ); 915 foreach( $intermediates as $int_size ) { 916 $size_array = $this->_get_image_size_array_from_name( $int_size ); 917 list( $width, $height ) = $size_array; 906 918 907 919 $expected = '(max-width: ' . $width . 'px) 100vw, ' . $width . 'px'; 908 $sizes = wp_get_attachment_image_sizes( self::$large_id, $int);920 $sizes = wp_get_attachment_image_sizes( $size_array, $image_meta ); 909 921 910 $this->assertSame( $expected, $sizes);922 $this->assertSame( $expected, $sizes ); 911 923 } 912 924 } 913 925 914 926 /** 915 927 * @ticket 33641 916 928 */ 917 function test_wp_get_attachment_image_sizes_with_width() {918 $width = 350;919 920 $expected = '(max-width: 350px) 100vw, 350px';921 $sizes = wp_get_attachment_image_sizes( self::$large_id, 'medium', $width );922 923 $this->assertSame( $expected, $sizes );924 }925 926 /**927 * @ticket 33641928 */929 929 function test_wp_make_content_images_responsive() { 930 $srcset = sprintf( 'srcset="%s"', wp_get_attachment_image_srcset( self::$large_id, 'medium' ) ); 931 $sizes = sprintf( 'sizes="%s"', wp_get_attachment_image_sizes( self::$large_id, 'medium' ) ); 930 $image_meta = wp_get_attachment_metadata( self::$large_id ); 931 $size_array = $this->_get_image_size_array_from_name( 'medium' ); 932 933 $srcset = sprintf( 'srcset="%s"', wp_get_attachment_image_srcset( self::$large_id, $size_array, $image_meta ) ); 934 $sizes = sprintf( 'sizes="%s"', wp_get_attachment_image_sizes( self::$large_id, $size_array, $image_meta ) ); 932 935 933 936 // Function used to build HTML for the editor. 934 937 $img = get_image_tag( self::$large_id, '', '', '', 'medium' );