Ticket #36982: 36982.5.diff
File 36982.5.diff, 15.8 KB (added by , 4 years ago) |
---|
-
src/wp-includes/media.php
diff --git a/src/wp-includes/media.php b/src/wp-includes/media.php index 088e6868c7..09eef00976 100644
a b 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 /** 1468 1477 * Creates a 'sizes' attribute value for an image. 1469 1478 * 1470 1479 * @since 4.4.0 1480 * @since 5.7.0 Added the '$image_attr' parameter. 1471 1481 * 1472 1482 * @param string|int[] $size Image size. Accepts any registered image size name, or an array of 1473 1483 * width and height values in pixels (in that order). … … function wp_get_attachment_image_sizes( $attachment_id, $size = 'medium', $image 1476 1486 * Default null. 1477 1487 * @param int $attachment_id Optional. Image attachment ID. Either `$image_meta` or `$attachment_id` 1478 1488 * is needed when using the image size name as argument for `$size`. Default 0. 1489 * @param array $image_attr Image attributes. 1479 1490 * @return string|false A valid source size value for use in a 'sizes' attribute or false. 1480 1491 */ 1481 function wp_calculate_image_sizes( $size, $image_src = null, $image_meta = null, $attachment_id = 0 ) {1492 function wp_calculate_image_sizes( $size, $image_src = null, $image_meta = null, $attachment_id = 0, $image_attr = array() ) { 1482 1493 $width = 0; 1483 1494 1484 1495 if ( is_array( $size ) ) { … … function wp_calculate_image_sizes( $size, $image_src = null, $image_meta = null, 1507 1518 * Filters the output of 'wp_calculate_image_sizes()'. 1508 1519 * 1509 1520 * @since 4.4.0 1521 * @since 5.7.0 Added the '$image_attr' parameter. 1510 1522 * 1511 1523 * @param string $sizes A source size value for use in a 'sizes' attribute. 1512 1524 * @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, 1514 1526 * @param string|null $image_src The URL to the image file or null. 1515 1527 * @param array|null $image_meta The image meta data as returned by wp_get_attachment_metadata() or null. 1516 1528 * @param int $attachment_id Image attachment ID of the original image or 0. 1529 * @param array $image_attr Image attributes. 1517 1530 */ 1518 return apply_filters( 'wp_calculate_image_sizes', $sizes, $size, $image_src, $image_meta, $attachment_id );1531 return apply_filters( 'wp_calculate_image_sizes', $sizes, $size, $image_src, $image_meta, $attachment_id, $image_attr ); 1519 1532 } 1520 1533 1521 1534 /** -
tests/phpunit/tests/media.php
diff --git a/tests/phpunit/tests/media.php b/tests/phpunit/tests/media.php index 055618f620..f5daa8090f 100644
a b EOF; 3164 3164 array( 'trash-attachment', '/?attachment_id=%ID%', false ), 3165 3165 ); 3166 3166 } 3167 3168 /** 3169 * @ticket 36982 3170 */ 3171 public function test_filter_image_srcset_and_sizes_by_image_attributes() { 3172 3173 $image_meta = wp_get_attachment_metadata( self::$large_id ); 3174 $class_attribute_string = 'test-class-string test-image-full'; 3175 3176 // Add a filter to remove srcset and sizes from the generated image. 3177 add_filter( 'wp_calculate_image_srcset', '__return_false' ); 3178 add_filter( 'wp_calculate_image_sizes', '__return_false' ); 3179 3180 $image_with_class_attribute_no_srcset_sizes = wp_get_attachment_image( 3181 self::$large_id, 3182 'full', 3183 false, 3184 array( 3185 'class' => $class_attribute_string, 3186 'alt' => 'Full size test image', 3187 ) 3188 ); 3189 $image_without_class_attribute_no_srcset_sizes = wp_get_attachment_image( 3190 self::$large_id, 3191 'full', 3192 false, 3193 array( 3194 'class' => '', 3195 'alt' => 'Full size test image', 3196 ) 3197 ); 3198 3199 // Remove the filter to restore srcset and sizes from the generated image. 3200 remove_filter( 'wp_calculate_image_srcset', '__return_false' ); 3201 remove_filter( 'wp_calculate_image_sizes', '__return_false' ); 3202 3203 $default_image_without_class_attribute = wp_get_attachment_image( 3204 self::$large_id, 3205 'full', 3206 false, 3207 array( 3208 'class' => '', 3209 'alt' => 'Full size test image', 3210 ) 3211 ); 3212 $default_srcset_string_without_class_attribute = wp_get_attachment_image_srcset( 3213 self::$large_id, 3214 'full', 3215 false, 3216 array( 3217 'class' => '', 3218 'alt' => 'Full size test image', 3219 ) 3220 ); 3221 $default_sizes_string_without_class_attribute = wp_get_attachment_image_sizes( 3222 self::$large_id, 3223 'full', 3224 false, 3225 array( 3226 'class' => '', 3227 'alt' => 'Full size test image', 3228 ) 3229 ); 3230 3231 // Filter the srcset and sizes values. 3232 add_filter( 'wp_calculate_image_srcset', array( $this, '_filter_36982_srcset' ), 10, 6 ); 3233 add_filter( 'wp_calculate_image_sizes', array( $this, '_filter_36982_sizes' ), 10, 6 ); 3234 3235 // Generate an image with srcset and sizes values that should match the filtered image. 3236 $uploads_dir_url = 'http://' . WP_TESTS_DOMAIN . '/wp-content/uploads/'; 3237 $image_file_date_dir = preg_replace( '/(\d{4}\/\d{2}\/).+/', '$1', $image_meta['file'] ); 3238 3239 // Set sources that will match the filtered values. 3240 $expected_sources = array( 3241 $image_meta['width'] => array( 3242 'url' => $uploads_dir_url . $image_meta['file'], 3243 'descriptor' => 'w', 3244 'value' => $image_meta['width'], 3245 'width' => $image_meta['width'], 3246 'height' => $image_meta['height'], 3247 ), 3248 ); 3249 3250 foreach ( $image_meta['sizes'] as $size ) { 3251 $expected_sources[ $size['width'] ] = array( 3252 'url' => $uploads_dir_url . $image_file_date_dir . $size['file'], 3253 'descriptor' => 'w', 3254 'value' => $size['width'], 3255 'width' => $size['width'], 3256 'height' => $size['height'], 3257 ); 3258 } 3259 3260 $expected_sources = array_slice( 3261 array_filter( 3262 array_map( 3263 function( $source, $image_meta ) { 3264 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'] ) ) ) { 3265 return false; 3266 } 3267 return $source['url'] . ' ' . $source['value'] . $source['descriptor']; 3268 }, 3269 $expected_sources, 3270 array_fill( 0, count( $expected_sources ), $image_meta ) 3271 ) 3272 ), 3273 2 3274 ); 3275 3276 // Set a sizes sting value that will match the arbitrary value set in the filter. 3277 $expected_sizes_string = sprintf( '(max-width: %1$dpx) 100vw, %1$dpx', 9999 ); 3278 3279 $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 . '" />'; 3280 3281 // Images without a class attribute that will match the test filter. Should match the default image with unfiltered srcset and sizes values. 3282 $this->assertSame( 3283 $default_image_without_class_attribute, 3284 wp_get_attachment_image( 3285 self::$large_id, 3286 'full', 3287 false, 3288 array( 3289 'class' => '', 3290 'alt' => 'Full size test image', 3291 ) 3292 ) 3293 ); 3294 $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 ) ); 3295 3296 // Images with a class attribute that will match the test filter. Should match the expected image with filtered srcset and sizes values. 3297 $this->assertSame( $expected_image, wp_image_add_srcset_and_sizes( $image_with_class_attribute_no_srcset_sizes, $image_meta, self::$large_id ) ); 3298 $this->assertSame( 3299 $expected_image, 3300 wp_get_attachment_image( 3301 self::$large_id, 3302 'full', 3303 false, 3304 array( 3305 'class' => $class_attribute_string, 3306 'alt' => 'Full size test image', 3307 ) 3308 ) 3309 ); 3310 3311 // Srcset and sizes strings with class attribute string. Should match the filtered string. 3312 $this->assertSame( 3313 implode( ', ', $expected_sources ), 3314 wp_get_attachment_image_srcset( 3315 self::$large_id, 3316 'full', 3317 false, 3318 array( 3319 'class' => $class_attribute_string, 3320 'alt' => 'Full size test image', 3321 ) 3322 ) 3323 ); 3324 $this->assertSame( 3325 $expected_sizes_string, 3326 wp_get_attachment_image_sizes( 3327 self::$large_id, 3328 'full', 3329 false, 3330 array( 3331 'class' => $class_attribute_string, 3332 'alt' => 'Full size test image', 3333 ) 3334 ) 3335 ); 3336 3337 // Srcset and sizes strings without class attribute string. Should match the unfiltered default string. 3338 $this->assertSame( 3339 $default_srcset_string_without_class_attribute, 3340 wp_get_attachment_image_srcset( 3341 self::$large_id, 3342 'full', 3343 false, 3344 array( 3345 'class' => '', 3346 'alt' => 'Full size test image', 3347 ) 3348 ) 3349 ); 3350 $this->assertSame( 3351 $default_sizes_string_without_class_attribute, 3352 wp_get_attachment_image_sizes( 3353 self::$large_id, 3354 'full', 3355 false, 3356 array( 3357 'class' => '', 3358 'alt' => 'Full size test image', 3359 ) 3360 ) 3361 ); 3362 3363 } 3364 3365 public function _filter_36982_srcset( $sources, $size_array, $image_src, $image_meta, $attachment_id, $image_attr ) { 3366 3367 if ( empty( $image_attr ) ) { 3368 return $sources; 3369 } 3370 3371 if ( empty( $image_attr['class'] ) ) { 3372 return $sources; 3373 } 3374 3375 $class_array = explode( ' ', $image_attr['class'] ); 3376 3377 if ( in_array( 'test-image-full', $class_array, true ) ) { 3378 return array_slice( $sources, 2 ); 3379 } 3380 3381 return $sources; 3382 } 3383 public function _filter_36982_sizes( $sizes, $size_array, $image_src, $image_meta, $attachment_id, $image_attr ) { 3384 3385 if ( empty( $image_attr ) ) { 3386 return $sizes; 3387 } 3388 3389 if ( empty( $image_attr['class'] ) ) { 3390 return $sizes; 3391 } 3392 3393 $class_array = explode( ' ', $image_attr['class'] ); 3394 3395 if ( in_array( 'test-image-full', $class_array, true ) ) { 3396 return sprintf( '(max-width: %1$dpx) 100vw, %1$dpx', 9999 ); 3397 } 3398 3399 return $sizes; 3400 } 3167 3401 } 3168 3402 3169 3403 /**