Ticket #36982: 36982.6.diff
File 36982.6.diff, 15.8 KB (added by , 3 years ago) |
---|
-
src/wp-includes/media.php
diff --git src/wp-includes/media.php src/wp-includes/media.php index 6e7f66760f..a45cc80ab1 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 ) { 1194 1194 * Retrieves the value for an image attachment's 'srcset' attribute. 1195 1195 * 1196 1196 * @since 4.4.0 1197 * @since 5.7.0 Added the '$image_attr' parameter. 1197 1198 * 1198 1199 * @see wp_calculate_image_srcset() 1199 1200 * … … function _wp_get_image_size_from_meta( $size_name, $image_meta ) { 1202 1203 * width and height values in pixels (in that order). Default 'medium'. 1203 1204 * @param array $image_meta Optional. The image meta data as returned by 'wp_get_attachment_metadata()'. 1204 1205 * Default null. 1206 * @param array $image_attr Optional. An array of image attributes to be passed to 'wp_calculate_image_srcset()'. 1205 1207 * @return string|false A 'srcset' value string or false. 1206 1208 */ 1207 function wp_get_attachment_image_srcset( $attachment_id, $size = 'medium', $image_meta = null ) {1209 function wp_get_attachment_image_srcset( $attachment_id, $size = 'medium', $image_meta = null, $image_attr = array() ) { 1208 1210 $image = wp_get_attachment_image_src( $attachment_id, $size ); 1209 1211 1210 1212 if ( ! $image ) { … … function wp_get_attachment_image_srcset( $attachment_id, $size = 'medium', $imag 1221 1223 absint( $image[2] ), 1222 1224 ); 1223 1225 1224 return wp_calculate_image_srcset( $size_array, $image_src, $image_meta, $attachment_id );1226 return wp_calculate_image_srcset( $size_array, $image_src, $image_meta, $attachment_id, $image_attr ); 1225 1227 } 1226 1228 1227 1229 /** 1228 1230 * A helper function to calculate the image sources to include in a 'srcset' attribute. 1229 1231 * 1230 1232 * @since 4.4.0 1233 * @since 5.7.0 Added the '$image_attr' parameter. 1231 1234 * 1232 1235 * @param int[] $size_array { 1233 1236 * An array of width and height values. … … function wp_get_attachment_image_srcset( $attachment_id, $size = 'medium', $imag 1238 1241 * @param string $image_src The 'src' of the image. 1239 1242 * @param array $image_meta The image meta data as returned by 'wp_get_attachment_metadata()'. 1240 1243 * @param int $attachment_id Optional. The image attachment ID. Default 0. 1244 * @param array $image_attr Optional. Image attributes. 1245 1241 1246 * @return string|false The 'srcset' attribute value. False on error or when only one source exists. 1242 1247 */ 1243 function wp_calculate_image_srcset( $size_array, $image_src, $image_meta, $attachment_id = 0 ) {1248 function wp_calculate_image_srcset( $size_array, $image_src, $image_meta, $attachment_id = 0, $image_attr = array() ) { 1244 1249 /** 1245 1250 * Let plugins pre-filter the image meta to be able to fix inconsistencies in the stored data. 1246 1251 * … … function wp_calculate_image_srcset( $size_array, $image_src, $image_meta, $attac 1255 1260 * } 1256 1261 * @param string $image_src The 'src' of the image. 1257 1262 * @param int $attachment_id The image attachment ID or 0 if not supplied. 1263 * @param string $image_attr The image attributes. 1258 1264 */ 1259 $image_meta = apply_filters( 'wp_calculate_image_srcset_meta', $image_meta, $size_array, $image_src, $attachment_id );1265 $image_meta = apply_filters( 'wp_calculate_image_srcset_meta', $image_meta, $size_array, $image_src, $attachment_id, $image_attr ); 1260 1266 1261 1267 if ( empty( $image_meta['sizes'] ) || ! isset( $image_meta['file'] ) || strlen( $image_meta['file'] ) < 4 ) { 1262 1268 return false; … … function wp_calculate_image_srcset( $size_array, $image_src, $image_meta, $attac 1414 1420 * @param string $image_src The 'src' of the image. 1415 1421 * @param array $image_meta The image meta data as returned by 'wp_get_attachment_metadata()'. 1416 1422 * @param int $attachment_id Image attachment ID or 0. 1423 * @param array $image_attr Image attributes. 1417 1424 */ 1418 $sources = apply_filters( 'wp_calculate_image_srcset', $sources, $size_array, $image_src, $image_meta, $attachment_id );1425 $sources = apply_filters( 'wp_calculate_image_srcset', $sources, $size_array, $image_src, $image_meta, $attachment_id, $image_attr ); 1419 1426 1420 1427 // Only return a 'srcset' value if there is more than one source. 1421 1428 if ( ! $src_matched || ! is_array( $sources ) || count( $sources ) < 2 ) { … … function wp_calculate_image_srcset( $size_array, $image_src, $image_meta, $attac 1435 1442 * Retrieves the value for an image attachment's 'sizes' attribute. 1436 1443 * 1437 1444 * @since 4.4.0 1445 * @since 5.7.0 Added the '$image_attr' parameter. 1438 1446 * 1439 1447 * @see wp_calculate_image_sizes() 1440 1448 * … … function wp_calculate_image_srcset( $size_array, $image_src, $image_meta, $attac 1443 1451 * width and height values in pixels (in that order). Default 'medium'. 1444 1452 * @param array $image_meta Optional. The image meta data as returned by 'wp_get_attachment_metadata()'. 1445 1453 * Default null. 1454 * @param array $image_attr Optional. Image attributes. 1446 1455 * @return string|false A valid source size value for use in a 'sizes' attribute or false. 1447 1456 */ 1448 function wp_get_attachment_image_sizes( $attachment_id, $size = 'medium', $image_meta = null ) {1457 function wp_get_attachment_image_sizes( $attachment_id, $size = 'medium', $image_meta = null, $image_attr = array() ) { 1449 1458 $image = wp_get_attachment_image_src( $attachment_id, $size ); 1450 1459 1451 1460 if ( ! $image ) { … … function wp_get_attachment_image_sizes( $attachment_id, $size = 'medium', $image 1462 1471 absint( $image[2] ), 1463 1472 ); 1464 1473 1465 return wp_calculate_image_sizes( $size_array, $image_src, $image_meta, $attachment_id );1474 return wp_calculate_image_sizes( $size_array, $image_src, $image_meta, $attachment_id, $image_attr ); 1466 1475 } 1467 1476 1468 1477 /** 1469 1478 * Creates a 'sizes' attribute value for an image. 1470 1479 * 1471 1480 * @since 4.4.0 1481 * @since 5.7.0 Added the '$image_attr' parameter. 1472 1482 * 1473 1483 * @param string|int[] $size Image size. Accepts any registered image size name, or an array of 1474 1484 * width and height values in pixels (in that order). … … function wp_get_attachment_image_sizes( $attachment_id, $size = 'medium', $image 1477 1487 * Default null. 1478 1488 * @param int $attachment_id Optional. Image attachment ID. Either `$image_meta` or `$attachment_id` 1479 1489 * is needed when using the image size name as argument for `$size`. Default 0. 1490 * @param array $image_attr Image attributes. 1480 1491 * @return string|false A valid source size value for use in a 'sizes' attribute or false. 1481 1492 */ 1482 function wp_calculate_image_sizes( $size, $image_src = null, $image_meta = null, $attachment_id = 0 ) {1493 function wp_calculate_image_sizes( $size, $image_src = null, $image_meta = null, $attachment_id = 0, $image_attr = array() ) { 1483 1494 $width = 0; 1484 1495 1485 1496 if ( is_array( $size ) ) { … … function wp_calculate_image_sizes( $size, $image_src = null, $image_meta = null, 1508 1519 * Filters the output of 'wp_calculate_image_sizes()'. 1509 1520 * 1510 1521 * @since 4.4.0 1522 * @since 5.7.0 Added the '$image_attr' parameter. 1511 1523 * 1512 1524 * @param string $sizes A source size value for use in a 'sizes' attribute. 1513 1525 * @param string|int[] $size Requested image size. Can be any registered image size name, or … … function wp_calculate_image_sizes( $size, $image_src = null, $image_meta = null, 1515 1527 * @param string|null $image_src The URL to the image file or null. 1516 1528 * @param array|null $image_meta The image meta data as returned by wp_get_attachment_metadata() or null. 1517 1529 * @param int $attachment_id Image attachment ID of the original image or 0. 1530 * @param array $image_attr Image attributes. 1518 1531 */ 1519 return apply_filters( 'wp_calculate_image_sizes', $sizes, $size, $image_src, $image_meta, $attachment_id );1532 return apply_filters( 'wp_calculate_image_sizes', $sizes, $size, $image_src, $image_meta, $attachment_id, $image_attr ); 1520 1533 } 1521 1534 1522 1535 /** -
tests/phpunit/tests/media.php
diff --git tests/phpunit/tests/media.php tests/phpunit/tests/media.php index 1be2526ff4..74102613dd 100644
EOF; 3186 3186 array( 'trash-attachment', '/?attachment_id=%ID%', false ), 3187 3187 ); 3188 3188 } 3189 3190 /** 3191 * @ticket 36982 3192 */ 3193 public function test_filter_image_srcset_and_sizes_by_image_attributes() { 3194 3195 $image_meta = wp_get_attachment_metadata( self::$large_id ); 3196 $class_attribute_string = 'test-class-string test-image-full'; 3197 3198 // Add a filter to remove srcset and sizes from the generated image. 3199 add_filter( 'wp_calculate_image_srcset', '__return_false' ); 3200 add_filter( 'wp_calculate_image_sizes', '__return_false' ); 3201 3202 $image_with_class_attribute_no_srcset_sizes = wp_get_attachment_image( 3203 self::$large_id, 3204 'full', 3205 false, 3206 array( 3207 'class' => $class_attribute_string, 3208 'alt' => 'Full size test image', 3209 ) 3210 ); 3211 $image_without_class_attribute_no_srcset_sizes = wp_get_attachment_image( 3212 self::$large_id, 3213 'full', 3214 false, 3215 array( 3216 'class' => '', 3217 'alt' => 'Full size test image', 3218 ) 3219 ); 3220 3221 // Remove the filter to restore srcset and sizes from the generated image. 3222 remove_filter( 'wp_calculate_image_srcset', '__return_false' ); 3223 remove_filter( 'wp_calculate_image_sizes', '__return_false' ); 3224 3225 $default_image_without_class_attribute = wp_get_attachment_image( 3226 self::$large_id, 3227 'full', 3228 false, 3229 array( 3230 'class' => '', 3231 'alt' => 'Full size test image', 3232 ) 3233 ); 3234 $default_srcset_string_without_class_attribute = wp_get_attachment_image_srcset( 3235 self::$large_id, 3236 'full', 3237 false, 3238 array( 3239 'class' => '', 3240 'alt' => 'Full size test image', 3241 ) 3242 ); 3243 $default_sizes_string_without_class_attribute = wp_get_attachment_image_sizes( 3244 self::$large_id, 3245 'full', 3246 false, 3247 array( 3248 'class' => '', 3249 'alt' => 'Full size test image', 3250 ) 3251 ); 3252 3253 // Filter the srcset and sizes values. 3254 add_filter( 'wp_calculate_image_srcset', array( $this, '_filter_36982_srcset' ), 10, 6 ); 3255 add_filter( 'wp_calculate_image_sizes', array( $this, '_filter_36982_sizes' ), 10, 6 ); 3256 3257 // Generate an image with srcset and sizes values that should match the filtered image. 3258 $uploads_dir_url = 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/'; 3259 $image_file_date_dir = preg_replace( '/(\d{4}\/\d{2}\/).+/', '$1', $image_meta['file'] ); 3260 3261 // Set sources that will match the filtered values. 3262 $expected_sources = array( 3263 $image_meta['width'] => array( 3264 'url' => $uploads_dir_url . $image_meta['file'], 3265 'descriptor' => 'w', 3266 'value' => $image_meta['width'], 3267 'width' => $image_meta['width'], 3268 'height' => $image_meta['height'], 3269 ), 3270 ); 3271 3272 foreach ( $image_meta['sizes'] as $size ) { 3273 $expected_sources[ $size['width'] ] = array( 3274 'url' => $uploads_dir_url . $image_file_date_dir . $size['file'], 3275 'descriptor' => 'w', 3276 'value' => $size['width'], 3277 'width' => $size['width'], 3278 'height' => $size['height'], 3279 ); 3280 } 3281 3282 $expected_sources = array_slice( 3283 array_filter( 3284 array_map( 3285 function( $source, $image_meta ) { 3286 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'] ) ) ) { 3287 return false; 3288 } 3289 return $source['url'] . ' ' . $source['value'] . $source['descriptor']; 3290 }, 3291 $expected_sources, 3292 array_fill( 0, count( $expected_sources ), $image_meta ) 3293 ) 3294 ), 3295 2 3296 ); 3297 3298 // Set a sizes sting value that will match the arbitrary value set in the filter. 3299 $expected_sizes_string = sprintf( '(max-width: %1$dpx) 100vw, %1$dpx', 9999 ); 3300 3301 $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" loading="lazy" srcset="' . implode( ', ', $expected_sources ) . '" sizes="' . $expected_sizes_string . '" />'; 3302 3303 // Images without a class attribute that will match the test filter. Should match the default image with unfiltered srcset and sizes values. 3304 $this->assertSame( 3305 $default_image_without_class_attribute, 3306 wp_get_attachment_image( 3307 self::$large_id, 3308 'full', 3309 false, 3310 array( 3311 'class' => '', 3312 'alt' => 'Full size test image', 3313 ) 3314 ) 3315 ); 3316 $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 ) ); 3317 3318 // Images with a class attribute that will match the test filter. Should match the expected image with filtered srcset and sizes values. 3319 $this->assertSame( $expected_image, wp_image_add_srcset_and_sizes( $image_with_class_attribute_no_srcset_sizes, $image_meta, self::$large_id ) ); 3320 $this->assertSame( 3321 $expected_image, 3322 wp_get_attachment_image( 3323 self::$large_id, 3324 'full', 3325 false, 3326 array( 3327 'class' => $class_attribute_string, 3328 'alt' => 'Full size test image', 3329 ) 3330 ) 3331 ); 3332 3333 // Srcset and sizes strings with class attribute string. Should match the filtered string. 3334 $this->assertSame( 3335 implode( ', ', $expected_sources ), 3336 wp_get_attachment_image_srcset( 3337 self::$large_id, 3338 'full', 3339 false, 3340 array( 3341 'class' => $class_attribute_string, 3342 'alt' => 'Full size test image', 3343 ) 3344 ) 3345 ); 3346 $this->assertSame( 3347 $expected_sizes_string, 3348 wp_get_attachment_image_sizes( 3349 self::$large_id, 3350 'full', 3351 false, 3352 array( 3353 'class' => $class_attribute_string, 3354 'alt' => 'Full size test image', 3355 ) 3356 ) 3357 ); 3358 3359 // Srcset and sizes strings without class attribute string. Should match the unfiltered default string. 3360 $this->assertSame( 3361 $default_srcset_string_without_class_attribute, 3362 wp_get_attachment_image_srcset( 3363 self::$large_id, 3364 'full', 3365 false, 3366 array( 3367 'class' => '', 3368 'alt' => 'Full size test image', 3369 ) 3370 ) 3371 ); 3372 $this->assertSame( 3373 $default_sizes_string_without_class_attribute, 3374 wp_get_attachment_image_sizes( 3375 self::$large_id, 3376 'full', 3377 false, 3378 array( 3379 'class' => '', 3380 'alt' => 'Full size test image', 3381 ) 3382 ) 3383 ); 3384 3385 } 3386 3387 public function _filter_36982_srcset( $sources, $size_array, $image_src, $image_meta, $attachment_id, $image_attr ) { 3388 3389 if ( empty( $image_attr ) ) { 3390 return $sources; 3391 } 3392 3393 if ( empty( $image_attr['class'] ) ) { 3394 return $sources; 3395 } 3396 3397 $class_array = explode( ' ', $image_attr['class'] ); 3398 3399 if ( in_array( 'test-image-full', $class_array, true ) ) { 3400 return array_slice( $sources, 2 ); 3401 } 3402 3403 return $sources; 3404 } 3405 public function _filter_36982_sizes( $sizes, $size_array, $image_src, $image_meta, $attachment_id, $image_attr ) { 3406 3407 if ( empty( $image_attr ) ) { 3408 return $sizes; 3409 } 3410 3411 if ( empty( $image_attr['class'] ) ) { 3412 return $sizes; 3413 } 3414 3415 $class_array = explode( ' ', $image_attr['class'] ); 3416 3417 if ( in_array( 'test-image-full', $class_array, true ) ) { 3418 return sprintf( '(max-width: %1$dpx) 100vw, %1$dpx', 9999 ); 3419 } 3420 3421 return $sizes; 3422 } 3189 3423 } 3190 3424 3191 3425 /**