: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
<div class="misc-pub-section misc-pub-dimensions">
<?php _e( 'Dimensions:' ); ?> <strong><?php echo $media_dims; ?></strong>
if ( ! empty( $meta['original_image'] ) ) {
<div class="misc-pub-section misc-pub-original-image word-wrap-break-word">
<?php _e( 'Original image:' ); ?>
<a href="<?php echo esc_url( wp_get_original_image_url( $attachment_id ) ); ?>">
<strong><?php echo esc_html( wp_basename( wp_get_original_image_path( $attachment_id ) ) ); ?></strong>
* Parses ID3v2, ID3v1, and getID3 comments to extract usable data.
* @param array $metadata An existing array with data.
* @param array $data Data supplied by ID3 tags.
function wp_add_id3_tag_data( &$metadata, $data ) {
foreach ( array( 'id3v2', 'id3v1' ) as $version ) {
if ( ! empty( $data[ $version ]['comments'] ) ) {
foreach ( $data[ $version ]['comments'] as $key => $list ) {
if ( 'length' !== $key && ! empty( $list ) ) {
$metadata[ $key ] = wp_kses_post( reset( $list ) );
// Fix bug in byte stream analysis.
if ( 'terms_of_use' === $key && str_starts_with( $metadata[ $key ], 'yright notice.' ) ) {
$metadata[ $key ] = 'Cop' . $metadata[ $key ];
if ( ! empty( $data['id3v2']['APIC'] ) ) {
$image = reset( $data['id3v2']['APIC'] );
if ( ! empty( $image['data'] ) ) {
$metadata['image'] = array(
'data' => $image['data'],
'mime' => $image['image_mime'],
'width' => $image['image_width'],
'height' => $image['image_height'],
} elseif ( ! empty( $data['comments']['picture'] ) ) {
$image = reset( $data['comments']['picture'] );
if ( ! empty( $image['data'] ) ) {
$metadata['image'] = array(
'data' => $image['data'],
'mime' => $image['image_mime'],
* Retrieves metadata from a video file's ID3 tags.
* @param string $file Path to file.
* @return array|false Returns array of metadata, if found.
function wp_read_video_metadata( $file ) {
if ( ! file_exists( $file ) ) {
if ( ! defined( 'GETID3_TEMP_DIR' ) ) {
define( 'GETID3_TEMP_DIR', get_temp_dir() );
if ( ! class_exists( 'getID3', false ) ) {
require ABSPATH . WPINC . '/ID3/getid3.php';
// Required to get the `created_timestamp` value.
$id3->options_audiovideo_quicktime_ReturnAtomData = true; // phpcs:ignore WordPress.NamingConventions.ValidVariableName
$data = $id3->analyze( $file );
if ( isset( $data['video']['lossless'] ) ) {
$metadata['lossless'] = $data['video']['lossless'];
if ( ! empty( $data['video']['bitrate'] ) ) {
$metadata['bitrate'] = (int) $data['video']['bitrate'];
if ( ! empty( $data['video']['bitrate_mode'] ) ) {
$metadata['bitrate_mode'] = $data['video']['bitrate_mode'];
if ( ! empty( $data['filesize'] ) ) {
$metadata['filesize'] = (int) $data['filesize'];
if ( ! empty( $data['mime_type'] ) ) {
$metadata['mime_type'] = $data['mime_type'];
if ( ! empty( $data['playtime_seconds'] ) ) {
$metadata['length'] = (int) round( $data['playtime_seconds'] );
if ( ! empty( $data['playtime_string'] ) ) {
$metadata['length_formatted'] = $data['playtime_string'];
if ( ! empty( $data['video']['resolution_x'] ) ) {
$metadata['width'] = (int) $data['video']['resolution_x'];
if ( ! empty( $data['video']['resolution_y'] ) ) {
$metadata['height'] = (int) $data['video']['resolution_y'];
if ( ! empty( $data['fileformat'] ) ) {
$metadata['fileformat'] = $data['fileformat'];
if ( ! empty( $data['video']['dataformat'] ) ) {
$metadata['dataformat'] = $data['video']['dataformat'];
if ( ! empty( $data['video']['encoder'] ) ) {
$metadata['encoder'] = $data['video']['encoder'];
if ( ! empty( $data['video']['codec'] ) ) {
$metadata['codec'] = $data['video']['codec'];
if ( ! empty( $data['audio'] ) ) {
unset( $data['audio']['streams'] );
$metadata['audio'] = $data['audio'];
if ( empty( $metadata['created_timestamp'] ) ) {
$created_timestamp = wp_get_media_creation_timestamp( $data );
if ( false !== $created_timestamp ) {
$metadata['created_timestamp'] = $created_timestamp;
wp_add_id3_tag_data( $metadata, $data );
$file_format = isset( $metadata['fileformat'] ) ? $metadata['fileformat'] : null;
* Filters the array of metadata retrieved from a video.
* In core, usually this selection is what is stored.
* More complete data can be parsed from the `$data` parameter.
* @param array $metadata Filtered video metadata.
* @param string $file Path to video file.
* @param string|null $file_format File format of video, as analyzed by getID3.
* @param array $data Raw metadata from getID3.
return apply_filters( 'wp_read_video_metadata', $metadata, $file, $file_format, $data );
* Retrieves metadata from an audio file's ID3 tags.
* @param string $file Path to file.
* @return array|false Returns array of metadata, if found.
function wp_read_audio_metadata( $file ) {
if ( ! file_exists( $file ) ) {
if ( ! defined( 'GETID3_TEMP_DIR' ) ) {
define( 'GETID3_TEMP_DIR', get_temp_dir() );
if ( ! class_exists( 'getID3', false ) ) {
require ABSPATH . WPINC . '/ID3/getid3.php';
// Required to get the `created_timestamp` value.
$id3->options_audiovideo_quicktime_ReturnAtomData = true; // phpcs:ignore WordPress.NamingConventions.ValidVariableName
$data = $id3->analyze( $file );
if ( ! empty( $data['audio'] ) ) {
unset( $data['audio']['streams'] );
$metadata = $data['audio'];
if ( ! empty( $data['fileformat'] ) ) {
$metadata['fileformat'] = $data['fileformat'];
if ( ! empty( $data['filesize'] ) ) {
$metadata['filesize'] = (int) $data['filesize'];
if ( ! empty( $data['mime_type'] ) ) {
$metadata['mime_type'] = $data['mime_type'];
if ( ! empty( $data['playtime_seconds'] ) ) {
$metadata['length'] = (int) round( $data['playtime_seconds'] );
if ( ! empty( $data['playtime_string'] ) ) {
$metadata['length_formatted'] = $data['playtime_string'];
if ( empty( $metadata['created_timestamp'] ) ) {
$created_timestamp = wp_get_media_creation_timestamp( $data );
if ( false !== $created_timestamp ) {
$metadata['created_timestamp'] = $created_timestamp;
wp_add_id3_tag_data( $metadata, $data );
$file_format = isset( $metadata['fileformat'] ) ? $metadata['fileformat'] : null;
* Filters the array of metadata retrieved from an audio file.
* In core, usually this selection is what is stored.
* More complete data can be parsed from the `$data` parameter.
* @param array $metadata Filtered audio metadata.
* @param string $file Path to audio file.
* @param string|null $file_format File format of audio, as analyzed by getID3.
* @param array $data Raw metadata from getID3.
return apply_filters( 'wp_read_audio_metadata', $metadata, $file, $file_format, $data );
* Parses creation date from media metadata.
* The getID3 library doesn't have a standard method for getting creation dates,
* so the location of this data can vary based on the MIME type.
* @link https://github.com/JamesHeinrich/getID3/blob/master/structure.txt
* @param array $metadata The metadata returned by getID3::analyze().
* @return int|false A UNIX timestamp for the media's creation date if available
* or a boolean FALSE if a timestamp could not be determined.
function wp_get_media_creation_timestamp( $metadata ) {
if ( empty( $metadata['fileformat'] ) ) {
switch ( $metadata['fileformat'] ) {
if ( isset( $metadata['asf']['file_properties_object']['creation_date_unix'] ) ) {
$creation_date = (int) $metadata['asf']['file_properties_object']['creation_date_unix'];
if ( isset( $metadata['matroska']['comments']['creation_time'][0] ) ) {
$creation_date = strtotime( $metadata['matroska']['comments']['creation_time'][0] );
} elseif ( isset( $metadata['matroska']['info'][0]['DateUTC_unix'] ) ) {
$creation_date = (int) $metadata['matroska']['info'][0]['DateUTC_unix'];
if ( isset( $metadata['quicktime']['moov']['subatoms'][0]['creation_time_unix'] ) ) {
$creation_date = (int) $metadata['quicktime']['moov']['subatoms'][0]['creation_time_unix'];
* Encapsulates the logic for Attach/Detach actions.
* @global wpdb $wpdb WordPress database abstraction object.
* @param int $parent_id Attachment parent ID.
* @param string $action Optional. Attach/detach action. Accepts 'attach' or 'detach'.
function wp_media_attach_action( $parent_id, $action = 'attach' ) {
if ( ! current_user_can( 'edit_post', $parent_id ) ) {
wp_die( __( 'Sorry, you are not allowed to edit this post.' ) );
foreach ( (array) $_REQUEST['media'] as $attachment_id ) {
$attachment_id = (int) $attachment_id;
if ( ! current_user_can( 'edit_post', $attachment_id ) ) {
$ids_string = implode( ',', $ids );
if ( 'attach' === $action ) {
$result = $wpdb->query( $wpdb->prepare( "UPDATE $wpdb->posts SET post_parent = %d WHERE post_type = 'attachment' AND ID IN ( $ids_string )", $parent_id ) );
$result = $wpdb->query( "UPDATE $wpdb->posts SET post_parent = 0 WHERE post_type = 'attachment' AND ID IN ( $ids_string )" );
if ( isset( $result ) ) {
foreach ( $ids as $attachment_id ) {
* Fires when media is attached or detached from a post.
* @param string $action Attach/detach action. Accepts 'attach' or 'detach'.
* @param int $attachment_id The attachment ID.
* @param int $parent_id Attachment parent ID.
do_action( 'wp_media_attach_action', $action, $attachment_id, $parent_id );
clean_attachment_cache( $attachment_id );
$location = 'upload.php';
$referer = wp_get_referer();
if ( str_contains( $referer, 'upload.php' ) ) {
$location = remove_query_arg( array( 'attached', 'detach' ), $referer );
$key = 'attach' === $action ? 'attached' : 'detach';
$location = add_query_arg( array( $key => $result ), $location );
wp_redirect( $location );