if ( ! $_wp_additional_image_sizes ) { $_wp_additional_image_sizes = array(); }
return $_wp_additional_image_sizes; }
/** * Scales down the default size of an image. * * This is so that the image is a better fit for the editor and theme. * * The `$size` parameter accepts either an array or a string. The supported string * values are 'thumb' or 'thumbnail' for the given thumbnail size or defaults at * 128 width and 96 height in pixels. Also supported for the string value is * 'medium', 'medium_large' and 'full'. The 'full' isn't actually supported, but any value other * than the supported will result in the content_width size or 500 if that is * not set. * * Finally, there is a filter named {@see 'editor_max_image_size'}, that will be * called on the calculated array for width and height, respectively. * * @since 2.5.0 * * @global int $content_width * * @param int $width Width of the image in pixels. * @param int $height Height of the image in pixels. * @param string|int[] $size Optional. Image size. Accepts any registered image size name, or an array * of width and height values in pixels (in that order). Default 'medium'. * @param string $context Optional. Could be 'display' (like in a theme) or 'edit' * (like inserting into an editor). Default null. * @return int[] { * An array of width and height values. * * @type int $0 The maximum width in pixels. * @type int $1 The maximum height in pixels. * } */ function image_constrain_size_for_editor( $width, $height, $size = 'medium', $context = null ) { global $content_width;
if ( (int) $content_width > 0 ) { $max_width = min( (int) $content_width, $max_width ); } } elseif ( 'large' === $size ) { /* * We're inserting a large size image into the editor. If it's a really * big image we'll scale it down to fit reasonably within the editor * itself, and within the theme's content width if it's known. The user * can resize it in the editor if they wish. */ $max_width = (int) get_option( 'large_size_w' ); $max_height = (int) get_option( 'large_size_h' );
/** * Filters the maximum image size dimensions for the editor. * * @since 2.5.0 * * @param int[] $max_image_size { * An array of width and height values. * * @type int $0 The maximum width in pixels. * @type int $1 The maximum height in pixels. * } * @param string|int[] $size Requested image size. Can be any registered image size name, or * an array of width and height values in pixels (in that order). * @param string $context The context the image is being resized for. * Possible values are 'display' (like in a theme) * or 'edit' (like inserting into an editor). */ list( $max_width, $max_height ) = apply_filters( 'editor_max_image_size', array( $max_width, $max_height ), $size, $context );
/** * Retrieves width and height attributes using given width and height values. * * Both attributes are required in the sense that both parameters must have a * value, but are optional in that if you set them to false or null, then they * will not be added to the returned string. * * You can set the value using a string, but it will only take numeric values. * If you wish to put 'px' after the numbers, then it will be stripped out of * the return. * * @since 2.5.0 * * @param int|string $width Image width in pixels. * @param int|string $height Image height in pixels. * @return string HTML attributes for width and, or height. */ function image_hwstring( $width, $height ) { $out = ''; if ( $width ) { $out .= 'width="' . (int) $width . '" '; } if ( $height ) { $out .= 'height="' . (int) $height . '" '; } return $out; }
/** * Scales an image to fit a particular size (such as 'thumb' or 'medium'). * * The URL might be the original image, or it might be a resized version. This * function won't create a new resized copy, it will just return an already * resized one if it exists. * * A plugin may use the {@see 'image_downsize'} filter to hook into and offer image * resizing services for images. The hook must return an array with the same * elements that are normally returned from the function. * * @since 2.5.0 * * @param int $id Attachment ID for image. * @param string|int[] $size Optional. Image size. Accepts any registered image size name, or an array * of width and height values in pixels (in that order). Default 'medium'. * @return array|false { * Array of image data, or boolean false if no image is available. * * @type string $0 Image source URL. * @type int $1 Image width in pixels. * @type int $2 Image height in pixels. * @type bool $3 Whether the image is a resized image. * } */ function image_downsize( $id, $size = 'medium' ) { $is_image = wp_attachment_is_image( $id );
/** * Filters whether to preempt the output of image_downsize(). * * Returning a truthy value from the filter will effectively short-circuit * down-sizing the image, returning that value instead. * * @since 2.5.0 * * @param bool|array $downsize Whether to short-circuit the image downsize. * @param int $id Attachment ID for image. * @param string|int[] $size Requested image size. Can be any registered image size name, or * an array of width and height values in pixels (in that order). */ $out = apply_filters( 'image_downsize', false, $id, $size );
/* * If the file isn't an image, attempt to replace its URL with a rendered image from its meta. * Otherwise, a non-image type could be returned. */ if ( ! $is_image ) { if ( ! empty( $meta['sizes']['full'] ) ) { $img_url = str_replace( $img_url_basename, $meta['sizes']['full']['file'], $img_url ); $img_url_basename = $meta['sizes']['full']['file']; $width = $meta['sizes']['full']['width']; $height = $meta['sizes']['full']['height']; } else { return false; } }
// Try for a new style intermediate size. $intermediate = image_get_intermediate_size( $id, $size );
if ( ! $width && ! $height && isset( $meta['width'], $meta['height'] ) ) { // Any other type: use the real image. $width = $meta['width']; $height = $meta['height']; }
if ( $img_url ) { // We have the actual image size, but might need to further constrain it if content_width is narrower. list( $width, $height ) = image_constrain_size_for_editor( $width, $height, $size );
/** * Registers a new image size. * * @since 2.9.0 * * @global array $_wp_additional_image_sizes Associative array of additional image sizes. * * @param string $name Image size identifier. * @param int $width Optional. Image width in pixels. Default 0. * @param int $height Optional. Image height in pixels. Default 0. * @param bool|array $crop { * Optional. Image cropping behavior. If false, the image will be scaled (default). * If true, image will be cropped to the specified dimensions using center positions. * If an array, the image will be cropped using the array to specify the crop location: * * @type string $0 The x crop position. Accepts 'left' 'center', or 'right'. * @type string $1 The y crop position. Accepts 'top', 'center', or 'bottom'. * } */ function add_image_size( $name, $width = 0, $height = 0, $crop = false ) { global $_wp_additional_image_sizes;
/** * Checks if an image size exists. * * @since 3.9.0 * * @param string $name The image size to check. * @return bool True if the image size exists, false if not. */ function has_image_size( $name ) { $sizes = wp_get_additional_image_sizes(); return isset( $sizes[ $name ] ); }
/** * Removes a new image size. * * @since 3.9.0 * * @global array $_wp_additional_image_sizes * * @param string $name The image size to remove. * @return bool True if the image size was successfully removed, false on failure. */ function remove_image_size( $name ) { global $_wp_additional_image_sizes;
/** * Registers an image size for the post thumbnail. * * @since 2.9.0 * * @see add_image_size() for details on cropping behavior. * * @param int $width Image width in pixels. * @param int $height Image height in pixels. * @param bool|array $crop { * Optional. Image cropping behavior. If false, the image will be scaled (default). * If true, image will be cropped to the specified dimensions using center positions. * If an array, the image will be cropped using the array to specify the crop location: * * @type string $0 The x crop position. Accepts 'left' 'center', or 'right'. * @type string $1 The y crop position. Accepts 'top', 'center', or 'bottom'. * } */ function set_post_thumbnail_size( $width = 0, $height = 0, $crop = false ) { add_image_size( 'post-thumbnail', $width, $height, $crop ); }
/** * Gets an img tag for an image attachment, scaling it down if requested. * * The {@see 'get_image_tag_class'} filter allows for changing the class name for the * image without having to use regular expressions on the HTML content. The * parameters are: what WordPress will use for the class, the Attachment ID, * image align value, and the size the image should be. * * The second filter, {@see 'get_image_tag'}, has the HTML content, which can then be * further manipulated by a plugin to change all attribute values and even HTML * content. * * @since 2.5.0 * * @param int $id Attachment ID. * @param string $alt Image description for the alt attribute. * @param string $title Image description for the title attribute. * @param string $align Part of the class name for aligning the image. * @param string|int[] $size Optional. Image size. Accepts any registered image size name, or an array of * width and height values in pixels (in that order). Default 'medium'. * @return string HTML IMG element for given image attachment. */ function get_image_tag( $id, $alt, $title, $align, $size = 'medium' ) {
/** * Filters the value of the attachment's image tag class attribute. * * @since 2.6.0 * * @param string $class CSS class name or space-separated list of classes. * @param int $id Attachment ID. * @param string $align Part of the class name for aligning the image. * @param string|int[] $size Requested image size. Can be any registered image size name, or * an array of width and height values in pixels (in that order). */ $class = apply_filters( 'get_image_tag_class', $class, $id, $align, $size );
/** * Filters the HTML content for the image tag. * * @since 2.6.0 * * @param string $html HTML content for the image. * @param int $id Attachment ID. * @param string $alt Image description for the alt attribute. * @param string $title Image description for the title attribute. * @param string $align Part of the class name for aligning the image. * @param string|int[] $size Requested image size. Can be any registered image size name, or * an array of width and height values in pixels (in that order). */ return apply_filters( 'get_image_tag', $html, $id, $alt, $title, $align, $size ); }
/** * Calculates the new dimensions for a down-sampled image. * * If either width or height are empty, no constraint is applied on * that dimension. * * @since 2.5.0 * * @param int $current_width Current width of the image. * @param int $current_height Current height of the image. * @param int $max_width Optional. Max width in pixels to constrain to. Default 0. * @param int $max_height Optional. Max height in pixels to constrain to. Default 0. * @return int[] { * An array of width and height values. * * @type int $0 The width in pixels. * @type int $1 The height in pixels. * } */ function wp_constrain_dimensions( $current_width, $current_height, $max_width = 0, $max_height = 0 ) { if ( ! $max_width && ! $max_height ) { return array( $current_width, $current_height ); }
if ( (int) round( $current_width * $larger_ratio ) > $max_width || (int) round( $current_height * $larger_ratio ) > $max_height ) { // The larger ratio is too big. It would result in an overflow. $ratio = $smaller_ratio; } else { // The larger ratio fits, and is likely to be a more "snug" fit. $ratio = $larger_ratio; }
// Very small dimensions may result in 0, 1 should be the minimum. $w = max( 1, (int) round( $current_width * $ratio ) ); $h = max( 1, (int) round( $current_height * $ratio ) );
/* * Sometimes, due to rounding, we'll end up with a result like this: * 465x700 in a 177x177 box is 117x176... a pixel short. * We also have issues with recursive calls resulting in an ever-changing result. * Constraining to the result of a constraint should yield the original result. * Thus we look for dimensions that are one pixel shy of the max value and bump them up. */
// Note: $did_width means it is possible $smaller_ratio == $width_ratio. if ( $did_width && $w === $max_width - 1 ) { $w = $max_width; // Round it up. }
// Note: $did_height means it is possible $smaller_ratio == $height_ratio. if ( $did_height && $h === $max_height - 1 ) { $h = $max_height; // Round it up. }
/** * Filters dimensions to constrain down-sampled images to. * * @since 4.1.0 * * @param int[] $dimensions { * An array of width and height values. * * @type int $0 The width in pixels. * @type int $1 The height in pixels. * } * @param int $current_width The current width of the image. * @param int $current_height The current height of the image. * @param int $max_width The maximum width permitted. * @param int $max_height The maximum height permitted. */ return apply_filters( 'wp_constrain_dimensions', array( $w, $h ), $current_width, $current_height, $max_width, $max_height ); }
/** * Retrieves calculated resize dimensions for use in WP_Image_Editor. * * Calculates dimensions and coordinates for a resized image that fits * within a specified width and height. * * @since 2.5.0 * * @param int $orig_w Original width in pixels. * @param int $orig_h Original height in pixels. * @param int $dest_w New width in pixels. * @param int $dest_h New height in pixels. * @param bool|array $crop { * Optional. Image cropping behavior. If false, the image will be scaled (default). * If true, image will be cropped to the specified dimensions using center positions. * If an array, the image will be cropped using the array to specify the crop location: * * @type string $0 The x crop position. Accepts 'left' 'center', or 'right'. * @type string $1 The y crop position. Accepts 'top', 'center', or 'bottom'. * } * @return array|false Returned array matches parameters for `imagecopyresampled()`. False on failure. */ function image_resize_dimensions( $orig_w, $orig_h, $dest_w, $dest_h, $crop = false ) {
if ( $orig_w <= 0 || $orig_h <= 0 ) { return false; } // At least one of $dest_w or $dest_h must be specific. if ( $dest_w <= 0 && $dest_h <= 0 ) { return false; }
/** * Filters whether to preempt calculating the image resize dimensions. * * Returning a non-null value from the filter will effectively short-circuit * image_resize_dimensions(), returning that value instead. * * @since 3.4.0 * * @param null|mixed $null Whether to preempt output of the resize dimensions. * @param int $orig_w Original width in pixels. * @param int $orig_h Original height in pixels. * @param int $dest_w New width in pixels. * @param int $dest_h New height in pixels. * @param bool|array $crop Whether to crop image to specified width and height or resize. * An array can specify positioning of the crop area. Default false. */ $output = apply_filters( 'image_resize_dimensions', null, $orig_w, $orig_h, $dest_w, $dest_h, $crop );
if ( null !== $output ) { return $output; }
// Stop if the destination size is larger than the original image dimensions. if ( empty( $dest_h ) ) { if ( $orig_w < $dest_w ) { return false; } } elseif ( empty( $dest_w ) ) { if ( $orig_h < $dest_h ) { return false; } } else { if ( $orig_w < $dest_w && $orig_h < $dest_h ) { return false; } }
if ( $crop ) { /* * Crop the largest possible portion of the original image that we can size to $dest_w x $dest_h. * Note that the requested crop dimensions are used as a maximum bounding box for the original image. * If the original image's width or height is less than the requested width or height * only the greater one will be cropped. * For example when the original image is 600x300, and the requested crop dimensions are 400x400, * the resulting image will be 400x300. */ $aspect_ratio = $orig_w / $orig_h; $new_w = min( $dest_w, $orig_w ); $new_h = min( $dest_h, $orig_h );
if ( wp_fuzzy_number_match( $new_w, $orig_w ) && wp_fuzzy_number_match( $new_h, $orig_h ) ) { // The new size has virtually the same dimensions as the original image.
/** * Filters whether to proceed with making an image sub-size with identical dimensions * with the original/source image. Differences of 1px may be due to rounding and are ignored. * * @since 5.3.0 * * @param bool $proceed The filtered value. * @param int $orig_w Original image width. * @param int $orig_h Original image height. */ $proceed = (bool) apply_filters( 'wp_image_resize_identical_dimensions', false, $orig_w, $orig_h );
if ( ! $proceed ) { return false; } }
/* * The return array matches the parameters to imagecopyresampled(). * int dst_x, int dst_y, int src_x, int src_y, int dst_w, int dst_h, int src_w, int src_h */ return array( 0, 0, (int) $s_x, (int) $s_y, (int) $new_w, (int) $new_h, (int) $crop_w, (int) $crop_h ); }
/** * Resizes an image to make a thumbnail or intermediate size. * * The returned array has the file size, the image width, and image height. The * {@see 'image_make_intermediate_size'} filter can be used to hook in and change the * values of the returned array. The only parameter is the resized file path. * * @since 2.5.0 * * @param string $file File path. * @param int $width Image width. * @param int $height Image height. * @param bool|array $crop { * Optional. Image cropping behavior. If false, the image will be scaled (default). * If true, image will be cropped to the specified dimensions using center positions. * If an array, the image will be cropped using the array to specify the crop location: * * @type string $0 The x crop position. Accepts 'left' 'center', or 'right'. * @type string $1 The y crop position. Accepts 'top', 'center', or 'bottom'. * } * @return array|false Metadata array on success. False if no image was created. */ function image_make_intermediate_size( $file, $width, $height, $crop = false ) { if ( $width || $height ) { $editor = wp_get_image_editor( $file );
/** * Helper function to test if aspect ratios for two images match. * * @since 4.6.0 * * @param int $source_width Width of the first image in pixels. * @param int $source_height Height of the first image in pixels. * @param int $target_width Width of the second image in pixels. * @param int $target_height Height of the second image in pixels. * @return bool True if aspect ratios match within 1px. False if not. */ function wp_image_matches_ratio( $source_width, $source_height, $target_width, $target_height ) { /* * To test for varying crops, we constrain the dimensions of the larger image * to the dimensions of the smaller image and see if they match. */ if ( $source_width > $target_width ) { $constrained_size = wp_constrain_dimensions( $source_width, $source_height, $target_width ); $expected_size = array( $target_width, $target_height ); } else { $constrained_size = wp_constrain_dimensions( $target_width, $target_height, $source_width ); $expected_size = array( $source_width, $source_height ); }
// If the image dimensions are within 1px of the expected size, we consider it a match. $matched = ( wp_fuzzy_number_match( $constrained_size[0], $expected_size[0] ) && wp_fuzzy_number_match( $constrained_size[1], $expected_size[1] ) );
return $matched; }
/** * Retrieves the image's intermediate size (resized) path, width, and height. * * The $size parameter can be an array with the width and height respectively. * If the size matches the 'sizes' metadata array for width and height, then it * will be used. If there is no direct match, then the nearest image size larger * than the specified size will be used. If nothing is found, then the function * will break out and return false. * * The metadata 'sizes' is used for compatible sizes that can be used for the * parameter $size value. * * The url path will be given, when the $size parameter is a string. * * If you are passing an array for the $size, you should consider using * add_image_size() so that a cropped version is generated. It's much more * efficient than having to find the closest-sized image and then having the * browser scale down the image. * * @since 2.5.0 * * @param int $post_id Attachment ID. * @param string|int[] $size Optional. Image size. Accepts any registered image size name, or an array * of width and height values in pixels (in that order). Default 'thumbnail'. * @return array|false { * Array of file relative path, width, and height on success. Additionally includes absolute * path and URL if registered size is passed to `$size` parameter. False on failure. * * @type string $file Filename of image. * @type int $width Width of image in pixels. * @type int $height Height of image in pixels. * @type string $path Path of image relative to uploads directory. * @type string $url URL of image. * } */ function image_get_intermediate_size( $post_id, $size = 'thumbnail' ) { $imagedata = wp_get_attachment_metadata( $post_id );
foreach ( $imagedata['sizes'] as $_size => $data ) { // If there's an exact match to an existing image size, short circuit. if ( (int) $data['width'] === (int) $size[0] && (int) $data['height'] === (int) $size[1] ) { $candidates[ $data['width'] * $data['height'] ] = $data; break; }
// If it's not an exact match, consider larger sizes with the same aspect ratio. if ( $data['width'] >= $size[0] && $data['height'] >= $size[1] ) { // If '0' is passed to either size, we test ratios against the original file. if ( 0 === $size[0] || 0 === $size[1] ) { $same_ratio = wp_image_matches_ratio( $data['width'], $data['height'], $imagedata['width'], $imagedata['height'] ); } else { $same_ratio = wp_image_matches_ratio( $data['width'], $data['height'], $size[0], $size[1] ); }
if ( ! empty( $candidates ) ) { // Sort the array by size if we have more than one candidate. if ( 1 < count( $candidates ) ) { ksort( $candidates ); }
$data = array_shift( $candidates ); /* * When the size requested is smaller than the thumbnail dimensions, we * fall back to the thumbnail size to maintain backward compatibility with * pre 4.6 versions of WordPress. */ } elseif ( ! empty( $imagedata['sizes']['thumbnail'] ) && $imagedata['sizes']['thumbnail']['width'] >= $size[0] && $imagedata['sizes']['thumbnail']['width'] >= $size[1] ) { $data = $imagedata['sizes']['thumbnail']; } else { return false; }
// Constrain the width and height attributes to the requested values. list( $data['width'], $data['height'] ) = image_constrain_size_for_editor( $data['width'], $data['height'], $size );
// If we still don't have a match at this point, return false. if ( empty( $data ) ) { return false; }
// Include the full filesystem path of the intermediate file. if ( empty( $data['path'] ) && ! empty( $data['file'] ) && ! empty( $imagedata['file'] ) ) { $file_url = wp_get_attachment_url( $post_id ); $data['path'] = path_join( dirname( $imagedata['file'] ), $data['file'] ); $data['url'] = path_join( dirname( $file_url ), $data['file'] ); }
/** * Filters the output of image_get_intermediate_size() * * @since 4.4.0 * * @see image_get_intermediate_size() * * @param array $data Array of file relative path, width, and height on success. May also include * file absolute path and URL. * @param int $post_id The ID of the image attachment. * @param string|int[] $size Requested image size. Can be any registered image size name, or * an array of width and height values in pixels (in that order). */ return apply_filters( 'image_get_intermediate_size', $data, $post_id, $size ); }
/** * Gets the available intermediate image size names. * * @since 3.0.0 * * @return string[] An array of image size names. */ function get_intermediate_image_sizes() { $default_sizes = array( 'thumbnail', 'medium', 'medium_large', 'large' ); $additional_sizes = wp_get_additional_image_sizes();
/** * Retrieves an image to represent an attachment. * * @since 2.5.0 * * @param int $attachment_id Image attachment ID. * @param string|int[] $size Optional. Image size. Accepts any registered image size name, or an array of * width and height values in pixels (in that order). Default 'thumbnail'. * @param bool $icon Optional. Whether the image should fall back to a mime type icon. Default false. * @return array|false { * Array of image data, or boolean false if no image is available. * * @type string $0 Image source URL. * @type int $1 Image width in pixels. * @type int $2 Image height in pixels. * @type bool $3 Whether the image is a resized image. * } */ function wp_get_attachment_image_src( $attachment_id, $size = 'thumbnail', $icon = false ) { // Get a thumbnail or intermediate image if there is one. $image = image_downsize( $attachment_id, $size ); if ( ! $image ) { $src = false;
if ( '.svg' === $ext ) { // SVG does not have true dimensions, so this assigns width and height directly. $width = 48; $height = 64; } else { list( $width, $height ) = wp_getimagesize( $src_file ); } } }
if ( $src && $width && $height ) { $image = array( $src, $width, $height, false ); } } /** * Filters the attachment image source result. * * @since 4.3.0 * * @param array|false $image { * Array of image data, or boolean false if no image is available. * * @type string $0 Image source URL. * @type int $1 Image width in pixels. * @type int $2 Image height in pixels. * @type bool $3 Whether the image is a resized image. * } * @param int $attachment_id Image attachment ID. * @param string|int[] $size Requested image size. Can be any registered image size name, or * an array of width and height values in pixels (in that order). * @param bool $icon Whether the image should be treated as an icon. */ return apply_filters( 'wp_get_attachment_image_src', $image, $attachment_id, $size, $icon ); }
/** * Gets an HTML img element representing an image attachment. * * While `$size` will accept an array, it is better to register a size with * add_image_size() so that a cropped version is generated. It's much more * efficient than having to find the closest-sized image and then having the * browser scale down the image. * * @since 2.5.0 * @since 4.4.0 The `$srcset` and `$sizes` attributes were added. * @since 5.5.0 The `$loading` attribute was added. * @since 6.1.0 The `$decoding` attribute was added. * * @param int $attachment_id Image attachment ID. * @param string|int[] $size Optional. Image size. Accepts any registered image size name, or an array * of width and height values in pixels (in that order). Default 'thumbnail'. * @param bool $icon Optional. Whether the image should be treated as an icon. Default false. * @param string|array $attr { * Optional. Attributes for the image markup. * * @type string $src Image attachment URL. * @type string $class CSS class name or space-separated list of classes. * Default `attachment-$size_class size-$size_class`, * where `$size_class` is the image size being requested. * @type string $alt Image description for the alt attribute. * @type string $srcset The 'srcset' attribute value. * @type string $sizes The 'sizes' attribute value. * @type string|false $loading The 'loading' attribute value. Passing a value of false * will result in the attribute being omitted for the image. * Default determined by {@see wp_get_loading_optimization_attributes()}. * @type string $decoding The 'decoding' attribute value. Possible values are * 'async' (default), 'sync', or 'auto'. Passing false or an empty * string will result in the attribute being omitted. * @type string $fetchpriority The 'fetchpriority' attribute value, whether `high`, `low`, or `auto`. * Default determined by {@see wp_get_loading_optimization_attributes()}. * } * @return string HTML img element or empty string on failure. */ function wp_get_attachment_image( $attachment_id, $size = 'thumbnail', $icon = false, $attr = '' ) { $html = ''; $image = wp_get_attachment_image_src( $attachment_id, $size, $icon );
// Add loading optimization attributes if not available. $attr = array_merge( $attr, $loading_optimization_attr );
// Omit the `decoding` attribute if the value is invalid according to the spec. if ( empty( $attr['decoding'] ) || ! in_array( $attr['decoding'], array( 'async', 'sync', 'auto' ), true ) ) { unset( $attr['decoding'] ); }
/* * If the default value of `lazy` for the `loading` attribute is overridden * to omit the attribute for this image, ensure it is not included. */ if ( isset( $attr['loading'] ) && ! $attr['loading'] ) { unset( $attr['loading'] ); }
// If the `fetchpriority` attribute is overridden and set to false or an empty string. if ( isset( $attr['fetchpriority'] ) && ! $attr['fetchpriority'] ) { unset( $attr['fetchpriority'] ); }
// Generate 'srcset' and 'sizes' if not already present. if ( empty( $attr['srcset'] ) ) { $image_meta = wp_get_attachment_metadata( $attachment_id );
/** This filter is documented in wp-includes/media.php */ $add_auto_sizes = apply_filters( 'wp_img_tag_add_auto_sizes', true );
// Adds 'auto' to the sizes attribute if applicable. if ( $add_auto_sizes && isset( $attr['loading'] ) && 'lazy' === $attr['loading'] && isset( $attr['sizes'] ) && ! wp_sizes_attribute_includes_valid_auto( $attr['sizes'] ) ) { $attr['sizes'] = 'auto, ' . $attr['sizes']; }
/** * Filters the list of attachment image attributes. * * @since 2.8.0 * * @param string[] $attr Array of attribute values for the image markup, keyed by attribute name. * See wp_get_attachment_image(). * @param WP_Post $attachment Image attachment post. * @param string|int[] $size Requested image size. Can be any registered image size name, or * an array of width and height values in pixels (in that order). */ $attr = apply_filters( 'wp_get_attachment_image_attributes', $attr, $attachment, $size );
/** * Filters the HTML img element representing an image attachment. * * @since 5.6.0 * * @param string $html HTML img element or empty string on failure. * @param int $attachment_id Image attachment ID. * @param string|int[] $size Requested image size. Can be any registered image size name, or * an array of width and height values in pixels (in that order). * @param bool $icon Whether the image should be treated as an icon. * @param string[] $attr Array of attribute values for the image markup, keyed by attribute name. * See wp_get_attachment_image(). */ return apply_filters( 'wp_get_attachment_image', $html, $attachment_id, $size, $icon, $attr ); }
/** * Gets the URL of an image attachment. * * @since 4.4.0 * * @param int $attachment_id Image attachment ID. * @param string|int[] $size Optional. Image size. Accepts any registered image size name, or an array of * width and height values in pixels (in that order). Default 'thumbnail'. * @param bool $icon Optional. Whether the image should be treated as an icon. Default false. * @return string|false Attachment URL or false if no image is available. If `$size` does not match * any registered image size, the original image URL will be returned. */ function wp_get_attachment_image_url( $attachment_id, $size = 'thumbnail', $icon = false ) { $image = wp_get_attachment_image_src( $attachment_id, $size, $icon ); return isset( $image[0] ) ? $image[0] : false; }
/** * Gets the attachment path relative to the upload directory. * * @since 4.4.1 * @access private * * @param string $file Attachment file name. * @return string Attachment path relative to the upload directory. */ function _wp_get_attachment_relative_path( $file ) { $dirname = dirname( $file );
if ( '.' === $dirname ) { return ''; }
if ( str_contains( $dirname, 'wp-content/uploads' ) ) { // Get the directory name relative to the upload directory (back compat for pre-2.7 uploads). $dirname = substr( $dirname, strpos( $dirname, 'wp-content/uploads' ) + 18 ); $dirname = ltrim( $dirname, '/' ); }
return $dirname; }
/** * Gets the image size as array from its meta data. * * Used for responsive images. * * @since 4.4.0 * @access private * * @param string $size_name Image size. Accepts any registered image size name. * @param array $image_meta The image meta data. * @return array|false { * Array of width and height or false if the size isn't present in the meta data. * * @type int $0 Image width. * @type int $1 Image height. * } */ function _wp_get_image_size_from_meta( $size_name, $image_meta ) { if ( 'full' === $size_name ) { return array( absint( $image_meta['width'] ), absint( $image_meta['height'] ), ); } elseif ( ! empty( $image_meta['sizes'][ $size_name ] ) ) { return array( absint( $image_meta['sizes'][ $size_name ]['width'] ), absint( $image_meta['sizes'][ $size_name ]['height'] ), ); }
return false; }
/** * Retrieves the value for an image attachment's 'srcset' attribute. * * @since 4.4.0 * * @see wp_calculate_image_srcset() * * @param int $attachment_id Image attachment ID. * @param string|int[] $size Optional. Image size. Accepts any registered image size name, or an array of * width and height values in pixels (in that order). Default 'medium'. * @param array|null $image_meta Optional. The image meta data as returned by 'wp_get_attachment_metadata()'. * Default null. * @return string|false A 'srcset' value string or false. */ function wp_get_attachment_image_srcset( $attachment_id, $size = 'medium', $image_meta = null ) { $image = wp_get_attachment_image_src( $attachment_id, $size );
/** * A helper function to calculate the image sources to include in a 'srcset' attribute. * * @since 4.4.0 * * @param int[] $size_array { * An array of width and height values. * * @type int $0 The width in pixels. * @type int $1 The height in pixels. * } * @param string $image_src The 'src' of the image. * @param array $image_meta The image meta data as returned by 'wp_get_attachment_metadata()'. * @param int $attachment_id Optional. The image attachment ID. Default 0. * @return string|false The 'srcset' attribute value. False on error or when only one source exists. */ function wp_calculate_image_srcset( $size_array, $image_src, $image_meta, $attachment_id = 0 ) { /** * Pre-filters the image meta to be able to fix inconsistencies in the stored data. * * @since 4.5.0 * * @param array $image_meta The image meta data as returned by 'wp_get_attachment_metadata()'. * @param int[] $size_array { * An array of requested width and height values. * * @type int $0 The width in pixels. * @type int $1 The height in pixels. * } * @param string $image_src The 'src' of the image. * @param int $attachment_id The image attachment ID or 0 if not supplied. */ $image_meta = apply_filters( 'wp_calculate_image_srcset_meta', $image_meta, $size_array, $image_src, $attachment_id );
/* * WordPress flattens animated GIFs into one frame when generating intermediate sizes. * To avoid hiding animation in user content, if src is a full size GIF, a srcset attribute is not generated. * If src is an intermediate size GIF, the full size is excluded from srcset to keep a flattened GIF from becoming animated. */ if ( ! isset( $image_sizes['thumbnail']['mime-type'] ) || 'image/gif' !== $image_sizes['thumbnail']['mime-type'] ) { $image_sizes[] = array( 'width' => $image_meta['width'], 'height' => $image_meta['height'], 'file' => $image_basename, ); } elseif ( str_contains( $image_src, $image_meta['file'] ) ) { return false; }
// Retrieve the uploads sub-directory from the full size image. $dirname = _wp_get_attachment_relative_path( $image_meta['file'] );
/* * If currently on HTTPS, prefer HTTPS URLs when we know they're supported by the domain * (which is to say, when they share the domain name of the current request). */ if ( is_ssl() && ! str_starts_with( $image_baseurl, 'https' ) ) { /* * Since the `Host:` header might contain a port, it should * be compared against the image URL using the same port. */ $parsed = parse_url( $image_baseurl ); $domain = isset( $parsed['host'] ) ? $parsed['host'] : '';
/* * Images that have been edited in WordPress after being uploaded will * contain a unique hash. Look for that hash and use it later to filter * out images that are leftovers from previous versions. */ $image_edited = preg_match( '/-e[0-9]{13}/', wp_basename( $image_src ), $image_edit_hash );
/** * Filters the maximum image width to be included in a 'srcset' attribute. * * @since 4.4.0 * * @param int $max_width The maximum image width to be included in the 'srcset'. Default '2048'. * @param int[] $size_array { * An array of requested width and height values. * * @type int $0 The width in pixels. * @type int $1 The height in pixels. * } */ $max_srcset_image_width = apply_filters( 'max_srcset_image_width', 2048, $size_array );
// Array to hold URL candidates. $sources = array();
/** * To make sure the ID matches our image src, we will check to see if any sizes in our attachment * meta match our $image_src. If no matches are found we don't return a srcset to avoid serving * an incorrect image. See #35045. */ $src_matched = false;
/* * Loop through available images. Only use images that are resized * versions of the same edit. */ foreach ( $image_sizes as $image ) { $is_src = false;
// Check if image meta isn't corrupted. if ( ! is_array( $image ) ) { continue; }
// If the file name is part of the `src`, we've confirmed a match. if ( ! $src_matched && str_contains( $image_src, $dirname . $image['file'] ) ) { $src_matched = true; $is_src = true; }
// Filter out images that are from previous edits. if ( $image_edited && ! strpos( $image['file'], $image_edit_hash[0] ) ) { continue; }
/* * Filters out images that are wider than '$max_srcset_image_width' unless * that file is in the 'src' attribute. */ if ( $max_srcset_image_width && $image['width'] > $max_srcset_image_width && ! $is_src ) { continue; }
// If the image dimensions are within 1px of the expected size, use it. if ( wp_image_matches_ratio( $image_width, $image_height, $image['width'], $image['height'] ) ) { // Add the URL, descriptor, and value to the sources array to be returned. $source = array( 'url' => $image_baseurl . $image['file'], 'descriptor' => 'w', 'value' => $image['width'], );
// The 'src' image has to be the first in the 'srcset', because of a bug in iOS8. See #35030. if ( $is_src ) { $sources = array( $image['width'] => $source ) + $sources; } else { $sources[ $image['width'] ] = $source; } } }
/** * Filters an image's 'srcset' sources. * * @since 4.4.0 * * @param array $sources { * One or more arrays of source data to include in the 'srcset'. * * @type array $width { * @type string $url The URL of an image source. * @type string $descriptor The descriptor type used in the image candidate string, * either 'w' or 'x'. * @type int $value The source width if paired with a 'w' descriptor, or a * pixel density value if paired with an 'x' descriptor. * } * } * @param array $size_array { * An array of requested width and height values. * * @type int $0 The width in pixels. * @type int $1 The height in pixels. * } * @param string $image_src The 'src' of the image. * @param array $image_meta The image meta data as returned by 'wp_get_attachment_metadata()'. * @param int $attachment_id Image attachment ID or 0. */ $sources = apply_filters( 'wp_calculate_image_srcset', $sources, $size_array, $image_src, $image_meta, $attachment_id );
// Only return a 'srcset' value if there is more than one source. if ( ! $src_matched || ! is_array( $sources ) || count( $sources ) < 2 ) { return false; }
/** * Retrieves the value for an image attachment's 'sizes' attribute. * * @since 4.4.0 * * @see wp_calculate_image_sizes() * * @param int $attachment_id Image attachment ID. * @param string|int[] $size Optional. Image size. Accepts any registered image size name, or an array of * width and height values in pixels (in that order). Default 'medium'. * @param array|null $image_meta Optional. The image meta data as returned by 'wp_get_attachment_metadata()'. * Default null. * @return string|false A valid source size value for use in a 'sizes' attribute or false. */ function wp_get_attachment_image_sizes( $attachment_id, $size = 'medium', $image_meta = null ) { $image = wp_get_attachment_image_src( $attachment_id, $size );
/** * Creates a 'sizes' attribute value for an image. * * @since 4.4.0 * * @param string|int[] $size Image size. Accepts any registered image size name, or an array of * width and height values in pixels (in that order). * @param string|null $image_src Optional. The URL to the image file. Default null. * @param array|null $image_meta Optional. The image meta data as returned by 'wp_get_attachment_metadata()'. * Default null. * @param int $attachment_id Optional. Image attachment ID. Either `$image_meta` or `$attachment_id` * is needed when using the image size name as argument for `$size`. Default 0. * @return string|false A valid source size value for use in a 'sizes' attribute or false. */ function wp_calculate_image_sizes( $size, $image_src = null, $image_meta = null, $attachment_id = 0 ) { $width = 0;
/** * Filters the output of 'wp_calculate_image_sizes()'. * * @since 4.4.0 * * @param string $sizes A source size value for use in a 'sizes' attribute. * @param string|int[] $size Requested image size. Can be any registered image size name, or * an array of width and height values in pixels (in that order). * @param string|null $image_src The URL to the image file or null. * @param array|null $image_meta The image meta data as returned by wp_get_attachment_metadata() or null. * @param int $attachment_id Image attachment ID of the original image or 0. */ return apply_filters( 'wp_calculate_image_sizes', $sizes, $size, $image_src, $image_meta, $attachment_id ); }
/** * Determines if the image meta data is for the image source file. * * The image meta data is retrieved by attachment post ID. In some cases the post IDs may change. * For example when the website is exported and imported at another website. Then the * attachment post IDs that are in post_content for the exported website may not match * the same attachments at the new website. * * @since 5.5.0 * * @param string $image_location The full path or URI to the image file. * @param array $image_meta The attachment meta data as returned by 'wp_get_attachment_metadata()'. * @param int $attachment_id Optional. The image attachment ID. Default 0. * @return bool Whether the image meta is for this image file. */ function wp_image_file_matches_image_meta( $image_location, $image_meta, $attachment_id = 0 ) { $match = false;
// Ensure the $image_meta is valid. if ( isset( $image_meta['file'] ) && strlen( $image_meta['file'] ) > 4 ) { // Remove query args in image URI. list( $image_location ) = explode( '?', $image_location );
// Check if the relative image path from the image meta is at the end of $image_location. if ( strrpos( $image_location, $image_meta['file'] ) === strlen( $image_location ) - strlen( $image_meta['file'] ) ) { $match = true; } else { // Retrieve the uploads sub-directory from the full size image. $dirname = _wp_get_attachment_relative_path( $image_meta['file'] );
/** * Filters whether an image path or URI matches image meta. * * @since 5.5.0 * * @param bool $match Whether the image relative path from the image meta * matches the end of the URI or path to the image file. * @param string $image_location Full path or URI to the tested image file. * @param array $image_meta The image meta data as returned by 'wp_get_attachment_metadata()'. * @param int $attachment_id The image attachment ID or 0 if not supplied. */ return apply_filters( 'wp_image_file_matches_image_meta', $match, $image_location, $image_meta, $attachment_id ); }
/** * Determines an image's width and height dimensions based on the source file. * * @since 5.5.0 * * @param string $image_src The image source file. * @param array $image_meta The image meta data as returned by 'wp_get_attachment_metadata()'. * @param int $attachment_id Optional. The image attachment ID. Default 0. * @return array|false Array with first element being the width and second element being the height, * or false if dimensions cannot be determined. */ function wp_image_src_get_dimensions( $image_src, $image_meta, $attachment_id = 0 ) { $dimensions = false;
// Is it a full size image? if ( isset( $image_meta['file'] ) && str_contains( $image_src, wp_basename( $image_meta['file'] ) ) ) { $dimensions = array( (int) $image_meta['width'], (int) $image_meta['height'], ); }
/** * Filters the 'wp_image_src_get_dimensions' value. * * @since 5.7.0 * * @param array|false $dimensions Array with first element being the width * and second element being the height, or * false if dimensions could not be determined. * @param string $image_src The image source file. * @param array $image_meta The image meta data as returned by * 'wp_get_attachment_metadata()'. * @param int $attachment_id The image attachment ID. Default 0. */ return apply_filters( 'wp_image_src_get_dimensions', $dimensions, $image_src, $image_meta, $attachment_id ); }
/** * Adds 'srcset' and 'sizes' attributes to an existing 'img' element. * * @since 4.4.0 * * @see wp_calculate_image_srcset() * @see wp_calculate_image_sizes() * * @param string $image An HTML 'img' element to be filtered. * @param array $image_meta The image meta data as returned by 'wp_get_attachment_metadata()'. * @param int $attachment_id Image attachment ID. * @return string Converted 'img' element with 'srcset' and 'sizes' attributes added. */ function wp_image_add_srcset_and_sizes( $image, $image_meta, $attachment_id ) { // Ensure the image meta exists. if ( empty( $image_meta['sizes'] ) ) { return $image; }
// Return early if we couldn't get the image source. if ( ! $image_src ) { return $image; }
// Bail early if an image has been inserted and later edited. if ( preg_match( '/-e[0-9]{13}/', $image_meta['file'], $img_edit_hash ) && ! str_contains( wp_basename( $image_src ), $img_edit_hash[0] ) ) { return $image; }
// Add the srcset and sizes attributes to the image markup. return preg_replace( '/<img ([^>]+?)[\/ ]*>/', '<img $1' . $attr . ' />', $image ); }
return $image; }
/** * Determines whether to add the `loading` attribute to the specified tag in the specified context. * * @since 5.5.0 * @since 5.7.0 Now returns `true` by default for `iframe` tags. * * @param string $tag_name The tag name. * @param string $context Additional context, like the current filter name * or the function name from where this was called. * @return bool Whether to add the attribute. */ function wp_lazy_loading_enabled( $tag_name, $context ) { /* * By default add to all 'img' and 'iframe' tags. * See https://html.spec.whatwg.org/multipage/embedded-content.html#attr-img-loading * See https://html.spec.whatwg.org/multipage/iframe-embed-object.html#attr-iframe-loading */ $default = ( 'img' === $tag_name || 'iframe' === $tag_name );
/** * Filters whether to add the `loading` attribute to the specified tag in the specified context. * * @since 5.5.0 * * @param bool $default Default value. * @param string $tag_name The tag name. * @param string $context Additional context, like the current filter name * or the function name from where this was called. */ return (bool) apply_filters( 'wp_lazy_loading_enabled', $default, $tag_name, $context ); }
/** * Filters specific tags in post content and modifies their markup. * * Modifies HTML tags in post content to include new browser and HTML technologies * that may not have existed at the time of post creation. These modifications currently * include adding `srcset`, `sizes`, and `loading` attributes to `img` HTML tags, as well * as adding `loading` attributes to `iframe` HTML tags. * Future similar optimizations should be added/expected here. * * @since 5.5.0 * @since 5.7.0 Now supports adding `loading` attributes to `iframe` tags. * * @see wp_img_tag_add_width_and_height_attr() * @see wp_img_tag_add_srcset_and_sizes_attr() * @see wp_img_tag_add_loading_optimization_attrs() * @see wp_iframe_tag_add_loading_attr() * * @param string $content The HTML content to be filtered. * @param string $context Optional. Additional context to pass to the filters. * Defaults to `current_filter()` when not set. * @return string Converted content with images modified. */ function wp_filter_content_tags( $content, $context = null ) { if ( null === $context ) { $context = current_filter(); }
if ( $attachment_id ) { /* * If exactly the same image tag is used more than once, overwrite it. * All identical tags will be replaced later with 'str_replace()'. */ $images[ $tag ] = $attachment_id; break; } } $images[ $tag ] = 0; break; case 'iframe': $iframes[ $tag ] = 0; break; } }
// Reduce the array to unique attachment IDs. $attachment_ids = array_unique( array_filter( array_values( $images ) ) );
if ( count( $attachment_ids ) > 1 ) { /* * Warm the object cache with post and meta information for all found * images to avoid making individual database calls. */ _prime_post_caches( $attachment_ids, false, true ); }
// Iterate through the matches in order of occurrence as it is relevant for whether or not to lazy-load. foreach ( $matches as $match ) { // Filter an image match. if ( isset( $images[ $match[0] ] ) ) { $filtered_image = $match[0]; $attachment_id = $images[ $match[0] ];
// Adds 'auto' to the sizes attribute if applicable. $filtered_image = wp_img_tag_add_auto_sizes( $filtered_image );
/** * Filters an img tag within the content for a given context. * * @since 6.0.0 * * @param string $filtered_image Full img tag with attributes that will replace the source img tag. * @param string $context Additional context, like the current filter name or the function name from where this was called. * @param int $attachment_id The image attachment ID. May be 0 in case the image is not an attachment. */ $filtered_image = apply_filters( 'wp_content_img_tag', $filtered_image, $context, $attachment_id );
/* * Unset image lookup to not run the same logic again unnecessarily if the same image tag is used more than * once in the same blob of content. */ unset( $images[ $match[0] ] ); }
// Filter an iframe match. if ( isset( $iframes[ $match[0] ] ) ) { $filtered_iframe = $match[0];
/* * Unset iframe lookup to not run the same logic again unnecessarily if the same iframe tag is used more * than once in the same blob of content. */ unset( $iframes[ $match[0] ] ); } }
return $content; }
/** * Adds 'auto' to the sizes attribute to the image, if the image is lazy loaded and does not already include it. * * @since 6.7.0 * * @param string $image The image tag markup being filtered. * @return string The filtered image tag markup. */ function wp_img_tag_add_auto_sizes( string $image ): string { /** * Filters whether auto-sizes for lazy loaded images is enabled. * * @since 6.7.1 * * @param boolean $enabled Whether auto-sizes for lazy loaded images is enabled. */ if ( ! apply_filters( 'wp_img_tag_add_auto_sizes', true ) ) { return $image; }
$processor = new WP_HTML_Tag_Processor( $image );
// Bail if there is no IMG tag. if ( ! $processor->next_tag( array( 'tag_name' => 'IMG' ) ) ) { return $image; }
// Bail early if the image is not lazy-loaded. $loading = $processor->get_attribute( 'loading' ); if ( ! is_string( $loading ) || 'lazy' !== strtolower( trim( $loading, " \t\f\r\n" ) ) ) { return $image; }
/* * Bail early if the image doesn't have a width attribute. * Per WordPress Core itself, lazy-loaded images should always have a width attribute. * However, it is possible that lazy-loading could be added by a plugin, where we don't have that guarantee. * As such, it still makes sense to ensure presence of a width attribute here in order to use `sizes=auto`. */ $width = $processor->get_attribute( 'width' ); if ( ! is_string( $width ) || '' === $width ) { return $image; }
$sizes = $processor->get_attribute( 'sizes' );
// Bail early if the image is not responsive. if ( ! is_string( $sizes ) ) { return $image; }
// Don't add 'auto' to the sizes attribute if it already exists. if ( wp_sizes_attribute_includes_valid_auto( $sizes ) ) { return $image; }
/** * Checks whether the given 'sizes' attribute includes the 'auto' keyword as the first item in the list. * * Per the HTML spec, if present it must be the first entry. * * @since 6.7.0 * * @param string $sizes_attr The 'sizes' attribute value. * @return bool True if the 'auto' keyword is present, false otherwise. */ function wp_sizes_attribute_includes_valid_auto( string $sizes_attr ): bool { list( $first_size ) = explode( ',', $sizes_attr, 2 ); return 'auto' === strtolower( trim( $first_size, " \t\f\r\n" ) ); }
/** * Prints a CSS rule to fix potential visual issues with images using `sizes=auto`. * * This rule overrides the similar rule in the default user agent stylesheet, to avoid images that use e.g. * `width: auto` or `width: fit-content` to appear smaller. * * @since 6.7.1 * @see https://html.spec.whatwg.org/multipage/rendering.html#img-contain-size * @see https://core.trac.wordpress.org/ticket/62413 */ function wp_print_auto_sizes_contain_css_fix() { /** This filter is documented in wp-includes/media.php */ $add_auto_sizes = apply_filters( 'wp_img_tag_add_auto_sizes', true ); if ( ! $add_auto_sizes ) { return; }
/** * Adds optimization attributes to an `img` HTML tag. * * @since 6.3.0 * * @param string $image The HTML `img` tag where the attribute should be added. * @param string $context Additional context to pass to the filters. * @return string Converted `img` tag with optimization attributes added. */ function wp_img_tag_add_loading_optimization_attrs( $image, $context ) { $src = preg_match( '/ src=["\']?([^"\']*)/i', $image, $matche_src ) ? $matche_src[1] : null; $width = preg_match( '/ width=["\']([0-9]+)["\']/', $image, $match_width ) ? (int) $match_width[1] : null; $height = preg_match( '/ height=["\']([0-9]+)["\']/', $image, $match_height ) ? (int) $match_height[1] : null; $loading_val = preg_match( '/ loading=["\']([A-Za-z]+)["\']/', $image, $match_loading ) ? $match_loading[1] : null; $fetchpriority_val = preg_match( '/ fetchpriority=["\']([A-Za-z]+)["\']/', $image, $match_fetchpriority ) ? $match_fetchpriority[1] : null; $decoding_val = preg_match( '/ decoding=["\']([A-Za-z]+)["\']/', $image, $match_decoding ) ? $match_decoding[1] : null;
/* * Get loading optimization attributes to use. * This must occur before the conditional check below so that even images * that are ineligible for being lazy-loaded are considered. */ $optimization_attrs = wp_get_loading_optimization_attributes( 'img', array( 'src' => $src, 'width' => $width, 'height' => $height, 'loading' => $loading_val, 'fetchpriority' => $fetchpriority_val, 'decoding' => $decoding_val, ), $context );
// Images should have source for the loading optimization attributes to be added. if ( ! str_contains( $image, ' src="' ) ) { return $image; }
if ( empty( $decoding_val ) ) { /** * Filters the `decoding` attribute value to add to an image. Default `async`. * * Returning a falsey value will omit the attribute. * * @since 6.1.0 * * @param string|false|null $value The `decoding` attribute value. Returning a falsey value * will result in the attribute being omitted for the image. * Otherwise, it may be: 'async', 'sync', or 'auto'. Defaults to false. * @param string $image The HTML `img` tag to be filtered. * @param string $context Additional context about how the function was called * or where the img tag is. */ $filtered_decoding_attr = apply_filters( 'wp_img_tag_add_decoding_attr', isset( $optimization_attrs['decoding'] ) ? $optimization_attrs['decoding'] : false, $image, $context );
// Validate the values after filtering. if ( isset( $optimization_attrs['decoding'] ) && ! $filtered_decoding_attr ) { // Unset `decoding` attribute if `$filtered_decoding_attr` is set to `false`. unset( $optimization_attrs['decoding'] ); } elseif ( in_array( $filtered_decoding_attr, array( 'async', 'sync', 'auto' ), true ) ) { $optimization_attrs['decoding'] = $filtered_decoding_attr; }
// Images should have dimension attributes for the 'loading' and 'fetchpriority' attributes to be added. if ( ! str_contains( $image, ' width="' ) || ! str_contains( $image, ' height="' ) ) { return $image; }
if ( empty( $loading_val ) && $loading_attrs_enabled ) { /** * Filters the `loading` attribute value to add to an image. Default `lazy`. * * Returning `false` or an empty string will not add the attribute. * Returning `true` will add the default value. * * @since 5.5.0 * * @param string|bool $value The `loading` attribute value. Returning a falsey value will result in * the attribute being omitted for the image. * @param string $image The HTML `img` tag to be filtered. * @param string $context Additional context about how the function was called or where the img tag is. */ $filtered_loading_attr = apply_filters( 'wp_img_tag_add_loading_attr', isset( $optimization_attrs['loading'] ) ? $optimization_attrs['loading'] : false, $image, $context );
// Validate the values after filtering. if ( isset( $optimization_attrs['loading'] ) && ! $filtered_loading_attr ) { // Unset `loading` attributes if `$filtered_loading_attr` is set to `false`. unset( $optimization_attrs['loading'] ); } elseif ( in_array( $filtered_loading_attr, array( 'lazy', 'eager' ), true ) ) { /* * If the filter changed the loading attribute to "lazy" when a fetchpriority attribute * with value "high" is already present, trigger a warning since those two attribute * values should be mutually exclusive. * * The same warning is present in `wp_get_loading_optimization_attributes()`, and here it * is only intended for the specific scenario where the above filtered caused the problem. */ if ( isset( $optimization_attrs['fetchpriority'] ) && 'high' === $optimization_attrs['fetchpriority'] && ( isset( $optimization_attrs['loading'] ) ? $optimization_attrs['loading'] : false ) !== $filtered_loading_attr && 'lazy' === $filtered_loading_attr ) { _doing_it_wrong( __FUNCTION__, __( 'An image should not be lazy-loaded and marked as high priority at the same time.' ), '6.3.0' ); }
// The filtered value will still be respected. $optimization_attrs['loading'] = $filtered_loading_attr; }
/** * Adds `width` and `height` attributes to an `img` HTML tag. * * @since 5.5.0 * * @param string $image The HTML `img` tag where the attribute should be added. * @param string $context Additional context to pass to the filters. * @param int $attachment_id Image attachment ID. * @return string Converted 'img' element with 'width' and 'height' attributes added. */ function wp_img_tag_add_width_and_height_attr( $image, $context, $attachment_id ) { $image_src = preg_match( '/src="([^"]+)"/', $image, $match_src ) ? $match_src[1] : ''; list( $image_src ) = explode( '?', $image_src );
// Return early if we couldn't get the image source. if ( ! $image_src ) { return $image; }
/** * Filters whether to add the missing `width` and `height` HTML attributes to the img tag. Default `true`. * * Returning anything else than `true` will not add the attributes. * * @since 5.5.0 * * @param bool $value The filtered value, defaults to `true`. * @param string $image The HTML `img` tag where the attribute should be added. * @param string $context Additional context about how the function was called or where the img tag is. * @param int $attachment_id The image attachment ID. */ $add = apply_filters( 'wp_img_tag_add_width_and_height_attr', true, $image, $context, $attachment_id );
/** * Adds `srcset` and `sizes` attributes to an existing `img` HTML tag. * * @since 5.5.0 * * @param string $image The HTML `img` tag where the attribute should be added. * @param string $context Additional context to pass to the filters. * @param int $attachment_id Image attachment ID. * @return string Converted 'img' element with 'loading' attribute added. */ function wp_img_tag_add_srcset_and_sizes_attr( $image, $context, $attachment_id ) { /** * Filters whether to add the `srcset` and `sizes` HTML attributes to the img tag. Default `true`. * * Returning anything else than `true` will not add the attributes. * * @since 5.5.0 * * @param bool $value The filtered value, defaults to `true`. * @param string $image The HTML `img` tag where the attribute should be added. * @param string $context Additional context about how the function was called or where the img tag is. * @param int $attachment_id The image attachment ID. */ $add = apply_filters( 'wp_img_tag_add_srcset_and_sizes_attr', true, $image, $context, $attachment_id );
/** * Adds `loading` attribute to an `iframe` HTML tag. * * @since 5.7.0 * * @param string $iframe The HTML `iframe` tag where the attribute should be added. * @param string $context Additional context to pass to the filters. * @return string Converted `iframe` tag with `loading` attribute added. */ function wp_iframe_tag_add_loading_attr( $iframe, $context ) { /* * Get loading attribute value to use. This must occur before the conditional check below so that even iframes that * are ineligible for being lazy-loaded are considered. */ $optimization_attrs = wp_get_loading_optimization_attributes( 'iframe', array( /* * The concrete values for width and height are not important here for now * since fetchpriority is not yet supported for iframes. * TODO: Use WP_HTML_Tag_Processor to extract actual values once support is * added. */ 'width' => str_contains( $iframe, ' width="' ) ? 100 : null, 'height' => str_contains( $iframe, ' height="' ) ? 100 : null, // This function is never called when a 'loading' attribute is already present. 'loading' => null, ), $context );
// Iframes should have source and dimension attributes for the `loading` attribute to be added. if ( ! str_contains( $iframe, ' src="' ) || ! str_contains( $iframe, ' width="' ) || ! str_contains( $iframe, ' height="' ) ) { return $iframe; }
/** * Filters the `loading` attribute value to add to an iframe. Default `lazy`. * * Returning `false` or an empty string will not add the attribute. * Returning `true` will add the default value. * * @since 5.7.0 * * @param string|bool $value The `loading` attribute value. Returning a falsey value will result in * the attribute being omitted for the iframe. * @param string $iframe The HTML `iframe` tag to be filtered. * @param string $context Additional context about how the function was called or where the iframe tag is. */ $value = apply_filters( 'wp_iframe_tag_add_loading_attr', $value, $iframe, $context );
/** * Adds a 'wp-post-image' class to post thumbnails. Internal use only. * * Uses the {@see 'begin_fetch_post_thumbnail_html'} and {@see 'end_fetch_post_thumbnail_html'} * action hooks to dynamically add/remove itself so as to only filter post thumbnails. * * @ignore * @since 2.9.0 * * @param string[] $attr Array of thumbnail attributes including src, class, alt, title, keyed by attribute name. * @return string[] Modified array of attributes including the new 'wp-post-image' class. */ function _wp_post_thumbnail_class_filter( $attr ) { $attr['class'] .= ' wp-post-image'; return $attr; }
/** * Adds '_wp_post_thumbnail_class_filter' callback to the 'wp_get_attachment_image_attributes' * filter hook. Internal use only. * * @ignore * @since 2.9.0 * * @param string[] $attr Array of thumbnail attributes including src, class, alt, title, keyed by attribute name. */ function _wp_post_thumbnail_class_filter_add( $attr ) { add_filter( 'wp_get_attachment_image_attributes', '_wp_post_thumbnail_class_filter' ); }
/** * Removes the '_wp_post_thumbnail_class_filter' callback from the 'wp_get_attachment_image_attributes' * filter hook. Internal use only. * * @ignore * @since 2.9.0 * * @param string[] $attr Array of thumbnail attributes including src, class, alt, title, keyed by attribute name. */ function _wp_post_thumbnail_class_filter_remove( $attr ) { remove_filter( 'wp_get_attachment_image_attributes', '_wp_post_thumbnail_class_filter' ); }
/** * Overrides the context used in {@see wp_get_attachment_image()}. Internal use only. * * Uses the {@see 'begin_fetch_post_thumbnail_html'} and {@see 'end_fetch_post_thumbnail_html'} * action hooks to dynamically add/remove itself so as to only filter post thumbnails. * * @ignore * @since 6.3.0 * @access private * * @param string $context The context for rendering an attachment image. * @return string Modified context set to 'the_post_thumbnail'. */ function _wp_post_thumbnail_context_filter( $context ) { return 'the_post_thumbnail'; }
/** * Adds the '_wp_post_thumbnail_context_filter' callback to the 'wp_get_attachment_image_context' * filter hook. Internal use only. * * @ignore * @since 6.3.0 * @access private */ function _wp_post_thumbnail_context_filter_add() { add_filter( 'wp_get_attachment_image_context', '_wp_post_thumbnail_context_filter' ); }
/** * Removes the '_wp_post_thumbnail_context_filter' callback from the 'wp_get_attachment_image_context' * filter hook. Internal use only. * * @ignore * @since 6.3.0 * @access private */ function _wp_post_thumbnail_context_filter_remove() { remove_filter( 'wp_get_attachment_image_context', '_wp_post_thumbnail_context_filter' ); }
/** * Builds the Caption shortcode output. * * Allows a plugin to replace the content that would otherwise be returned. The * filter is {@see 'img_caption_shortcode'} and passes an empty string, the attr * parameter and the content parameter values. * * The supported attributes for the shortcode are 'id', 'caption_id', 'align', * 'width', 'caption', and 'class'. * * @since 2.6.0 * @since 3.9.0 The `class` attribute was added. * @since 5.1.0 The `caption_id` attribute was added. * @since 5.9.0 The `$content` parameter default value changed from `null` to `''`. * * @param array $attr { * Attributes of the caption shortcode. * * @type string $id ID of the image and caption container element, i.e. `<figure>` or `<div>`. * @type string $caption_id ID of the caption element, i.e. `<figcaption>` or `<p>`. * @type string $align Class name that aligns the caption. Default 'alignnone'. Accepts 'alignleft', * 'aligncenter', alignright', 'alignnone'. * @type int $width The width of the caption, in pixels. * @type string $caption The caption text. * @type string $class Additional class name(s) added to the caption container. * } * @param string $content Optional. Shortcode content. Default empty string. * @return string HTML content to display the caption. */ function img_caption_shortcode( $attr, $content = '' ) { // New-style shortcode with the caption inside the shortcode with the link and image tags. if ( ! isset( $attr['caption'] ) ) { if ( preg_match( '#((?:<a [^>]+>\s*)?<img [^>]+>(?:\s*</a>)?)(.*)#is', $content, $matches ) ) { $content = $matches[1]; $attr['caption'] = trim( $matches[2] ); } } elseif ( str_contains( $attr['caption'], '<' ) ) { $attr['caption'] = wp_kses( $attr['caption'], 'post' ); }
/** * Filters the default caption shortcode output. * * If the filtered output isn't empty, it will be used instead of generating * the default caption template. * * @since 2.6.0 * * @see img_caption_shortcode() * * @param string $output The caption output. Default empty. * @param array $attr Attributes of the caption shortcode. * @param string $content The image element, possibly wrapped in a hyperlink. */ $output = apply_filters( 'img_caption_shortcode', '', $attr, $content );
$html5 = current_theme_supports( 'html5', 'caption' ); // HTML5 captions never added the extra 10px to the image width. $width = $html5 ? $atts['width'] : ( 10 + $atts['width'] );
/** * Filters the width of an image's caption. * * By default, the caption is 10 pixels greater than the width of the image, * to prevent post content from running up against a floated image. * * @since 3.7.0 * * @see img_caption_shortcode() * * @param int $width Width of the caption in pixels. To remove this inline style, * return zero. * @param array $atts Attributes of the caption shortcode. * @param string $content The image element, possibly wrapped in a hyperlink. */ $caption_width = apply_filters( 'img_caption_shortcode_width', $width, $atts, $content );
/** * Builds the Gallery shortcode output. * * This implements the functionality of the Gallery Shortcode for displaying * WordPress images on a post. * * @since 2.5.0 * @since 2.8.0 Added the `$attr` parameter to set the shortcode output. New attributes included * such as `size`, `itemtag`, `icontag`, `captiontag`, and columns. Changed markup from * `div` tags to `dl`, `dt` and `dd` tags. Support more than one gallery on the * same page. * @since 2.9.0 Added support for `include` and `exclude` to shortcode. * @since 3.5.0 Use get_post() instead of global `$post`. Handle mapping of `ids` to `include` * and `orderby`. * @since 3.6.0 Added validation for tags used in gallery shortcode. Add orientation information to items. * @since 3.7.0 Introduced the `link` attribute. * @since 3.9.0 `html5` gallery support, accepting 'itemtag', 'icontag', and 'captiontag' attributes. * @since 4.0.0 Removed use of `extract()`. * @since 4.1.0 Added attribute to `wp_get_attachment_link()` to output `aria-describedby`. * @since 4.2.0 Passed the shortcode instance ID to `post_gallery` and `post_playlist` filters. * @since 4.6.0 Standardized filter docs to match documentation standards for PHP. * @since 5.1.0 Code cleanup for WPCS 1.0.0 coding standards. * @since 5.3.0 Saved progress of intermediate image creation after upload. * @since 5.5.0 Ensured that galleries can be output as a list of links in feeds. * @since 5.6.0 Replaced order-style PHP type conversion functions with typecasts. Fix logic for * an array of image dimensions. * * @param array $attr { * Attributes of the gallery shortcode. * * @type string $order Order of the images in the gallery. Default 'ASC'. Accepts 'ASC', 'DESC'. * @type string $orderby The field to use when ordering the images. Default 'menu_order ID'. * Accepts any valid SQL ORDERBY statement. * @type int $id Post ID. * @type string $itemtag HTML tag to use for each image in the gallery. * Default 'dl', or 'figure' when the theme registers HTML5 gallery support. * @type string $icontag HTML tag to use for each image's icon. * Default 'dt', or 'div' when the theme registers HTML5 gallery support. * @type string $captiontag HTML tag to use for each image's caption. * Default 'dd', or 'figcaption' when the theme registers HTML5 gallery support. * @type int $columns Number of columns of images to display. Default 3. * @type string|int[] $size Size of the images to display. Accepts any registered image size name, or an array * of width and height values in pixels (in that order). Default 'thumbnail'. * @type string $ids A comma-separated list of IDs of attachments to display. Default empty. * @type string $include A comma-separated list of IDs of attachments to include. Default empty. * @type string $exclude A comma-separated list of IDs of attachments to exclude. Default empty. * @type string $link What to link each image to. Default empty (links to the attachment page). * Accepts 'file', 'none'. * } * @return string HTML content to display gallery. */ function gallery_shortcode( $attr ) { $post = get_post();
static $instance = 0; ++$instance;
if ( ! empty( $attr['ids'] ) ) { // 'ids' is explicitly ordered, unless you specify otherwise. if ( empty( $attr['orderby'] ) ) { $attr['orderby'] = 'post__in'; } $attr['include'] = $attr['ids']; }
/** * Filters the default gallery shortcode output. * * If the filtered output isn't empty, it will be used instead of generating * the default gallery template. * * @since 2.5.0 * @since 4.2.0 The `$instance` parameter was added. * * @see gallery_shortcode() * * @param string $output The gallery output. Default empty. * @param array $attr Attributes of the gallery shortcode. * @param int $instance Unique numeric ID of this gallery shortcode instance. */ $output = apply_filters( 'post_gallery', '', $attr, $instance );
// Terminate the shortcode execution if the user cannot read the post or it is password-protected. if ( ! is_post_publicly_viewable( $post_parent->ID ) && ! current_user_can( 'read_post', $post_parent->ID ) || post_password_required( $post_parent ) ) { return ''; } }
/** * Outputs and enqueues default scripts and styles for playlists. * * @since 3.9.0 * * @param string $type Type of playlist. Accepts 'audio' or 'video'. */ function wp_playlist_scripts( $type ) { wp_enqueue_style( 'wp-mediaelement' ); wp_enqueue_script( 'wp-playlist' ); ?> <!--[if lt IE 9]><script>document.createElement('<?php echo esc_js( $type ); ?>');</script><![endif]--> <?php add_action( 'wp_footer', 'wp_underscore_playlist_templates', 0 ); add_action( 'admin_footer', 'wp_underscore_playlist_templates', 0 ); }
/** * Builds the Playlist shortcode output. * * This implements the functionality of the playlist shortcode for displaying * a collection of WordPress audio or video files in a post. * * @since 3.9.0 * * @global int $content_width * * @param array $attr { * Array of default playlist attributes. * * @type string $type Type of playlist to display. Accepts 'audio' or 'video'. Default 'audio'. * @type string $order Designates ascending or descending order of items in the playlist. * Accepts 'ASC', 'DESC'. Default 'ASC'. * @type string $orderby Any column, or columns, to sort the playlist. If $ids are * passed, this defaults to the order of the $ids array ('post__in'). * Otherwise default is 'menu_order ID'. * @type int $id If an explicit $ids array is not present, this parameter * will determine which attachments are used for the playlist. * Default is the current post ID. * @type array $ids Create a playlist out of these explicit attachment IDs. If empty, * a playlist will be created from all $type attachments of $id. * Default empty. * @type array $exclude List of specific attachment IDs to exclude from the playlist. Default empty. * @type string $style Playlist style to use. Accepts 'light' or 'dark'. Default 'light'. * @type bool $tracklist Whether to show or hide the playlist. Default true. * @type bool $tracknumbers Whether to show or hide the numbers next to entries in the playlist. Default true. * @type bool $images Show or hide the video or audio thumbnail (Featured Image/post * thumbnail). Default true. * @type bool $artists Whether to show or hide artist name in the playlist. Default true. * } * * @return string Playlist output. Empty string if the passed type is unsupported. */ function wp_playlist_shortcode( $attr ) { global $content_width; $post = get_post();
static $instance = 0; ++$instance;
if ( ! empty( $attr['ids'] ) ) { // 'ids' is explicitly ordered, unless you specify otherwise. if ( empty( $attr['orderby'] ) ) { $attr['orderby'] = 'post__in'; } $attr['include'] = $attr['ids']; }
/** * Filters the playlist output. * * Returning a non-empty value from the filter will short-circuit generation * of the default playlist output, returning the passed value instead. * * @since 3.9.0 * @since 4.2.0 The `$instance` parameter was added. * * @param string $output Playlist output. Default empty. * @param array $attr An array of shortcode attributes. * @param int $instance Unique numeric ID of this playlist shortcode instance. */ $output = apply_filters( 'post_playlist', '', $attr, $instance );
// Terminate the shortcode execution if the user cannot read the post or it is password-protected. if ( ! current_user_can( 'read_post', $post_parent->ID ) || post_password_required( $post_parent ) ) { return ''; } }
/** * Filters the editable list of keys to look up data from an attachment's metadata. * * @since 3.9.0 * * @param array $fields Key/value pairs of field keys to labels. * @param WP_Post $attachment Attachment object. * @param string $context The context. Accepts 'edit', 'display'. Default 'display'. */ return apply_filters( 'wp_get_attachment_id3_keys', $fields, $attachment, $context ); } /** * Builds the Audio shortcode output. * * This implements the functionality of the Audio Shortcode for displaying * WordPress mp3s in a post. * * @since 3.6.0 * * @param array $attr { * Attributes of the audio shortcode. * * @type string $src URL to the source of the audio file. Default empty. * @type string $loop The 'loop' attribute for the `<audio>` element. Default empty. * @type string $autoplay The 'autoplay' attribute for the `<audio>` element. Default empty. * @type string $preload The 'preload' attribute for the `<audio>` element. Default 'none'. * @type string $class The 'class' attribute for the `<audio>` element. Default 'wp-audio-shortcode'. * @type string $style The 'style' attribute for the `<audio>` element. Default 'width: 100%;'. * } * @param string $content Shortcode content. * @return string|void HTML content to display audio. */ function wp_audio_shortcode( $attr, $content = '' ) { $post_id = get_post() ? get_the_ID() : 0;
static $instance = 0; ++$instance;
/** * Filters the default audio shortcode output. * * If the filtered output isn't empty, it will be used instead of generating the default audio template. * * @since 3.6.0 * * @param string $html Empty variable to be replaced with shortcode markup. * @param array $attr Attributes of the shortcode. See {@see wp_audio_shortcode()}. * @param string $content Shortcode content. * @param int $instance Unique numeric ID of this audio shortcode instance. */ $override = apply_filters( 'wp_audio_shortcode_override', '', $attr, $content, $instance );
/** * Filters the media library used for the audio shortcode. * * @since 3.6.0 * * @param string $library Media library used for the audio shortcode. */ $library = apply_filters( 'wp_audio_shortcode_library', 'mediaelement' );
/** * Filters the class attribute for the audio shortcode output container. * * @since 3.6.0 * @since 4.9.0 The `$atts` parameter was added. * * @param string $class CSS class or list of space-separated classes. * @param array $atts Array of audio shortcode attributes. */ $atts['class'] = apply_filters( 'wp_audio_shortcode_class', $atts['class'], $atts );
// These ones should just be omitted altogether if they are blank. foreach ( array( 'loop', 'autoplay', 'preload' ) as $a ) { if ( empty( $html_atts[ $a ] ) ) { unset( $html_atts[ $a ] ); } }
/** * Filters the audio shortcode output. * * @since 3.6.0 * * @param string $html Audio shortcode HTML output. * @param array $atts Array of audio shortcode attributes. * @param string $audio Audio file. * @param int $post_id Post ID. * @param string $library Media library used for the audio shortcode. */ return apply_filters( 'wp_audio_shortcode', $html, $atts, $audio, $post_id, $library ); } add_shortcode( 'audio', 'wp_audio_shortcode' );
/** * Returns a filtered list of supported video formats. * * @since 3.6.0 * * @return string[] List of supported video formats. */ function wp_get_video_extensions() { /** * Filters the list of supported video formats. * * @since 3.6.0 * * @param string[] $extensions An array of supported video formats. Defaults are * 'mp4', 'm4v', 'webm', 'ogv', 'flv'. */ return apply_filters( 'wp_video_extensions', array( 'mp4', 'm4v', 'webm', 'ogv', 'flv' ) ); }
/** * Builds the Video shortcode output. * * This implements the functionality of the Video Shortcode for displaying * WordPress mp4s in a post. * * @since 3.6.0 * * @global int $content_width * * @param array $attr { * Attributes of the shortcode. * * @type string $src URL to the source of the video file. Default empty. * @type int $height Height of the video embed in pixels. Default 360. * @type int $width Width of the video embed in pixels. Default $content_width or 640. * @type string $poster The 'poster' attribute for the `<video>` element. Default empty. * @type string $loop The 'loop' attribute for the `<video>` element. Default empty. * @type string $autoplay The 'autoplay' attribute for the `<video>` element. Default empty. * @type string $muted The 'muted' attribute for the `<video>` element. Default false. * @type string $preload The 'preload' attribute for the `<video>` element. * Default 'metadata'. * @type string $class The 'class' attribute for the `<video>` element. * Default 'wp-video-shortcode'. * } * @param string $content Shortcode content. * @return string|void HTML content to display video. */ function wp_video_shortcode( $attr, $content = '' ) { global $content_width; $post_id = get_post() ? get_the_ID() : 0;
static $instance = 0; ++$instance;
/** * Filters the default video shortcode output. * * If the filtered output isn't empty, it will be used instead of generating * the default video template. * * @since 3.6.0 * * @see wp_video_shortcode() * * @param string $html Empty variable to be replaced with shortcode markup. * @param array $attr Attributes of the shortcode. See {@see wp_video_shortcode()}. * @param string $content Video shortcode content. * @param int $instance Unique numeric ID of this video shortcode instance. */ $override = apply_filters( 'wp_video_shortcode_override', '', $attr, $content, $instance );
/** * Filters the media library used for the video shortcode. * * @since 3.6.0 * * @param string $library Media library used for the video shortcode. */ $library = apply_filters( 'wp_video_shortcode_library', 'mediaelement' ); if ( 'mediaelement' === $library && did_action( 'init' ) ) { wp_enqueue_style( 'wp-mediaelement' ); wp_enqueue_script( 'wp-mediaelement' ); wp_enqueue_script( 'mediaelement-vimeo' ); }
/* * MediaElement.js has issues with some URL formats for Vimeo and YouTube, * so update the URL to prevent the ME.js player from breaking. */ if ( 'mediaelement' === $library ) { if ( $is_youtube ) { // Remove `feature` query arg and force SSL - see #40866. $atts['src'] = remove_query_arg( 'feature', $atts['src'] ); $atts['src'] = set_url_scheme( $atts['src'], 'https' ); } elseif ( $is_vimeo ) { // Remove all query arguments and force SSL - see #40866. $parsed_vimeo_url = wp_parse_url( $atts['src'] ); $vimeo_src = 'https://' . $parsed_vimeo_url['host'] . $parsed_vimeo_url['path'];
// Add loop param for mejs bug - see #40977, not needed after #39686. $loop = $atts['loop'] ? '1' : '0'; $atts['src'] = add_query_arg( 'loop', $loop, $vimeo_src ); } }
/** * Filters the class attribute for the video shortcode output container. * * @since 3.6.0 * @since 4.9.0 The `$atts` parameter was added. * * @param string $class CSS class or list of space-separated classes. * @param array $atts Array of video shortcode attributes. */ $atts['class'] = apply_filters( 'wp_video_shortcode_class', $atts['class'], $atts );
// These ones should just be omitted altogether if they are blank. foreach ( array( 'poster', 'loop', 'autoplay', 'preload', 'muted' ) as $a ) { if ( empty( $html_atts[ $a ] ) ) { unset( $html_atts[ $a ] ); } }
/** * Filters the output of the video shortcode. * * @since 3.6.0 * * @param string $output Video shortcode HTML output. * @param array $atts Array of video shortcode attributes. * @param string $video Video file. * @param int $post_id Post ID. * @param string $library Media library used for the video shortcode. */ return apply_filters( 'wp_video_shortcode', $output, $atts, $video, $post_id, $library ); } add_shortcode( 'video', 'wp_video_shortcode' );
/** * Gets the previous image link that has the same post parent. * * @since 5.8.0 * * @see get_adjacent_image_link() * * @param string|int[] $size Optional. Image size. Accepts any registered image size name, or an array * of width and height values in pixels (in that order). Default 'thumbnail'. * @param string|false $text Optional. Link text. Default false. * @return string Markup for previous image link. */ function get_previous_image_link( $size = 'thumbnail', $text = false ) { return get_adjacent_image_link( true, $size, $text ); }
/** * Displays previous image link that has the same post parent. * * @since 2.5.0 * * @param string|int[] $size Optional. Image size. Accepts any registered image size name, or an array * of width and height values in pixels (in that order). Default 'thumbnail'. * @param string|false $text Optional. Link text. Default false. */ function previous_image_link( $size = 'thumbnail', $text = false ) { echo get_previous_image_link( $size, $text ); }
/** * Gets the next image link that has the same post parent. * * @since 5.8.0 * * @see get_adjacent_image_link() * * @param string|int[] $size Optional. Image size. Accepts any registered image size name, or an array * of width and height values in pixels (in that order). Default 'thumbnail'. * @param string|false $text Optional. Link text. Default false. * @return string Markup for next image link. */ function get_next_image_link( $size = 'thumbnail', $text = false ) { return get_adjacent_image_link( false, $size, $text ); }
/** * Displays next image link that has the same post parent. * * @since 2.5.0 * * @param string|int[] $size Optional. Image size. Accepts any registered image size name, or an array * of width and height values in pixels (in that order). Default 'thumbnail'. * @param string|false $text Optional. Link text. Default false. */ function next_image_link( $size = 'thumbnail', $text = false ) { echo get_next_image_link( $size, $text ); }
/** * Gets the next or previous image link that has the same post parent. * * Retrieves the current attachment object from the $post global. * * @since 5.8.0 * * @param bool $prev Optional. Whether to display the next (false) or previous (true) link. Default true. * @param string|int[] $size Optional. Image size. Accepts any registered image size name, or an array * of width and height values in pixels (in that order). Default 'thumbnail'. * @param bool $text Optional. Link text. Default false. * @return string Markup for image link. */ function get_adjacent_image_link( $prev = true, $size = 'thumbnail', $text = false ) { $post = get_post(); $attachments = array_values( get_children( array( 'post_parent' => $post->post_parent, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => 'ASC', 'orderby' => 'menu_order ID', ) ) );
/** * Filters the adjacent image link. * * The dynamic portion of the hook name, `$adjacent`, refers to the type of adjacency, * either 'next', or 'previous'. * * Possible hook names include: * * - `next_image_link` * - `previous_image_link` * * @since 3.5.0 * * @param string $output Adjacent image HTML markup. * @param int $attachment_id Attachment ID * @param string|int[] $size Requested image size. Can be any registered image size name, or * an array of width and height values in pixels (in that order). * @param string $text Link text. */ return apply_filters( "{$adjacent}_image_link", $output, $attachment_id, $size, $text ); }
/** * Displays next or previous image link that has the same post parent. * * Retrieves the current attachment object from the $post global. * * @since 2.5.0 * * @param bool $prev Optional. Whether to display the next (false) or previous (true) link. Default true. * @param string|int[] $size Optional. Image size. Accepts any registered image size name, or an array * of width and height values in pixels (in that order). Default 'thumbnail'. * @param bool $text Optional. Link text. Default false. */ function adjacent_image_link( $prev = true, $size = 'thumbnail', $text = false ) { echo get_adjacent_image_link( $prev, $size, $text ); }
/** * Retrieves taxonomies attached to given the attachment. * * @since 2.5.0 * @since 4.7.0 Introduced the `$output` parameter. * * @param int|array|object $attachment Attachment ID, data array, or data object. * @param string $output Output type. 'names' to return an array of taxonomy names, * or 'objects' to return an array of taxonomy objects. * Default is 'names'. * @return string[]|WP_Taxonomy[] List of taxonomies or taxonomy names. Empty array on failure. */ function get_attachment_taxonomies( $attachment, $output = 'names' ) { if ( is_int( $attachment ) ) { $attachment = get_post( $attachment ); } elseif ( is_array( $attachment ) ) { $attachment = (object) $attachment; }
/** * Retrieves all of the taxonomies that are registered for attachments. * * Handles mime-type-specific taxonomies such as attachment:image and attachment:video. * * @since 3.5.0 * * @see get_taxonomies() * * @param string $output Optional. The type of taxonomy output to return. Accepts 'names' or 'objects'. * Default 'names'. * @return string[]|WP_Taxonomy[] Array of names or objects of registered taxonomies for attachments. */ function get_taxonomies_for_attachments( $output = 'names' ) { $taxonomies = array();
/** * Determines whether the value is an acceptable type for GD image functions. * * In PHP 8.0, the GD extension uses GdImage objects for its data structures. * This function checks if the passed value is either a GdImage object instance * or a resource of type `gd`. Any other type will return false. * * @since 5.6.0 * * @param resource|GdImage|false $image A value to check the type for. * @return bool True if `$image` is either a GD image resource or a GdImage instance, * false otherwise. */ function is_gd_image( $image ) { if ( $image instanceof GdImage || is_resource( $image ) && 'gd' === get_resource_type( $image ) ) { return true; }
return false; }
/** * Creates a new GD image resource with transparency support. * * @todo Deprecate if possible. * * @since 2.9.0 * * @param int $width Image width in pixels. * @param int $height Image height in pixels. * @return resource|GdImage|false The GD image resource or GdImage instance on success. * False on failure. */ function wp_imagecreatetruecolor( $width, $height ) { $img = imagecreatetruecolor( $width, $height );
/** * Based on a supplied width/height example, returns the biggest possible dimensions based on the max width/height. * * @since 2.9.0 * * @see wp_constrain_dimensions() * * @param int $example_width The width of an example embed. * @param int $example_height The height of an example embed. * @param int $max_width The maximum allowed width. * @param int $max_height The maximum allowed height. * @return int[] { * An array of maximum width and height values. * * @type int $0 The maximum width in pixels. * @type int $1 The maximum height in pixels. * } */ function wp_expand_dimensions( $example_width, $example_height, $max_width, $max_height ) { $example_width = (int) $example_width; $example_height = (int) $example_height; $max_width = (int) $max_width; $max_height = (int) $max_height;
/** * Determines the maximum upload size allowed in php.ini. * * @since 2.5.0 * * @return int Allowed upload size. */ function wp_max_upload_size() { $u_bytes = wp_convert_hr_to_bytes( ini_get( 'upload_max_filesize' ) ); $p_bytes = wp_convert_hr_to_bytes( ini_get( 'post_max_size' ) );
/** * Filters the maximum upload size allowed in php.ini. * * @since 2.5.0 * * @param int $size Max upload size limit in bytes. * @param int $u_bytes Maximum upload filesize in bytes. * @param int $p_bytes Maximum size of POST data in bytes. */ return apply_filters( 'upload_size_limit', min( $u_bytes, $p_bytes ), $u_bytes, $p_bytes ); }
/** * Returns a WP_Image_Editor instance and loads file into it. * * @since 3.5.0 * * @param string $path Path to the file to load. * @param array $args Optional. Additional arguments for retrieving the image editor. * Default empty array. * @return WP_Image_Editor|WP_Error The WP_Image_Editor object on success, * a WP_Error object otherwise. */ function wp_get_image_editor( $path, $args = array() ) { $args['path'] = $path;
// If the mime type is not set in args, try to extract and set it from the file. if ( ! isset( $args['mime_type'] ) ) { $file_info = wp_check_filetype( $args['path'] );
/* * If $file_info['type'] is false, then we let the editor attempt to * figure out the file type, rather than forcing a failure based on extension. */ if ( isset( $file_info ) && $file_info['type'] ) { $args['mime_type'] = $file_info['type']; } }
// Check and set the output mime type mapped to the input type. if ( isset( $args['mime_type'] ) ) { $output_format = wp_get_image_editor_output_format( $path, $args['mime_type'] ); if ( isset( $output_format[ $args['mime_type'] ] ) ) { $args['output_mime_type'] = $output_format[ $args['mime_type'] ]; } }
if ( $implementation ) { $editor = new $implementation( $path ); $loaded = $editor->load();
if ( is_wp_error( $loaded ) ) { return $loaded; }
return $editor; }
return new WP_Error( 'image_no_editor', __( 'No editor could be selected.' ) ); }
/** * Tests whether there is an editor that supports a given mime type or methods. * * @since 3.5.0 * * @param string|array $args Optional. Array of arguments to retrieve the image editor supports. * Default empty array. * @return bool True if an eligible editor is found; false otherwise. */ function wp_image_editor_supports( $args = array() ) { return (bool) _wp_image_editor_choose( $args ); }
/** * Tests which editors are capable of supporting the request. * * @ignore * @since 3.5.0 * * @param array $args Optional. Array of arguments for choosing a capable editor. Default empty array. * @return string|false Class name for the first editor that claims to support the request. * False if no editor claims to support the request. */ function _wp_image_editor_choose( $args = array() ) { require_once ABSPATH . WPINC . '/class-wp-image-editor.php'; require_once ABSPATH . WPINC . '/class-wp-image-editor-gd.php'; require_once ABSPATH . WPINC . '/class-wp-image-editor-imagick.php'; require_once ABSPATH . WPINC . '/class-avif-info.php'; /** * Filters the list of image editing library classes. * * @since 3.5.0 * * @param string[] $image_editors Array of available image editor class names. Defaults are * 'WP_Image_Editor_Imagick', 'WP_Image_Editor_GD'. */ $implementations = apply_filters( 'wp_image_editors', array( 'WP_Image_Editor_Imagick', 'WP_Image_Editor_GD' ) );
// Cache the chosen editor implementation based on specific args and available implementations. $cache_key = md5( serialize( array( $args, $implementations ) ) );
// Implementation should support the passed mime type. if ( isset( $args['mime_type'] ) && ! call_user_func( array( $implementation, 'supports_mime_type' ), $args['mime_type'] ) ) { continue; }
// Implementation should support requested methods. if ( isset( $args['methods'] ) && array_diff( $args['methods'], get_class_methods( $implementation ) ) ) {
continue; }
// Implementation should ideally support the output mime type as well if set and different than the passed type. if ( isset( $args['mime_type'] ) && isset( $args['output_mime_type'] ) && $args['mime_type'] !== $args['output_mime_type'] && ! call_user_func( array( $implementation, 'supports_mime_type' ), $args['output_mime_type'] ) ) { /* * This implementation supports the input type but not the output type. * Keep looking to see if we can find an implementation that supports both. */ $editor = $implementation; continue; }
// Favor the implementation that supports both input and output mime types. $editor = $implementation; break; }
/* * Since 4.9 the `runtimes` setting is hardcoded in our version of Plupload to `html5,html4`, * and the `flash_swf_url` and `silverlight_xap_url` are not used. */ $defaults = array( 'file_data_name' => 'async-upload', // Key passed to $_FILE. 'url' => admin_url( 'async-upload.php', 'relative' ), 'filters' => array( 'max_file_size' => $max_upload_size . 'b', 'mime_types' => array( array( 'extensions' => implode( ',', $extensions ) ) ), ), );
/* * Currently only iOS Safari supports multiple files uploading, * but iOS 7.x has a bug that prevents uploading of videos when enabled. * See #29602. */ if ( wp_is_mobile() && str_contains( $_SERVER['HTTP_USER_AGENT'], 'OS 7_' ) && str_contains( $_SERVER['HTTP_USER_AGENT'], 'like Mac OS X' ) ) { $defaults['multi_selection'] = false; }
// Check if WebP images can be edited. if ( ! wp_image_editor_supports( array( 'mime_type' => 'image/webp' ) ) ) { $defaults['webp_upload_error'] = true; }
// Check if AVIF images can be edited. if ( ! wp_image_editor_supports( array( 'mime_type' => 'image/avif' ) ) ) { $defaults['avif_upload_error'] = true; }
// Check if HEIC images can be edited. if ( ! wp_image_editor_supports( array( 'mime_type' => 'image/heic' ) ) ) { $defaults['heic_upload_error'] = true; }
/** * Prepares an attachment post object for JS, where it is expected * to be JSON-encoded and fit into an Attachment model. * * @since 3.5.0 * * @param int|WP_Post $attachment Attachment ID or object. * @return array|void { * Array of attachment details, or void if the parameter does not correspond to an attachment. * * @type string $alt Alt text of the attachment. * @type string $author ID of the attachment author, as a string. * @type string $authorName Name of the attachment author. * @type string $caption Caption for the attachment. * @type array $compat Containing item and meta. * @type string $context Context, whether it's used as the site icon for example. * @type int $date Uploaded date, timestamp in milliseconds. * @type string $dateFormatted Formatted date (e.g. June 29, 2018). * @type string $description Description of the attachment. * @type string $editLink URL to the edit page for the attachment. * @type string $filename File name of the attachment. * @type string $filesizeHumanReadable Filesize of the attachment in human readable format (e.g. 1 MB). * @type int $filesizeInBytes Filesize of the attachment in bytes. * @type int $height If the attachment is an image, represents the height of the image in pixels. * @type string $icon Icon URL of the attachment (e.g. /wp-includes/images/media/archive.png). * @type int $id ID of the attachment. * @type string $link URL to the attachment. * @type int $menuOrder Menu order of the attachment post. * @type array $meta Meta data for the attachment. * @type string $mime Mime type of the attachment (e.g. image/jpeg or application/zip). * @type int $modified Last modified, timestamp in milliseconds. * @type string $name Name, same as title of the attachment. * @type array $nonces Nonces for update, delete and edit. * @type string $orientation If the attachment is an image, represents the image orientation * (landscape or portrait). * @type array $sizes If the attachment is an image, contains an array of arrays * for the images sizes: thumbnail, medium, large, and full. * @type string $status Post status of the attachment (usually 'inherit'). * @type string $subtype Mime subtype of the attachment (usually the last part, e.g. jpeg or zip). * @type string $title Title of the attachment (usually slugified file name without the extension). * @type string $type Type of the attachment (usually first part of the mime type, e.g. image). * @type int $uploadedTo Parent post to which the attachment was uploaded. * @type string $uploadedToLink URL to the edit page of the parent post of the attachment. * @type string $uploadedToTitle Post title of the parent of the attachment. * @type string $url Direct URL to the attachment file (from wp-content). * @type int $width If the attachment is an image, represents the width of the image in pixels. * } * */ function wp_prepare_attachment_for_js( $attachment ) { $attachment = get_post( $attachment );
if ( ! $attachment ) { return; }
if ( 'attachment' !== $attachment->post_type ) { return; }
/* * Loop through all potential sizes that may be chosen. Try to do this with some efficiency. * First: run the image_downsize filter. If it returns something, we can use its data. * If the filter does not return something, then image_downsize() is just an expensive way * to check the image metadata, which we do second. */ foreach ( $possible_sizes as $size => $label ) {
/** This filter is documented in wp-includes/media.php */ $downsize = apply_filters( 'image_downsize', false, $attachment->ID, $size );
if ( $downsize ) { if ( empty( $downsize[3] ) ) { continue; }
$sizes[ $size ] = array( 'height' => $downsize[2], 'width' => $downsize[1], 'url' => $downsize[0], 'orientation' => $downsize[2] > $downsize[1] ? 'portrait' : 'landscape', ); } elseif ( isset( $meta['sizes'][ $size ] ) ) { // Nothing from the filter, so consult image metadata if we have it. $size_meta = $meta['sizes'][ $size ];
/* * We have the actual image size, but might need to further constrain it if content_width is narrower. * Thumbnail, medium, and full sizes are also checked against the site's height/width options. */ list( $width, $height ) = image_constrain_size_for_editor( $size_meta['width'], $size_meta['height'], $size, 'edit' );
/** * Filters the attachment data prepared for JavaScript. * * @since 3.5.0 * * @param array $response Array of prepared attachment data. See {@see wp_prepare_attachment_for_js()}. * @param WP_Post $attachment Attachment object. * @param array|false $meta Array of attachment meta data, or false if there is none. */ return apply_filters( 'wp_prepare_attachment_for_js', $response, $attachment, $meta ); }
/** * Enqueues all scripts, styles, settings, and templates necessary to use * all media JS APIs. * * @since 3.5.0 * * @global int $content_width * @global wpdb $wpdb WordPress database abstraction object. * @global WP_Locale $wp_locale WordPress date and time locale object. * * @param array $args { * Arguments for enqueuing media scripts. * * @type int|WP_Post $post Post ID or post object. * } */ function wp_enqueue_media( $args = array() ) { // Enqueue me just once per page, please. if ( did_action( 'wp_enqueue_media' ) ) { return; }
/* * We're going to pass the old thickbox media tabs to `media_upload_tabs` * to ensure plugins will work. We will then unset those tabs. */ $tabs = array( // handler action suffix => tab label 'type' => '', 'type_url' => '', 'gallery' => '', 'library' => '', );
/** This filter is documented in wp-admin/includes/media.php */ $tabs = apply_filters( 'media_upload_tabs', $tabs ); unset( $tabs['type'], $tabs['type_url'], $tabs['gallery'], $tabs['library'] );
/** * Allows showing or hiding the "Create Audio Playlist" button in the media library. * * By default, the "Create Audio Playlist" button will always be shown in * the media library. If this filter returns `null`, a query will be run * to determine whether the media library contains any audio items. This * was the default behavior prior to version 4.8.0, but this query is * expensive for large media libraries. * * @since 4.7.4 * @since 4.8.0 The filter's default value is `true` rather than `null`. * * @link https://core.trac.wordpress.org/ticket/31071 * * @param bool|null $show Whether to show the button, or `null` to decide based * on whether any audio files exist in the media library. */ $show_audio_playlist = apply_filters( 'media_library_show_audio_playlist', true ); if ( null === $show_audio_playlist ) { $show_audio_playlist = $wpdb->get_var( "SELECT ID FROM $wpdb->posts WHERE post_type = 'attachment' AND post_mime_type LIKE 'audio%' LIMIT 1" ); }
/** * Allows showing or hiding the "Create Video Playlist" button in the media library. * * By default, the "Create Video Playlist" button will always be shown in * the media library. If this filter returns `null`, a query will be run * to determine whether the media library contains any video items. This * was the default behavior prior to version 4.8.0, but this query is * expensive for large media libraries. * * @since 4.7.4 * @since 4.8.0 The filter's default value is `true` rather than `null`. * * @link https://core.trac.wordpress.org/ticket/31071 * * @param bool|null $show Whether to show the button, or `null` to decide based * on whether any video files exist in the media library. */ $show_video_playlist = apply_filters( 'media_library_show_video_playlist', true ); if ( null === $show_video_playlist ) { $show_video_playlist = $wpdb->get_var( "SELECT ID FROM $wpdb->posts WHERE post_type = 'attachment' AND post_mime_type LIKE 'video%' LIMIT 1" ); }
/** * Allows overriding the list of months displayed in the media library. * * By default (if this filter does not return an array), a query will be * run to determine the months that have media items. This query can be * expensive for large media libraries, so it may be desirable for sites to * override this behavior. * * @since 4.7.4 * * @link https://core.trac.wordpress.org/ticket/31071 * * @param stdClass[]|null $months An array of objects with `month` and `year` * properties, or `null` for default behavior. */ $months = apply_filters( 'media_library_months_with_files', null ); if ( ! is_array( $months ) ) { $months = $wpdb->get_results( $wpdb->prepare( "SELECT DISTINCT YEAR( post_date ) AS year, MONTH( post_date ) AS month FROM $wpdb->posts WHERE post_type = %s ORDER BY post_date DESC", 'attachment' ) ); } foreach ( $months as $month_year ) { $month_year->text = sprintf( /* translators: 1: Month, 2: Year. */ __( '%1$s %2$d' ), $wp_locale->get_month( $month_year->month ), $month_year->year ); }
/** * Filters whether the Media Library grid has infinite scrolling. Default `false`. * * @since 5.8.0 * * @param bool $infinite Whether the Media Library grid has infinite scrolling. */ $infinite_scrolling = apply_filters( 'media_library_infinite_scrolling', false );
$strings = array( // Generic. 'mediaFrameDefaultTitle' => __( 'Media' ), 'url' => __( 'URL' ), 'addMedia' => __( 'Add media' ), 'search' => __( 'Search' ), 'select' => __( 'Select' ), 'cancel' => __( 'Cancel' ), 'update' => __( 'Update' ), 'replace' => __( 'Replace' ), 'remove' => __( 'Remove' ), 'back' => __( 'Back' ), /* * translators: This is a would-be plural string used in the media manager. * If there is not a word you can use in your language to avoid issues with the * lack of plural support here, turn it into "selected: %d" then translate it. */ 'selected' => __( '%d selected' ), 'dragInfo' => __( 'Drag and drop to reorder media files.' ),
// Video Playlist. 'videoPlaylistDragInfo' => __( 'Drag and drop to reorder videos.' ), 'createVideoPlaylistTitle' => __( 'Create video playlist' ), 'editVideoPlaylistTitle' => __( 'Edit video playlist' ), 'cancelVideoPlaylistTitle' => __( '← Cancel video playlist' ), 'insertVideoPlaylist' => __( 'Insert video playlist' ), 'updateVideoPlaylist' => __( 'Update video playlist' ), 'addToVideoPlaylist' => __( 'Add to video playlist' ), 'addToVideoPlaylistTitle' => __( 'Add to video Playlist' ),
/** * Filters the media view settings. * * @since 3.5.0 * * @param array $settings List of media view settings. * @param WP_Post $post Post object. */ $settings = apply_filters( 'media_view_settings', $settings, $post );
/** * Filters the media view strings. * * @since 3.5.0 * * @param string[] $strings Array of media view strings keyed by the name they'll be referenced by in JavaScript. * @param WP_Post $post Post object. */ $strings = apply_filters( 'media_view_strings', $strings, $post );
$strings['settings'] = $settings;
/* * Ensure we enqueue media-editor first, that way media-views * is registered internally before we try to localize it. See #24724. */ wp_enqueue_script( 'media-editor' ); wp_localize_script( 'media-views', '_wpMediaViewsL10n', $strings );
/** * Fires at the conclusion of wp_enqueue_media(). * * @since 3.5.0 */ do_action( 'wp_enqueue_media' ); }
/** * Retrieves media attached to the passed post. * * @since 3.6.0 * * @param string $type Mime type. * @param int|WP_Post $post Optional. Post ID or WP_Post object. Default is global $post. * @return WP_Post[] Array of media attached to the given post. */ function get_attached_media( $type, $post = 0 ) { $post = get_post( $post );
/** * Filters arguments used to retrieve media attached to the given post. * * @since 3.6.0 * * @param array $args Post query arguments. * @param string $type Mime type of the desired media. * @param WP_Post $post Post object. */ $args = apply_filters( 'get_attached_media_args', $args, $type, $post );
$children = get_children( $args );
/** * Filters the list of media attached to the given post. * * @since 3.6.0 * * @param WP_Post[] $children Array of media attached to the given post. * @param string $type Mime type of the media desired. * @param WP_Post $post Post object. */ return (array) apply_filters( 'get_attached_media', $children, $type, $post ); }
/** * Checks the HTML content for an audio, video, object, embed, or iframe tags. * * @since 3.6.0 * * @param string $content A string of HTML which might contain media elements. * @param string[] $types An array of media types: 'audio', 'video', 'object', 'embed', or 'iframe'. * @return string[] Array of found HTML media elements. */ function get_media_embedded_in_content( $content, $types = null ) { $html = array();
/** * Filters the embedded media types that are allowed to be returned from the content blob. * * @since 4.2.0 * * @param string[] $allowed_media_types An array of allowed media types. Default media types are * 'audio', 'video', 'object', 'embed', and 'iframe'. */ $allowed_media_types = apply_filters( 'media_embedded_in_content_allowed_types', array( 'audio', 'video', 'object', 'embed', 'iframe' ) );
/** * Retrieves galleries from the passed post's content. * * @since 3.6.0 * * @param int|WP_Post $post Post ID or object. * @param bool $html Optional. Whether to return HTML or data in the array. Default true. * @return array A list of arrays, each containing gallery data and srcs parsed * from the expanded shortcode. */ function get_post_galleries( $post, $html = true ) { $post = get_post( $post );
// Specify the post ID of the gallery we're viewing if the shortcode doesn't reference another post already. if ( ! isset( $shortcode_attrs['id'] ) ) { $shortcode[3] .= ' id="' . (int) $post->ID . '"'; }
// Skip blocks with no blockName and no innerHTML. if ( ! $block['blockName'] ) { continue; }
// Skip non-Gallery blocks. if ( 'core/gallery' !== $block['blockName'] ) { // Move inner blocks into the root array before skipping. if ( $has_inner_blocks ) { array_push( $post_blocks, ...$block['innerBlocks'] ); } continue; }
// New Gallery block format as HTML. if ( $has_inner_blocks && $html ) { $block_html = wp_list_pluck( $block['innerBlocks'], 'innerHTML' ); $galleries[] = '<figure>' . implode( ' ', $block_html ) . '</figure>'; continue; }
$srcs = array();
// New Gallery block format as an array. if ( $has_inner_blocks ) { $attrs = wp_list_pluck( $block['innerBlocks'], 'attrs' ); $ids = wp_list_pluck( $attrs, 'id' );
// Old Gallery block format as HTML. if ( $html ) { $galleries[] = $block['innerHTML']; continue; }
// Old Gallery block format as an array. $ids = ! empty( $block['attrs']['ids'] ) ? $block['attrs']['ids'] : array();
// If present, use the image IDs from the JSON blob as canonical. if ( ! empty( $ids ) ) { foreach ( $ids as $id ) { $url = wp_get_attachment_url( $id );
/** * Filters the list of all found galleries in the given post. * * @since 3.6.0 * * @param array $galleries Associative array of all found post galleries. * @param WP_Post $post Post object. */ return apply_filters( 'get_post_galleries', $galleries, $post ); }
/** * Checks a specified post's content for gallery and, if present, return the first * * @since 3.6.0 * * @param int|WP_Post $post Optional. Post ID or WP_Post object. Default is global $post. * @param bool $html Optional. Whether to return HTML or data. Default is true. * @return string|array Gallery data and srcs parsed from the expanded shortcode. */ function get_post_gallery( $post = 0, $html = true ) { $galleries = get_post_galleries( $post, $html ); $gallery = reset( $galleries );
/** * Filters the first-found post gallery. * * @since 3.6.0 * * @param array $gallery The first-found post gallery. * @param int|WP_Post $post Post ID or object. * @param array $galleries Associative array of all found post galleries. */ return apply_filters( 'get_post_gallery', $gallery, $post, $galleries ); }
/** * Retrieves the image srcs from galleries from a post's content, if present. * * @since 3.6.0 * * @see get_post_galleries() * * @param int|WP_Post $post Optional. Post ID or WP_Post object. Default is global `$post`. * @return array A list of lists, each containing image srcs parsed. * from an expanded shortcode */ function get_post_galleries_images( $post = 0 ) { $galleries = get_post_galleries( $post, false ); return wp_list_pluck( $galleries, 'src' ); }
/** * Checks a post's content for galleries and return the image srcs for the first found gallery. * * @since 3.6.0 * * @see get_post_gallery() * * @param int|WP_Post $post Optional. Post ID or WP_Post object. Default is global `$post`. * @return string[] A list of a gallery's image srcs in order. */ function get_post_gallery_images( $post = 0 ) { $gallery = get_post_gallery( $post, false ); return empty( $gallery['src'] ) ? array() : $gallery['src']; }
/** * Maybe attempts to generate attachment metadata, if missing. * * @since 3.9.0 * * @param WP_Post $attachment Attachment object. */ function wp_maybe_generate_attachment_metadata( $attachment ) { if ( empty( $attachment ) || empty( $attachment->ID ) ) { return; }
/** * Tries to convert an attachment URL into a post ID. * * @since 4.0.0 * * @global wpdb $wpdb WordPress database abstraction object. * * @param string $url The URL to resolve. * @return int The found post ID, or 0 on failure. */ function attachment_url_to_postid( $url ) { global $wpdb;
/** * Filters the attachment ID to allow short-circuit the function. * * Allows plugins to short-circuit attachment ID lookups. Plugins making * use of this function should return: * * - 0 (integer) to indicate the attachment is not found, * - attachment ID (integer) to indicate the attachment ID found, * - null to indicate WordPress should proceed with the lookup. * * Warning: The post ID may be null or zero, both of which cast to a * boolean false. For information about casting to booleans see the * {@link https://www.php.net/manual/en/language.types.boolean.php PHP documentation}. * Use the === operator for testing the post ID when developing filters using * this hook. * * @param int|null $post_id The result of the post ID lookup. Null to indicate * no lookup has been attempted. Default null. * @param string $url The URL being looked up. */ $post_id = apply_filters( 'pre_attachment_url_to_postid', null, $url ); if ( null !== $post_id ) { return (int) $post_id; }
// Force the protocols to match if needed. if ( isset( $image_path['scheme'] ) && ( $image_path['scheme'] !== $site_url['scheme'] ) ) { $path = str_replace( $image_path['scheme'], $site_url['scheme'], $path ); }
/** * Filters an attachment ID found by URL. * * @since 4.2.0 * * @param int|null $post_id The post_id (if any) found by the function. * @param string $url The URL being looked up. */ return (int) apply_filters( 'attachment_url_to_postid', $post_id, $url ); }
/** * Returns the URLs for CSS files used in an iframe-sandbox'd TinyMCE media view. * * @since 4.0.0 * * @return string[] The relevant CSS file URLs. */ function wpview_media_sandbox_styles() { $version = 'ver=' . get_bloginfo( 'version' ); $mediaelement = includes_url( "js/mediaelement/mediaelementplayer-legacy.min.css?$version" ); $wpmediaelement = includes_url( "js/mediaelement/wp-mediaelement.css?$version" );
return array( $mediaelement, $wpmediaelement ); }
/** * Registers the personal data exporter for media. * * @param array[] $exporters An array of personal data exporters, keyed by their ID. * @return array[] Updated array of personal data exporters. */ function wp_register_media_personal_data_exporter( $exporters ) { $exporters['wordpress-media'] = array( 'exporter_friendly_name' => __( 'WordPress Media' ), 'callback' => 'wp_media_personal_data_exporter', );
return $exporters; }
/** * Finds and exports attachments associated with an email address. * * @since 4.9.6 * * @param string $email_address The attachment owner email address. * @param int $page Attachment page number. * @return array { * An array of personal data. * * @type array[] $data An array of personal data arrays. * @type bool $done Whether the exporter is finished. * } */ function wp_media_personal_data_exporter( $email_address, $page = 1 ) { // Limit us to 50 attachments at a time to avoid timing out. $number = 50; $page = (int) $page;
/** * Adds additional default image sub-sizes. * * These sizes are meant to enhance the way WordPress displays images on the front-end on larger, * high-density devices. They make it possible to generate more suitable `srcset` and `sizes` attributes * when the users upload large images. * * The sizes can be changed or removed by themes and plugins but that is not recommended. * The size "names" reflect the image dimensions, so changing the sizes would be quite misleading. * * @since 5.3.0 * @access private */ function _wp_add_additional_image_sizes() { // 2x medium_large size. add_image_size( '1536x1536', 1536, 1536 ); // 2x large size. add_image_size( '2048x2048', 2048, 2048 ); }
/** * Callback to enable showing of the user error when uploading .heic images. * * @since 5.5.0 * @since 6.7.0 The default behavior is to enable heic uploads as long as the server * supports the format. The uploads are converted to JPEG's by default. * * @param array[] $plupload_settings The settings for Plupload.js. * @return array[] Modified settings for Plupload.js. */ function wp_show_heic_upload_error( $plupload_settings ) { // Check if HEIC images can be edited. if ( ! wp_image_editor_supports( array( 'mime_type' => 'image/heic' ) ) ) { $plupload_init['heic_upload_error'] = true; } return $plupload_settings; }
/** * Allows PHP's getimagesize() to be debuggable when necessary. * * @since 5.7.0 * @since 5.8.0 Added support for WebP images. * @since 6.5.0 Added support for AVIF images. * * @param string $filename The file path. * @param array $image_info Optional. Extended image information (passed by reference). * @return array|false Array of image information or false on failure. */ function wp_getimagesize( $filename, ?array &$image_info = null ) { // Don't silence errors when in debug mode, unless running unit tests. if ( defined( 'WP_DEBUG' ) && WP_DEBUG && ! defined( 'WP_RUN_CORE_TESTS' ) ) { if ( 2 === func_num_args() ) { $info = getimagesize( $filename, $image_info ); } else { $info = getimagesize( $filename ); } } else { /* * Silencing notice and warning is intentional. * * getimagesize() has a tendency to generate errors, such as * "corrupt JPEG data: 7191 extraneous bytes before marker", * even when it's able to provide image size information. * * See https://core.trac.wordpress.org/ticket/42480 */ if ( 2 === func_num_args() ) { $info = @getimagesize( $filename, $image_info ); } else { $info = @getimagesize( $filename ); } }
if ( ! empty( $info ) && // Some PHP versions return 0x0 sizes from `getimagesize` for unrecognized image formats, including AVIFs. ! ( empty( $info[0] ) && empty( $info[1] ) ) ) { return $info; }
// Not an image? if ( false === $image_mime_type ) { return false; }
/* * For PHP versions that don't support WebP images, * extract the image size info from the file headers. */ if ( 'image/webp' === $image_mime_type ) { $webp_info = wp_get_webp_info( $filename ); $width = $webp_info['width']; $height = $webp_info['height'];
// For PHP versions that don't support AVIF images, extract the image size info from the file headers. if ( 'image/avif' === $image_mime_type ) { $avif_info = wp_get_avif_info( $filename );
// For PHP versions that don't support HEIC images, extract the size info using Imagick when available. if ( wp_is_heic_image_mime_type( $image_mime_type ) ) { $editor = wp_get_image_editor( $filename );
if ( is_wp_error( $editor ) ) { return false; }
// If the editor for HEICs is Imagick, use it to get the image size. if ( $editor instanceof WP_Image_Editor_Imagick ) { $size = $editor->get_size(); return array( $size['width'], $size['height'], IMAGETYPE_HEIC, sprintf( 'width="%d" height="%d"', $size['width'], $size['height'] ), 'mime' => 'image/heic', ); } }
// The image could not be parsed. return false; }
/** * Extracts meta information about an AVIF file: width, height, bit depth, and number of channels. * * @since 6.5.0 * * @param string $filename Path to an AVIF file. * @return array { * An array of AVIF image information. * * @type int|false $width Image width on success, false on failure. * @type int|false $height Image height on success, false on failure. * @type int|false $bit_depth Image bit depth on success, false on failure. * @type int|false $num_channels Image number of channels on success, false on failure. * } */ function wp_get_avif_info( $filename ) { $results = array( 'width' => false, 'height' => false, 'bit_depth' => false, 'num_channels' => false, );
/** * Extracts meta information about a WebP file: width, height, and type. * * @since 5.8.0 * * @param string $filename Path to a WebP file. * @return array { * An array of WebP image information. * * @type int|false $width Image width on success, false on failure. * @type int|false $height Image height on success, false on failure. * @type string|false $type The WebP type: one of 'lossy', 'lossless' or 'animated-alpha'. * False on failure. * } */ function wp_get_webp_info( $filename ) { $width = false; $height = false; $type = false;
/** * Gets loading optimization attributes. * * This function returns an array of attributes that should be merged into the given attributes array to optimize * loading performance. Potential attributes returned by this function are: * - `loading` attribute with a value of "lazy" * - `fetchpriority` attribute with a value of "high" * - `decoding` attribute with a value of "async" * * If any of these attributes are already present in the given attributes, they will not be modified. Note that no * element should have both `loading="lazy"` and `fetchpriority="high"`, so the function will trigger a warning in case * both attributes are present with those values. * * @since 6.3.0 * * @global WP_Query $wp_query WordPress Query object. * * @param string $tag_name The tag name. * @param array $attr Array of the attributes for the tag. * @param string $context Context for the element for which the loading optimization attribute is requested. * @return array Loading optimization attributes. */ function wp_get_loading_optimization_attributes( $tag_name, $attr, $context ) { global $wp_query;
/** * Filters whether to short-circuit loading optimization attributes. * * Returning an array from the filter will effectively short-circuit the loading of optimization attributes, * returning that value instead. * * @since 6.4.0 * * @param array|false $loading_attrs False by default, or array of loading optimization attributes to short-circuit. * @param string $tag_name The tag name. * @param array $attr Array of the attributes for the tag. * @param string $context Context for the element for which the loading optimization attribute is requested. */ $loading_attrs = apply_filters( 'pre_wp_get_loading_optimization_attributes', false, $tag_name, $attr, $context );
if ( is_array( $loading_attrs ) ) { return $loading_attrs; }
$loading_attrs = array();
/* * Skip lazy-loading for the overall block template, as it is handled more granularly. * The skip is also applicable for `fetchpriority`. */ if ( 'template' === $context ) { /** This filter is documented in wp-includes/media.php */ return apply_filters( 'wp_get_loading_optimization_attributes', $loading_attrs, $tag_name, $attr, $context ); }
// For now this function only supports images and iframes. if ( 'img' !== $tag_name && 'iframe' !== $tag_name ) { /** This filter is documented in wp-includes/media.php */ return apply_filters( 'wp_get_loading_optimization_attributes', $loading_attrs, $tag_name, $attr, $context ); }
/* * Skip programmatically created images within content blobs as they need to be handled together with the other * images within the post content or widget content. * Without this clause, they would already be considered within their own context which skews the image count and * can result in the first post content image being lazy-loaded or an image further down the page being marked as a * high priority. */ if ( 'the_content' !== $context && doing_filter( 'the_content' ) || 'widget_text_content' !== $context && doing_filter( 'widget_text_content' ) || 'widget_block_content' !== $context && doing_filter( 'widget_block_content' ) ) { /** This filter is documented in wp-includes/media.php */ return apply_filters( 'wp_get_loading_optimization_attributes', $loading_attrs, $tag_name, $attr, $context );
}
/* * Add `decoding` with a value of "async" for every image unless it has a * conflicting `decoding` attribute already present. */ if ( 'img' === $tag_name ) { if ( isset( $attr['decoding'] ) ) { $loading_attrs['decoding'] = $attr['decoding']; } else { $loading_attrs['decoding'] = 'async'; } }
// For any resources, width and height must be provided, to avoid layout shifts. if ( ! isset( $attr['width'], $attr['height'] ) ) { /** This filter is documented in wp-includes/media.php */ return apply_filters( 'wp_get_loading_optimization_attributes', $loading_attrs, $tag_name, $attr, $context ); }
/* * The key function logic starts here. */ $maybe_in_viewport = null; $increase_count = false; $maybe_increase_count = false;
// Logic to handle a `loading` attribute that is already provided. if ( isset( $attr['loading'] ) ) { /* * Interpret "lazy" as not in viewport. Any other value can be * interpreted as in viewport (realistically only "eager" or `false` * to force-omit the attribute are other potential values). */ if ( 'lazy' === $attr['loading'] ) { $maybe_in_viewport = false; } else { $maybe_in_viewport = true; } }
// Logic to handle a `fetchpriority` attribute that is already provided. if ( isset( $attr['fetchpriority'] ) && 'high' === $attr['fetchpriority'] ) { /* * If the image was already determined to not be in the viewport (e.g. * from an already provided `loading` attribute), trigger a warning. * Otherwise, the value can be interpreted as in viewport, since only * the most important in-viewport image should have `fetchpriority` set * to "high". */ if ( false === $maybe_in_viewport ) { _doing_it_wrong( __FUNCTION__, __( 'An image should not be lazy-loaded and marked as high priority at the same time.' ), '6.3.0' ); /* * Set `fetchpriority` here for backward-compatibility as we should * not override what a developer decided, even though it seems * incorrect. */ $loading_attrs['fetchpriority'] = 'high'; } else { $maybe_in_viewport = true; } }
/** * Filters the header-specific contexts. * * @since 6.4.0 * * @param array $default_header_enforced_contexts Map of contexts for which elements should be considered * in the header of the page, as $context => $enabled * pairs. The $enabled should always be true. */ $header_enforced_contexts = apply_filters( 'wp_loading_optimization_force_header_contexts', $header_enforced_contexts );
// Consider elements with these header-specific contexts to be in viewport. if ( isset( $header_enforced_contexts[ $context ] ) ) { $maybe_in_viewport = true; $maybe_increase_count = true; } elseif ( ! is_admin() && in_the_loop() && is_main_query() ) { /* * Get the content media count, since this is a main query * content element. This is accomplished by "increasing" * the count by zero, as the only way to get the count is * to call this function. * The actual count increase happens further below, based * on the `$increase_count` flag set here. */ $content_media_count = wp_increase_content_media_count( 0 ); $increase_count = true;
// If the count so far is below the threshold, `loading` attribute is omitted. if ( $content_media_count < wp_omit_loading_attr_threshold() ) { $maybe_in_viewport = true; } else { $maybe_in_viewport = false; } } elseif ( // Only apply for main query but before the loop. $wp_query->before_loop && $wp_query->is_main_query() /* * Any image before the loop, but after the header has started should not be lazy-loaded, * except when the footer has already started which can happen when the current template * does not include any loop. */ && did_action( 'get_header' ) && ! did_action( 'get_footer' ) ) { $maybe_in_viewport = true; $maybe_increase_count = true; } }
/* * If the element is in the viewport (`true`), potentially add * `fetchpriority` with a value of "high". Otherwise, i.e. if the element * is not not in the viewport (`false`) or it is unknown (`null`), add * `loading` with a value of "lazy". */ if ( $maybe_in_viewport ) { $loading_attrs = wp_maybe_add_fetchpriority_high_attr( $loading_attrs, $tag_name, $attr ); } else { // Only add `loading="lazy"` if the feature is enabled. if ( wp_lazy_loading_enabled( $tag_name, $context ) ) { $loading_attrs['loading'] = 'lazy'; } }
/* * If flag was set based on contextual logic above, increase the content * media count, either unconditionally, or based on whether the image size * is larger than the threshold. */ if ( $increase_count ) { wp_increase_content_media_count(); } elseif ( $maybe_increase_count ) { /** This filter is documented in wp-includes/media.php */ $wp_min_priority_img_pixels = apply_filters( 'wp_min_priority_img_pixels', 50000 );
/** * Filters the loading optimization attributes. * * @since 6.4.0 * * @param array $loading_attrs The loading optimization attributes. * @param string $tag_name The tag name. * @param array $attr Array of the attributes for the tag. * @param string $context Context for the element for which the loading optimization attribute is requested. */ return apply_filters( 'wp_get_loading_optimization_attributes', $loading_attrs, $tag_name, $attr, $context ); }
/** * Gets the threshold for how many of the first content media elements to not lazy-load. * * This function runs the {@see 'wp_omit_loading_attr_threshold'} filter, which uses a default threshold value of 3. * The filter is only run once per page load, unless the `$force` parameter is used. * * @since 5.9.0 * * @param bool $force Optional. If set to true, the filter will be (re-)applied even if it already has been before. * Default false. * @return int The number of content media elements to not lazy-load. */ function wp_omit_loading_attr_threshold( $force = false ) { static $omit_threshold;
// This function may be called multiple times. Run the filter only once per page load. if ( ! isset( $omit_threshold ) || $force ) { /** * Filters the threshold for how many of the first content media elements to not lazy-load. * * For these first content media elements, the `loading` attribute will be omitted. By default, this is the case * for only the very first content media element. * * @since 5.9.0 * @since 6.3.0 The default threshold was changed from 1 to 3. * * @param int $omit_threshold The number of media elements where the `loading` attribute will not be added. Default 3. */ $omit_threshold = apply_filters( 'wp_omit_loading_attr_threshold', 3 ); }
return $omit_threshold; }
/** * Increases an internal content media count variable. * * @since 5.9.0 * @access private * * @param int $amount Optional. Amount to increase by. Default 1. * @return int The latest content media count, after the increase. */ function wp_increase_content_media_count( $amount = 1 ) { static $content_media_count = 0;
$content_media_count += $amount;
return $content_media_count; }
/** * Determines whether to add `fetchpriority='high'` to loading attributes. * * @since 6.3.0 * @access private * * @param array $loading_attrs Array of the loading optimization attributes for the element. * @param string $tag_name The tag name. * @param array $attr Array of the attributes for the element. * @return array Updated loading optimization attributes for the element. */ function wp_maybe_add_fetchpriority_high_attr( $loading_attrs, $tag_name, $attr ) { // For now, adding `fetchpriority="high"` is only supported for images. if ( 'img' !== $tag_name ) { return $loading_attrs; }
if ( isset( $attr['fetchpriority'] ) ) { /* * While any `fetchpriority` value could be set in `$loading_attrs`, * for consistency we only do it for `fetchpriority="high"` since that * is the only possible value that WordPress core would apply on its * own. */ if ( 'high' === $attr['fetchpriority'] ) { $loading_attrs['fetchpriority'] = 'high'; wp_high_priority_element_flag( false ); }
return $loading_attrs; }
// Lazy-loading and `fetchpriority="high"` are mutually exclusive. if ( isset( $loading_attrs['loading'] ) && 'lazy' === $loading_attrs['loading'] ) { return $loading_attrs; }
if ( ! wp_high_priority_element_flag() ) { return $loading_attrs; }
/** * Filters the minimum square-pixels threshold for an image to be eligible as the high-priority image. * * @since 6.3.0 * * @param int $threshold Minimum square-pixels threshold. Default 50000. */ $wp_min_priority_img_pixels = apply_filters( 'wp_min_priority_img_pixels', 50000 );
/** * Accesses a flag that indicates if an element is a possible candidate for `fetchpriority='high'`. * * @since 6.3.0 * @access private * * @param bool $value Optional. Used to change the static variable. Default null. * @return bool Returns true if high-priority element was marked already, otherwise false. */ function wp_high_priority_element_flag( $value = null ) { static $high_priority_element = true;
/** * Determines the output format for the image editor. * * @since 6.7.0 * @access private * * @param string $filename Path to the image. * @param string $mime_type The source image mime type. * @return string[] An array of mime type mappings. */ function wp_get_image_editor_output_format( $filename, $mime_type ) { $output_format = array( 'image/heic' => 'image/jpeg', 'image/heif' => 'image/jpeg', 'image/heic-sequence' => 'image/jpeg', 'image/heif-sequence' => 'image/jpeg', );
/** * Filters the image editor output format mapping. * * Enables filtering the mime type used to save images. By default HEIC/HEIF images * are converted to JPEGs. * * @see WP_Image_Editor::get_output_format() * * @since 5.8.0 * @since 6.7.0 The default was changed from an empty array to an array * containing the HEIC/HEIF images mime types. * * @param string[] $output_format { * An array of mime type mappings. Maps a source mime type to a new * destination mime type. By default maps HEIC/HEIF input to JPEG output. * * @type string ...$0 The new mime type. * } * @param string $filename Path to the image. * @param string $mime_type The source image mime type. */ return apply_filters( 'image_editor_output_format', $output_format, $filename, $mime_type ); }