Ticket #36982: 36982.2.diff
File 36982.2.diff, 14.0 KB (added by , 4 years ago) |
---|
-
src/wp-includes/media.php
diff --git src/wp-includes/media.php src/wp-includes/media.php index d29426213e..470a5e320d 100644
function wp_get_attachment_image( $attachment_id, $size = 'thumbnail', $icon = f 1063 1063 1064 1064 if ( is_array( $image_meta ) ) { 1065 1065 $size_array = array( absint( $width ), absint( $height ) ); 1066 $srcset = wp_calculate_image_srcset( $size_array, $src, $image_meta, $attachment_id );1067 $sizes = wp_calculate_image_sizes( $size_array, $src, $image_meta, $attachment_id );1066 $srcset = wp_calculate_image_srcset( $size_array, $src, $image_meta, $attachment_id, $attr ); 1067 $sizes = wp_calculate_image_sizes( $size_array, $src, $image_meta, $attachment_id, $attr ); 1068 1068 1069 1069 if ( $srcset && ( $sizes || ! empty( $attr['sizes'] ) ) ) { 1070 1070 $attr['srcset'] = $srcset; … … function _wp_get_image_size_from_meta( $size_name, $image_meta ) { 1193 1193 * Retrieves the value for an image attachment's 'srcset' attribute. 1194 1194 * 1195 1195 * @since 4.4.0 1196 * @since 5.7.0 Added the '$image_attr' parameter. 1196 1197 * 1197 1198 * @see wp_calculate_image_srcset() 1198 1199 * … … function _wp_get_image_size_from_meta( $size_name, $image_meta ) { 1201 1202 * width and height values in pixels (in that order). Default 'medium'. 1202 1203 * @param array $image_meta Optional. The image meta data as returned by 'wp_get_attachment_metadata()'. 1203 1204 * Default null. 1205 * @param array $image_attr Optional. An array of image attributes to be passed to 'wp_calculate_image_srcset()'. 1204 1206 * @return string|false A 'srcset' value string or false. 1205 1207 */ 1206 function wp_get_attachment_image_srcset( $attachment_id, $size = 'medium', $image_meta = null ) {1208 function wp_get_attachment_image_srcset( $attachment_id, $size = 'medium', $image_meta = null, $image_attr = array() ) { 1207 1209 $image = wp_get_attachment_image_src( $attachment_id, $size ); 1208 1210 1209 1211 if ( ! $image ) { … … function wp_get_attachment_image_srcset( $attachment_id, $size = 'medium', $imag 1220 1222 absint( $image[2] ), 1221 1223 ); 1222 1224 1223 return wp_calculate_image_srcset( $size_array, $image_src, $image_meta, $attachment_id );1225 return wp_calculate_image_srcset( $size_array, $image_src, $image_meta, $attachment_id, $image_attr ); 1224 1226 } 1225 1227 1226 1228 /** 1227 1229 * A helper function to calculate the image sources to include in a 'srcset' attribute. 1228 1230 * 1229 1231 * @since 4.4.0 1232 * @since 5.7.0 Added the '$image_attr' parameter. 1230 1233 * 1231 1234 * @param int[] $size_array { 1232 1235 * An array of width and height values. … … function wp_get_attachment_image_srcset( $attachment_id, $size = 'medium', $imag 1237 1240 * @param string $image_src The 'src' of the image. 1238 1241 * @param array $image_meta The image meta data as returned by 'wp_get_attachment_metadata()'. 1239 1242 * @param int $attachment_id Optional. The image attachment ID. Default 0. 1243 * @param array $image_attr Optional. Image attributes. 1244 1240 1245 * @return string|false The 'srcset' attribute value. False on error or when only one source exists. 1241 1246 */ 1242 function wp_calculate_image_srcset( $size_array, $image_src, $image_meta, $attachment_id = 0 ) {1247 function wp_calculate_image_srcset( $size_array, $image_src, $image_meta, $attachment_id = 0, $image_attr = array() ) { 1243 1248 /** 1244 1249 * Let plugins pre-filter the image meta to be able to fix inconsistencies in the stored data. 1245 1250 * … … function wp_calculate_image_srcset( $size_array, $image_src, $image_meta, $attac 1254 1259 * } 1255 1260 * @param string $image_src The 'src' of the image. 1256 1261 * @param int $attachment_id The image attachment ID or 0 if not supplied. 1262 * @param string $image_attr The image attributes. 1257 1263 */ 1258 $image_meta = apply_filters( 'wp_calculate_image_srcset_meta', $image_meta, $size_array, $image_src, $attachment_id );1264 $image_meta = apply_filters( 'wp_calculate_image_srcset_meta', $image_meta, $size_array, $image_src, $attachment_id, $image_attr ); 1259 1265 1260 1266 if ( empty( $image_meta['sizes'] ) || ! isset( $image_meta['file'] ) || strlen( $image_meta['file'] ) < 4 ) { 1261 1267 return false; … … function wp_calculate_image_srcset( $size_array, $image_src, $image_meta, $attac 1413 1419 * @param string $image_src The 'src' of the image. 1414 1420 * @param array $image_meta The image meta data as returned by 'wp_get_attachment_metadata()'. 1415 1421 * @param int $attachment_id Image attachment ID or 0. 1422 * @param array $image_attr Image attributes. 1416 1423 */ 1417 $sources = apply_filters( 'wp_calculate_image_srcset', $sources, $size_array, $image_src, $image_meta, $attachment_id );1424 $sources = apply_filters( 'wp_calculate_image_srcset', $sources, $size_array, $image_src, $image_meta, $attachment_id, $image_attr ); 1418 1425 1419 1426 // Only return a 'srcset' value if there is more than one source. 1420 1427 if ( ! $src_matched || ! is_array( $sources ) || count( $sources ) < 2 ) { … … function wp_calculate_image_srcset( $size_array, $image_src, $image_meta, $attac 1434 1441 * Retrieves the value for an image attachment's 'sizes' attribute. 1435 1442 * 1436 1443 * @since 4.4.0 1444 * @since 5.7.0 Added the '$image_attr' parameter. 1437 1445 * 1438 1446 * @see wp_calculate_image_sizes() 1439 1447 * … … function wp_calculate_image_srcset( $size_array, $image_src, $image_meta, $attac 1442 1450 * width and height values in pixels (in that order). Default 'medium'. 1443 1451 * @param array $image_meta Optional. The image meta data as returned by 'wp_get_attachment_metadata()'. 1444 1452 * Default null. 1453 * @param array $image_attr Optional. Image attributes. 1445 1454 * @return string|false A valid source size value for use in a 'sizes' attribute or false. 1446 1455 */ 1447 function wp_get_attachment_image_sizes( $attachment_id, $size = 'medium', $image_meta = null ) {1456 function wp_get_attachment_image_sizes( $attachment_id, $size = 'medium', $image_meta = null, $image_attr = array() ) { 1448 1457 $image = wp_get_attachment_image_src( $attachment_id, $size ); 1449 1458 1450 1459 if ( ! $image ) { … … function wp_get_attachment_image_sizes( $attachment_id, $size = 'medium', $image 1461 1470 absint( $image[2] ), 1462 1471 ); 1463 1472 1464 return wp_calculate_image_sizes( $size_array, $image_src, $image_meta, $attachment_id );1473 return wp_calculate_image_sizes( $size_array, $image_src, $image_meta, $attachment_id, $image_attr ); 1465 1474 } 1466 1475 1467 1476 /** … … function wp_calculate_image_sizes( $size, $image_src = null, $image_meta = null, 1507 1516 * Filters the output of 'wp_calculate_image_sizes()'. 1508 1517 * 1509 1518 * @since 4.4.0 1519 * @since 5.7.0 Added the '$image_attr' parameter. 1510 1520 * 1511 1521 * @param string $sizes A source size value for use in a 'sizes' attribute. 1512 1522 * @param string|int[] $size Requested image size. Can be any registered image size name, or 1513 1523 * an array of width and height values in pixels (in that order). 1514 1524 * @param string|null $image_src The URL to the image file or null. 1515 1525 * @param array|null $image_meta The image meta data as returned by wp_get_attachment_metadata() or null. 1526 * @param array $image_attr Image attributes. 1516 1527 * @param int $attachment_id Image attachment ID of the original image or 0. 1517 1528 */ 1518 return apply_filters( 'wp_calculate_image_sizes', $sizes, $size, $image_src, $image_meta, $attachment_id );1529 return apply_filters( 'wp_calculate_image_sizes', $sizes, $size, $image_src, $image_meta, $attachment_id, $image_attr ); 1519 1530 } 1520 1531 1521 1532 /** -
tests/phpunit/tests/media.php
diff --git tests/phpunit/tests/media.php tests/phpunit/tests/media.php index e7326fec65..cfd2eaba0c 100644
EOF; 3159 3159 array( 'trash-attachment', '/?attachment_id=%ID%', false ), 3160 3160 ); 3161 3161 } 3162 3163 /** 3164 * @ticket 36982 3165 */ 3166 public function test_filter_image_srcset_and_sizes_by_image_attributes() { 3167 3168 $image_meta = wp_get_attachment_metadata( self::$large_id ); 3169 $class_attribute_string = 'test-class-string test-image-full'; 3170 3171 // Add a filter to remove srcset and sizes from the generated image. 3172 add_filter( 'wp_calculate_image_srcset', '__return_false' ); 3173 add_filter( 'wp_calculate_image_sizes', '__return_false' ); 3174 3175 $image_with_class_attribute_no_srcset_sizes = wp_get_attachment_image( self::$large_id, 'full', false, array( 'class' => $class_attribute_string, 'alt' => 'Full size test image' ) ); 3176 $image_without_class_attribute_no_srcset_sizes = wp_get_attachment_image( self::$large_id, 'full', false, array( 'class' => '', 'alt' => 'Full size test image' ) ); 3177 3178 // Remove the filter to restore srcset and sizes from the generated image. 3179 remove_filter( 'wp_calculate_image_srcset', '__return_false' ); 3180 remove_filter( 'wp_calculate_image_sizes', '__return_false' ); 3181 3182 $default_image_without_class_attribute = wp_get_attachment_image( self::$large_id, 'full', false, array( 'class' => '', 'alt' => 'Full size test image' ) ); 3183 $default_srcset_string_without_class_attribute = wp_get_attachment_image_srcset( self::$large_id, 'full', false, array( 'class' => '', 'alt' => 'Full size test image' ) ); 3184 $default_sizes_string_without_class_attribute = wp_get_attachment_image_sizes( self::$large_id, 'full', false, array( 'class' => '', 'alt' => 'Full size test image' ) ); 3185 3186 // Filter the srcset and sizes values. 3187 add_filter( 'wp_calculate_image_srcset', array( $this, '_filter_36982_srcset' ), 10, 6 ); 3188 add_filter( 'wp_calculate_image_sizes', array( $this, '_filter_36982_sizes' ), 10, 6 ); 3189 3190 // Generate an image with srcset and sizes values that should match the filtered image. 3191 $uploads_dir_url = 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/'; 3192 $image_file_date_dir = preg_replace( '/(\d{4}\/\d{2}\/).+/', '$1', $image_meta['file'] ); 3193 3194 // Set sources that will match the filtered values. 3195 $expected_sources = array( 3196 $image_meta['width'] => array( 3197 'url' => $uploads_dir_url . $image_meta['file'], 3198 'descriptor' => 'w', 3199 'value' => $image_meta['width'], 3200 'width' => $image_meta['width'], 3201 'height' => $image_meta['height'], 3202 ), 3203 ); 3204 3205 foreach( $image_meta['sizes'] as $size ) { 3206 $expected_sources[ $size['width'] ] = array( 3207 'url' => $uploads_dir_url . $image_file_date_dir . $size['file'], 3208 'descriptor' => 'w', 3209 'value' => $size['width'], 3210 'width' => $size['width'], 3211 'height' => $size['height'], 3212 ); 3213 } 3214 3215 $expected_sources = array_slice( array_filter( array_map( function( $source, $image_meta ) { 3216 if ( ! wp_image_matches_ratio( $image_meta['width'], $image_meta['height'], $source['width'], $source['height'] ) || $source['value'] > apply_filters( 'max_srcset_image_width', 1600, array( $image_meta['width'], $image_meta['height'] ) ) ) { 3217 return false; 3218 } 3219 return $source['url'] . ' ' . $source['value'] . $source['descriptor']; 3220 }, $expected_sources, array_fill( 0, count( $expected_sources ), $image_meta ) ) ), 2 ); 3221 3222 // Set a sizes sting value that will match the arbitrary value set in the filter. 3223 $expected_sizes_string = sprintf( '(max-width: %1$dpx) 100vw, %1$dpx', 9999 ); 3224 3225 $expected_image = '<img width="' . $image_meta['width'] . '" height="' . $image_meta['height'] . '" src="' . $uploads_dir_url . $image_meta['file'] . '" class="' . $class_attribute_string . '" alt="Full size test image" srcset="' . implode( ', ', $expected_sources ) . '" sizes="' . $expected_sizes_string . '" />'; 3226 3227 // Images without a class attribute that will match the test filter. Should match the default image with unfiltered srcset and sizes values. 3228 $this->assertSame( $default_image_without_class_attribute, wp_get_attachment_image( self::$large_id, 'full', false, array( 'class' => '', 'alt' => 'Full size test image' ) ) ); 3229 $this->assertSame( $default_image_without_class_attribute, wp_image_add_srcset_and_sizes( $image_without_class_attribute_no_srcset_sizes, $image_meta, self::$large_id ) ); 3230 3231 // Images with a class attribute that will match the test filter. Should match the expected image with filtered srcset and sizes values. 3232 $this->assertSame( $expected_image, wp_image_add_srcset_and_sizes( $image_with_class_attribute_no_srcset_sizes, $image_meta, self::$large_id ) ); 3233 $this->assertSame( $expected_image, wp_get_attachment_image( self::$large_id, 'full', false, array( 'class' => $class_attribute_string, 'alt' => 'Full size test image' ) ) ); 3234 3235 // Srcset and sizes strings with class attribute string. Should match the filtered string. 3236 $this->assertSame( implode( ', ', $expected_sources ), wp_get_attachment_image_srcset( self::$large_id, 'full', false, array( 'class' => $class_attribute_string, 'alt' => 'Full size test image' ) ) ); 3237 $this->assertSame( $expected_sizes_string, wp_get_attachment_image_sizes( self::$large_id, 'full', false, array( 'class' => $class_attribute_string, 'alt' => 'Full size test image' ) ) ); 3238 3239 // Srcset and sizes strings without class attribute string. Should match the unfiltered default string. 3240 $this->assertSame( $default_srcset_string_without_class_attribute, wp_get_attachment_image_srcset( self::$large_id, 'full', false, array( 'class' => '', 'alt' => 'Full size test image' ) ) ); 3241 $this->assertSame( $default_sizes_string_without_class_attribute, wp_get_attachment_image_sizes( self::$large_id, 'full', false, array( 'class' => '', 'alt' => 'Full size test image' ) ) ); 3242 3243 3244 } 3245 3246 public function _filter_36982_srcset( $sources, $size_array, $image_src, $image_meta, $attachment_id, $image_attr ) { 3247 3248 if ( empty( $image_attr ) ) { 3249 return $sources; 3250 } 3251 3252 if ( empty( $image_attr['class'] ) ) { 3253 return $sources; 3254 } 3255 3256 $class_array = explode( ' ', $image_attr['class'] ); 3257 3258 if ( in_array( 'test-image-full', $class_array, true ) ) { 3259 return array_slice( $sources, 2 ); 3260 } 3261 3262 return $sources; 3263 } 3264 public function _filter_36982_sizes( $sizes, $size_array, $image_src, $image_meta, $attachment_id, $image_attr ) { 3265 3266 if ( empty( $image_attr ) ) { 3267 return $sizes; 3268 } 3269 3270 if ( empty( $image_attr['class'] ) ) { 3271 return $sizes; 3272 } 3273 3274 $class_array = explode( ' ', $image_attr['class'] ); 3275 3276 if ( in_array( 'test-image-full', $class_array, true ) ) { 3277 return sprintf( '(max-width: %1$dpx) 100vw, %1$dpx', 9999 ); 3278 } 3279 3280 return $sizes; 3281 } 3162 3282 } 3163 3283 3164 3284 /**