: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
foreach ( $default_types as $type ) {
$defaults_atts[ $type ] = '';
$atts = shortcode_atts( $defaults_atts, $attr, 'video' );
// Shrink the video so it isn't huge in the admin.
if ( $atts['width'] > $defaults_atts['width'] ) {
$atts['height'] = round( ( $atts['height'] * $defaults_atts['width'] ) / $atts['width'] );
$atts['width'] = $defaults_atts['width'];
// If the video is bigger than the theme.
if ( ! empty( $content_width ) && $atts['width'] > $content_width ) {
$atts['height'] = round( ( $atts['height'] * $content_width ) / $atts['width'] );
$atts['width'] = $content_width;
$yt_pattern = '#^https?://(?:www\.)?(?:youtube\.com/watch|youtu\.be/)#';
$vimeo_pattern = '#^https?://(.+\.)?vimeo\.com/.*#';
if ( ! empty( $atts['src'] ) ) {
$is_vimeo = ( preg_match( $vimeo_pattern, $atts['src'] ) );
$is_youtube = ( preg_match( $yt_pattern, $atts['src'] ) );
if ( ! $is_youtube && ! $is_vimeo ) {
$type = wp_check_filetype( $atts['src'], wp_get_mime_types() );
if ( ! in_array( strtolower( $type['ext'] ), $default_types, true ) ) {
return sprintf( '<a class="wp-embedded-video" href="%s">%s</a>', esc_url( $atts['src'] ), esc_html( $atts['src'] ) );
wp_enqueue_script( 'mediaelement-vimeo' );
array_unshift( $default_types, 'src' );
foreach ( $default_types as $ext ) {
if ( ! empty( $atts[ $ext ] ) ) {
$type = wp_check_filetype( $atts[ $ext ], wp_get_mime_types() );
if ( strtolower( $type['ext'] ) === $ext ) {
$videos = get_attached_media( 'video', $post_id );
if ( empty( $videos ) ) {
$video = reset( $videos );
$atts['src'] = wp_get_attachment_url( $video->ID );
if ( empty( $atts['src'] ) ) {
array_unshift( $default_types, 'src' );
* Filters the media library used for the video shortcode.
* @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 ) {
// 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' );
// 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 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 );
'class' => $atts['class'],
'id' => sprintf( 'video-%d-%d', $post_id, $instance ),
'width' => absint( $atts['width'] ),
'height' => absint( $atts['height'] ),
'poster' => esc_url( $atts['poster'] ),
'loop' => wp_validate_boolean( $atts['loop'] ),
'autoplay' => wp_validate_boolean( $atts['autoplay'] ),
'muted' => wp_validate_boolean( $atts['muted'] ),
'preload' => $atts['preload'],
// 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 ] );
foreach ( $html_atts as $k => $v ) {
$attr_strings[] = $k . '="' . esc_attr( $v ) . '"';
if ( 'mediaelement' === $library && 1 === $instance ) {
$html .= "<!--[if lt IE 9]><script>document.createElement('video');</script><![endif]-->\n";
$html .= sprintf( '<video %s controls="controls">', implode( ' ', $attr_strings ) );
$source = '<source type="%s" src="%s" />';
foreach ( $default_types as $fallback ) {
if ( ! empty( $atts[ $fallback ] ) ) {
if ( empty( $fileurl ) ) {
$fileurl = $atts[ $fallback ];
if ( 'src' === $fallback && $is_youtube ) {
$type = array( 'type' => 'video/youtube' );
} elseif ( 'src' === $fallback && $is_vimeo ) {
$type = array( 'type' => 'video/vimeo' );
$type = wp_check_filetype( $atts[ $fallback ], wp_get_mime_types() );
$url = add_query_arg( '_', $instance, $atts[ $fallback ] );
$html .= sprintf( $source, $type['type'], esc_url( $url ) );
if ( ! empty( $content ) ) {
if ( str_contains( $content, "\n" ) ) {
$content = str_replace( array( "\r\n", "\n", "\t" ), '', $content );
$html .= trim( $content );
if ( 'mediaelement' === $library ) {
$html .= wp_mediaelement_fallback( $fileurl );
if ( ! empty( $atts['width'] ) ) {
$width_rule = sprintf( 'width: %dpx;', $atts['width'] );
$output = sprintf( '<div style="%s" class="wp-video">%s</div>', $width_rule, $html );
* Filters the output of the video shortcode.
* @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.
* @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.
* @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.
* @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.
* @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.
* @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 ) {
$attachments = array_values(
'post_parent' => $post->post_parent,
'post_status' => 'inherit',
'post_type' => 'attachment',
'post_mime_type' => 'image',
'orderby' => 'menu_order ID',
foreach ( $attachments as $k => $attachment ) {
if ( (int) $attachment->ID === (int) $post->ID ) {
$k = $prev ? $k - 1 : $k + 1;
if ( isset( $attachments[ $k ] ) ) {
$attachment_id = $attachments[ $k ]->ID;
$attr = array( 'alt' => get_the_title( $attachment_id ) );
$output = wp_get_attachment_link( $attachment_id, $size, true, false, $text, $attr );
$adjacent = $prev ? 'previous' : 'next';
* 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:
* - `previous_image_link`
* @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.
* @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 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.
* @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;
if ( ! is_object( $attachment ) ) {
$file = get_attached_file( $attachment->ID );
$filename = wp_basename( $file );
$objects = array( 'attachment' );
if ( str_contains( $filename, '.' ) ) {
$objects[] = 'attachment:' . substr( $filename, strrpos( $filename, '.' ) + 1 );
if ( ! empty( $attachment->post_mime_type ) ) {
$objects[] = 'attachment:' . $attachment->post_mime_type;
if ( str_contains( $attachment->post_mime_type, '/' ) ) {
foreach ( explode( '/', $attachment->post_mime_type ) as $token ) {
if ( ! empty( $token ) ) {
$objects[] = "attachment:$token";
foreach ( $objects as $object ) {
$taxes = get_object_taxonomies( $object, $output );
$taxonomies = array_merge( $taxonomies, $taxes );
if ( 'names' === $output ) {
$taxonomies = array_unique( $taxonomies );
* Retrieves all of the taxonomies that are registered for attachments.
* Handles mime-type-specific taxonomies such as attachment:image and attachment:video.
* @param string $output Optional. The type of taxonomy output to return. Accepts 'names' or 'objects'.
* @return string[]|WP_Taxonomy[] Array of names or objects of registered taxonomies for attachments.
function get_taxonomies_for_attachments( $output = 'names' ) {
foreach ( get_taxonomies( array(), 'objects' ) as $taxonomy ) {
foreach ( $taxonomy->object_type as $object_type ) {
if ( 'attachment' === $object_type || str_starts_with( $object_type, 'attachment:' ) ) {
if ( 'names' === $output ) {
$taxonomies[] = $taxonomy->name;
$taxonomies[ $taxonomy->name ] = $taxonomy;
* 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.
* @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,
function is_gd_image( $image ) {
if ( $image instanceof GdImage
|| is_resource( $image ) && 'gd' === get_resource_type( $image )
* Creates a new GD image resource with transparency support.
* @todo Deprecate if possible.
* @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.
function wp_imagecreatetruecolor( $width, $height ) {
$img = imagecreatetruecolor( $width, $height );
&& function_exists( 'imagealphablending' ) && function_exists( 'imagesavealpha' )
imagealphablending( $img, false );
imagesavealpha( $img, true );
* Based on a supplied width/height example, returns the biggest possible dimensions based on the max width/height.
* @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.
* An array of maximum width and height values.