--- a/wp/wp-admin/includes/media.php Thu Sep 29 08:06:27 2022 +0200
+++ b/wp/wp-admin/includes/media.php Fri Sep 05 18:40:08 2025 +0200
@@ -145,7 +145,7 @@
}
if ( $url ) {
- $html = '<a href="' . esc_attr( $url ) . '"' . $rel . '>' . $html . '</a>';
+ $html = '<a href="' . esc_url( $url ) . '"' . $rel . '>' . $html . '</a>';
}
/**
@@ -254,6 +254,9 @@
*
* @access private
* @since 3.4.0
+ *
+ * @param array $matches Single regex match.
+ * @return string Cleaned up HTML for caption.
*/
function _cleanup_image_add_caption( $matches ) {
// Remove any line breaks from inside the tags.
@@ -385,7 +388,7 @@
}
// Use image exif/iptc data for title and caption defaults if possible.
- } elseif ( 0 === strpos( $type, 'image/' ) ) {
+ } elseif ( str_starts_with( $type, 'image/' ) ) {
$image_meta = wp_read_image_metadata( $file );
if ( $image_meta ) {
@@ -419,14 +422,18 @@
$attachment_id = wp_insert_attachment( $attachment, $file, $post_id, true );
if ( ! is_wp_error( $attachment_id ) ) {
- // Set a custom header with the attachment_id.
- // Used by the browser/client to resume creating image sub-sizes after a PHP fatal error.
+ /*
+ * Set a custom header with the attachment_id.
+ * Used by the browser/client to resume creating image sub-sizes after a PHP fatal error.
+ */
if ( ! headers_sent() ) {
header( 'X-WP-Upload-Attachment-ID: ' . $attachment_id );
}
- // The image sub-sizes are created during wp_generate_attachment_metadata().
- // This is generally slow and may cause timeouts or out of memory errors.
+ /*
+ * The image sub-sizes are created during wp_generate_attachment_metadata().
+ * This is generally slow and may cause timeouts or out of memory errors.
+ */
wp_update_attachment_metadata( $attachment_id, wp_generate_attachment_metadata( $attachment_id, $file ) );
}
@@ -520,12 +527,14 @@
* @since 5.3.0 Formalized the existing and already documented `...$args` parameter
* by adding it to the function signature.
*
- * @global int $body_id
+ * @global string $body_id
*
* @param callable $content_func Function that outputs the content.
* @param mixed ...$args Optional additional parameters to pass to the callback function when it's called.
*/
function wp_iframe( $content_func, ...$args ) {
+ global $body_id;
+
_wp_admin_html_begin();
?>
<title><?php bloginfo( 'name' ); ?> › <?php _e( 'Uploads' ); ?> — <?php _e( 'WordPress' ); ?></title>
@@ -534,8 +543,8 @@
wp_enqueue_style( 'colors' );
// Check callback name for 'media'.
if (
- ( is_array( $content_func ) && ! empty( $content_func[1] ) && 0 === strpos( (string) $content_func[1], 'media' ) ) ||
- ( ! is_array( $content_func ) && 0 === strpos( $content_func, 'media' ) )
+ ( is_array( $content_func ) && ! empty( $content_func[1] ) && str_starts_with( (string) $content_func[1], 'media' ) ) ||
+ ( ! is_array( $content_func ) && str_starts_with( $content_func, 'media' ) )
) {
wp_enqueue_style( 'deprecated-media' );
}
@@ -596,8 +605,8 @@
$body_id_attr = '';
- if ( isset( $GLOBALS['body_id'] ) ) {
- $body_id_attr = ' id="' . $GLOBALS['body_id'] . '"';
+ if ( isset( $body_id ) ) {
+ $body_id_attr = ' id="' . $body_id . '"';
}
?>
@@ -631,7 +640,7 @@
*/
function media_buttons( $editor_id = 'content' ) {
static $instance = 0;
- $instance++;
+ ++$instance;
$post = get_post();
@@ -674,11 +683,16 @@
}
/**
+ * Retrieves the upload iframe source URL.
+ *
+ * @since 3.0.0
+ *
* @global int $post_ID
- * @param string $type
- * @param int $post_id
- * @param string $tab
- * @return string
+ *
+ * @param string $type Media type.
+ * @param int $post_id Post ID.
+ * @param string $tab Media upload tab.
+ * @return string Upload iframe source URL.
*/
function get_upload_iframe_src( $type = null, $post_id = null, $tab = null ) {
global $post_ID;
@@ -823,7 +837,7 @@
if ( ! empty( $attachment['url'] ) ) {
$rel = '';
- if ( strpos( $attachment['url'], 'attachment_id' ) || get_attachment_link( $send_id ) == $attachment['url'] ) {
+ if ( str_contains( $attachment['url'], 'attachment_id' ) || get_attachment_link( $send_id ) === $attachment['url'] ) {
$rel = " rel='attachment wp-att-" . esc_attr( $send_id ) . "'";
}
@@ -917,7 +931,7 @@
* @param string $src Media source URL.
* @param string $title Media title.
*/
- $html = apply_filters( "{$type}_send_to_editor_url", $html, esc_url_raw( $src ), $title );
+ $html = apply_filters( "{$type}_send_to_editor_url", $html, sanitize_url( $src ), $title );
} else {
$align = '';
$alt = esc_attr( wp_unslash( $_POST['alt'] ) );
@@ -942,7 +956,7 @@
* @param string $align The image alignment. Default 'alignnone'. Possible values include
* 'alignleft', 'aligncenter', 'alignright', 'alignnone'.
*/
- $html = apply_filters( 'image_send_to_editor_url', $html, esc_url_raw( $src ), $alt, $align );
+ $html = apply_filters( 'image_send_to_editor_url', $html, sanitize_url( $src ), $alt, $align );
}
return media_send_to_editor( $html );
@@ -988,6 +1002,7 @@
* @since 5.3.0 The `$post_id` parameter was made optional.
* @since 5.4.0 The original URL of the attachment is stored in the `_source_url`
* post meta value.
+ * @since 5.8.0 Added 'webp' to the default list of allowed file extensions.
*
* @param string $file The URL of the image to download.
* @param int $post_id Optional. The post ID the media is to be associated with.
@@ -1012,8 +1027,10 @@
* - `jpe`
* - `png`
* - `gif`
+ * - `webp`
*
* @since 5.6.0
+ * @since 5.8.0 Added 'webp' to the default list of allowed file extensions.
*
* @param string[] $allowed_extensions Array of allowed file extensions.
* @param string $file The URL of the image to download.
@@ -1150,16 +1167,16 @@
$checked = 'none';
}
- $out = array();
+ $output = array();
foreach ( $alignments as $name => $label ) {
- $name = esc_attr( $name );
- $out[] = "<input type='radio' name='attachments[{$post->ID}][align]' id='image-align-{$name}-{$post->ID}' value='$name'" .
+ $name = esc_attr( $name );
+ $output[] = "<input type='radio' name='attachments[{$post->ID}][align]' id='image-align-{$name}-{$post->ID}' value='$name'" .
( $checked == $name ? " checked='checked'" : '' ) .
" /><label for='image-align-{$name}-{$post->ID}' class='align image-align-{$name}-label'>$label</label>";
}
- return implode( "\n", $out );
+ return implode( "\n", $output );
}
/**
@@ -1194,7 +1211,7 @@
$check = get_user_setting( 'imgsize', 'medium' );
}
- $out = array();
+ $output = array();
foreach ( $size_names as $size => $label ) {
$downsize = image_downsize( $post->ID, $size );
@@ -1230,13 +1247,13 @@
}
$html .= '</div>';
- $out[] = $html;
+ $output[] = $html;
}
return array(
'label' => __( 'Size' ),
'input' => 'html',
- 'html' => implode( "\n", $out ),
+ 'html' => implode( "\n", $output ),
);
}
@@ -1269,8 +1286,8 @@
return "
<input type='text' class='text urlfield' name='attachments[$post->ID][url]' value='" . esc_attr( $url ) . "' /><br />
<button type='button' class='button urlnone' data-link-url=''>" . __( 'None' ) . "</button>
- <button type='button' class='button urlfile' data-link-url='" . esc_attr( $file ) . "'>" . __( 'File URL' ) . "</button>
- <button type='button' class='button urlpost' data-link-url='" . esc_attr( $link ) . "'>" . __( 'Attachment Post URL' ) . '</button>
+ <button type='button' class='button urlfile' data-link-url='" . esc_url( $file ) . "'>" . __( 'File URL' ) . "</button>
+ <button type='button' class='button urlpost' data-link-url='" . esc_url( $link ) . "'>" . __( 'Attachment Post URL' ) . '</button>
';
}
@@ -1343,12 +1360,12 @@
function image_media_send_to_editor( $html, $attachment_id, $attachment ) {
$post = get_post( $attachment_id );
- if ( 'image' === substr( $post->post_mime_type, 0, 5 ) ) {
+ if ( str_starts_with( $post->post_mime_type, 'image' ) ) {
$url = $attachment['url'];
$align = ! empty( $attachment['align'] ) ? $attachment['align'] : 'none';
$size = ! empty( $attachment['image-size'] ) ? $attachment['image-size'] : 'medium';
$alt = ! empty( $attachment['image_alt'] ) ? $attachment['image_alt'] : '';
- $rel = ( strpos( $url, 'attachment_id' ) || get_attachment_link( $attachment_id ) === $url );
+ $rel = ( str_contains( $url, 'attachment_id' ) || get_attachment_link( $attachment_id ) === $url );
return get_image_send_to_editor( $attachment_id, $attachment['post_excerpt'], $attachment['post_title'], $align, $url, $rel, $size, $alt );
}
@@ -1454,7 +1471,7 @@
$form_fields = array_merge_recursive( $form_fields, (array) $errors );
// This was formerly in image_attachment_fields_to_edit().
- if ( 'image' === substr( $post->post_mime_type, 0, 5 ) ) {
+ if ( str_starts_with( $post->post_mime_type, 'image' ) ) {
$alt = get_post_meta( $post->ID, '_wp_attachment_image_alt', true );
if ( empty( $alt ) ) {
@@ -1647,7 +1664,8 @@
$meta = wp_get_attachment_metadata( $post->ID );
if ( isset( $meta['width'], $meta['height'] ) ) {
- $media_dims .= "<span id='media-dims-$post->ID'>{$meta['width']} × {$meta['height']}</span> ";
+ /* translators: 1: A number of pixels wide, 2: A number of pixels tall. */
+ $media_dims .= "<span id='media-dims-$post->ID'>" . sprintf( __( '%1$s by %2$s pixels' ), $meta['width'], $meta['height'] ) . '</span>';
}
/**
@@ -1698,8 +1716,7 @@
<tr><td colspan='2' class='imgedit-response' id='imgedit-response-$post->ID'></td></tr>\n
<tr><td style='display:none' colspan='2' class='image-editor' id='image-editor-$post->ID'></td></tr>\n
<tr><td colspan='2'><p class='media-types media-types-required-info'>" .
- /* translators: %s: Asterisk symbol (*). */
- sprintf( __( 'Required fields are marked %s' ), '<span class="required">*</span>' ) .
+ wp_required_field_message() .
"</p></td></tr>\n";
$defaults = array(
@@ -1779,7 +1796,7 @@
continue;
}
- $required = $field['required'] ? '<span class="required">*</span>' : '';
+ $required = $field['required'] ? ' ' . wp_required_field_indicator() : '';
$required_attr = $field['required'] ? ' required' : '';
$class = $id;
$class .= $field['required'] ? ' form-required' : '';
@@ -1970,7 +1987,7 @@
}
$readonly = ! $user_can_edit && ! empty( $field['taxonomy'] ) ? " readonly='readonly' " : '';
- $required = $field['required'] ? '<span class="required">*</span>' : '';
+ $required = $field['required'] ? ' ' . wp_required_field_indicator() : '';
$required_attr = $field['required'] ? ' required' : '';
$class = 'compat-field-' . $id;
$class .= $field['required'] ? ' form-required' : '';
@@ -2026,8 +2043,7 @@
if ( $item ) {
$item = '<p class="media-types media-types-required-info">' .
- /* translators: %s: Asterisk symbol (*). */
- sprintf( __( 'Required fields are marked %s' ), '<span class="required">*</span>' ) .
+ wp_required_field_message() .
'</p>' .
'<table class="compat-attachment-fields">' . $item . '</table>';
}
@@ -2070,13 +2086,11 @@
*
* @global string $type
* @global string $tab
- * @global bool $is_IE
- * @global bool $is_opera
*
* @param array $errors
*/
function media_upload_form( $errors = null ) {
- global $type, $tab, $is_IE, $is_opera;
+ global $type, $tab;
if ( ! _device_can_upload() ) {
echo '<p>' . sprintf(
@@ -2174,8 +2188,8 @@
*/
if (
wp_is_mobile() &&
- strpos( $_SERVER['HTTP_USER_AGENT'], 'OS 7_' ) !== false &&
- strpos( $_SERVER['HTTP_USER_AGENT'], 'like Mac OS X' ) !== false
+ str_contains( $_SERVER['HTTP_USER_AGENT'], 'OS 7_' ) &&
+ str_contains( $_SERVER['HTTP_USER_AGENT'], 'like Mac OS X' )
) {
$plupload_init['multi_selection'] = false;
}
@@ -2185,6 +2199,11 @@
$plupload_init['webp_upload_error'] = true;
}
+ // Check if AVIF images can be edited.
+ if ( ! wp_image_editor_supports( array( 'mime_type' => 'image/avif' ) ) ) {
+ $plupload_init['avif_upload_error'] = true;
+ }
+
/**
* Filters the default Plupload settings.
*
@@ -2255,7 +2274,12 @@
?>
<p id="async-upload-wrap">
- <label class="screen-reader-text" for="async-upload"><?php _e( 'Upload' ); ?></label>
+ <label class="screen-reader-text" for="async-upload">
+ <?php
+ /* translators: Hidden accessibility text. */
+ _e( 'Upload' );
+ ?>
+ </label>
<input type="file" name="async-upload" id="async-upload" />
<?php submit_button( __( 'Upload' ), 'primary', 'html-upload', false ); ?>
<a href="#" onclick="try{top.tb_remove();}catch(e){}; return false;"><?php _e( 'Cancel' ); ?></a>
@@ -2723,7 +2747,12 @@
<input type="hidden" name="context" value="<?php echo isset( $_GET['context'] ) ? esc_attr( $_GET['context'] ) : ''; ?>" />
<p id="media-search" class="search-box">
- <label class="screen-reader-text" for="media-search-input"><?php _e( 'Search Media' ); ?>:</label>
+ <label class="screen-reader-text" for="media-search-input">
+ <?php
+ /* translators: Hidden accessibility text. */
+ _e( 'Search Media:' );
+ ?>
+ </label>
<input type="search" id="media-search-input" name="s" value="<?php the_search_query(); ?>" />
<?php submit_button( __( 'Search Media' ), '', '', false ); ?>
</p>
@@ -2804,7 +2833,7 @@
'format' => '',
'prev_text' => __( '«' ),
'next_text' => __( '»' ),
- 'total' => ceil( $wp_query->found_posts / 10 ),
+ 'total' => (int) ceil( $wp_query->found_posts / 10 ),
'current' => $q['paged'],
)
);
@@ -2924,13 +2953,12 @@
return '
<p class="media-types"><label><input type="radio" name="media_type" value="image" id="image-only"' . checked( 'image-only', $view, false ) . ' /> ' . __( 'Image' ) . '</label> <label><input type="radio" name="media_type" value="generic" id="not-image"' . checked( 'not-image', $view, false ) . ' /> ' . __( 'Audio, Video, or Other File' ) . '</label></p>
<p class="media-types media-types-required-info">' .
- /* translators: %s: Asterisk symbol (*). */
- sprintf( __( 'Required fields are marked %s' ), '<span class="required">*</span>' ) .
+ wp_required_field_message() .
'</p>
<table class="describe ' . $table_class . '"><tbody>
<tr>
<th scope="row" class="label" style="width:130px;">
- <label for="src"><span class="alignleft">' . __( 'URL' ) . '</span> <span class="required">*</span></label>
+ <label for="src"><span class="alignleft">' . __( 'URL' ) . '</span> ' . wp_required_field_indicator() . '</label>
<span class="alignright" id="status_img"></span>
</th>
<td class="field"><input id="src" name="src" value="" type="text" required onblur="addExtImage.getImageData()" /></td>
@@ -2938,7 +2966,7 @@
<tr>
<th scope="row" class="label">
- <label for="title"><span class="alignleft">' . __( 'Title' ) . '</span> <span class="required">*</span></label>
+ <label for="title"><span class="alignleft">' . __( 'Title' ) . '</span> ' . wp_required_field_indicator() . '</label>
</th>
<td class="field"><input id="title" name="title" value="" type="text" required /></td>
</tr>
@@ -2947,7 +2975,7 @@
<tr class="image-only">
<th scope="row" class="label">
- <label for="alt"><span class="alignleft">' . __( 'Alternative Text' ) . '</span></label>
+ <label for="alt"><span class="alignleft">' . __( 'Alternative Text' ) . '</span> ' . wp_required_field_indicator() . '</label>
</th>
<td class="field"><input id="alt" name="alt" value="" type="text" required />
<p class="help">' . __( 'Alt text for the image, e.g. “The Mona Lisa”' ) . '</p></td>
@@ -3202,10 +3230,10 @@
?>
</div>
<div class="wp_attachment_details edit-form-section">
- <?php if ( 'image' === substr( $post->post_mime_type, 0, 5 ) ) : ?>
+ <?php if ( str_starts_with( $post->post_mime_type, 'image' ) ) : ?>
<p class="attachment-alt-text">
<label for="attachment_alt"><strong><?php _e( 'Alternative Text' ); ?></strong></label><br />
- <input type="text" class="widefat" name="_wp_attachment_image_alt" id="attachment_alt" aria-describedby="alt-text-description" value="<?php echo esc_attr( $alt_text ); ?>" />
+ <textarea class="widefat" name="_wp_attachment_image_alt" id="attachment_alt" aria-describedby="alt-text-description"><?php echo esc_attr( $alt_text ); ?></textarea>
</p>
<p class="attachment-alt-text-description" id="alt-text-description">
<?php
@@ -3213,11 +3241,12 @@
printf(
/* translators: 1: Link to tutorial, 2: Additional link attributes, 3: Accessibility text. */
__( '<a href="%1$s" %2$s>Learn how to describe the purpose of the image%3$s</a>. Leave empty if the image is purely decorative.' ),
- esc_url( 'https://www.w3.org/WAI/tutorials/images/decision-tree' ),
+ /* translators: Localized tutorial, if one exists. W3C Web Accessibility Initiative link has list of existing translations. */
+ esc_url( __( 'https://www.w3.org/WAI/tutorials/images/decision-tree/' ) ),
'target="_blank" rel="noopener"',
sprintf(
'<span class="screen-reader-text"> %s</span>',
- /* translators: Accessibility text. */
+ /* translators: Hidden accessibility text. */
__( '(opens in a new tab)' )
)
);
@@ -3238,7 +3267,14 @@
'textarea_name' => 'content',
'textarea_rows' => 5,
'media_buttons' => false,
- 'tinymce' => false,
+ /**
+ * Filters the TinyMCE argument for the media description field on the attachment details screen.
+ *
+ * @since 6.6.0
+ *
+ * @param bool $tinymce Whether to activate TinyMCE in media description field. Default false.
+ */
+ 'tinymce' => apply_filters( 'activate_tinymce_for_media_description', false ),
'quicktags' => $quicktags_settings,
);
@@ -3279,7 +3315,8 @@
$meta = wp_get_attachment_metadata( $attachment_id );
if ( isset( $meta['width'], $meta['height'] ) ) {
- $media_dims .= "<span id='media-dims-$attachment_id'>{$meta['width']} × {$meta['height']}</span> ";
+ /* translators: 1: A number of pixels wide, 2: A number of pixels tall. */
+ $media_dims .= "<span id='media-dims-$attachment_id'>" . sprintf( __( '%1$s by %2$s pixels' ), $meta['width'], $meta['height'] ) . '</span>';
}
/** This filter is documented in wp-admin/includes/media.php */
$media_dims = apply_filters( 'media_meta', $media_dims, $post );
@@ -3331,6 +3368,9 @@
<span class="success hidden" aria-hidden="true"><?php _e( 'Copied!' ); ?></span>
</span>
</div>
+ <div class="misc-pub-section misc-pub-download">
+ <a href="<?php echo esc_attr( $att_url ); ?>" download><?php _e( 'Download file' ); ?></a>
+ </div>
<div class="misc-pub-section misc-pub-filename">
<?php _e( 'File name:' ); ?> <strong><?php echo $filename; ?></strong>
</div>
@@ -3411,6 +3451,9 @@
echo ' ' . strtoupper( esc_html( $meta['bitrate_mode'] ) );
}
break;
+ case 'length_formatted':
+ echo human_readable_duration( $meta['length_formatted'] );
+ break;
default:
echo esc_html( $meta[ $key ] );
break;
@@ -3464,10 +3507,10 @@
if ( ! empty( $meta['original_image'] ) ) {
?>
- <div class="misc-pub-section misc-pub-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 ) ); ?>">
- <?php echo esc_html( wp_basename( wp_get_original_image_path( $attachment_id ) ) ); ?>
+ <strong><?php echo esc_html( wp_basename( wp_get_original_image_path( $attachment_id ) ) ); ?></strong>
</a>
</div>
<?php
@@ -3489,7 +3532,7 @@
if ( 'length' !== $key && ! empty( $list ) ) {
$metadata[ $key ] = wp_kses_post( reset( $list ) );
// Fix bug in byte stream analysis.
- if ( 'terms_of_use' === $key && 0 === strpos( $metadata[ $key ], 'yright notice.' ) ) {
+ if ( 'terms_of_use' === $key && str_starts_with( $metadata[ $key ], 'yright notice.' ) ) {
$metadata[ $key ] = 'Cop' . $metadata[ $key ];
}
}
@@ -3625,10 +3668,11 @@
*
* @since 4.9.0
*
- * @param array $metadata Filtered Video metadata.
- * @param string $file Path to video file.
- * @param string $file_format File format of video, as analyzed by getID3.
- * @param array $data Raw metadata from getID3.
+ * @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.
+ * Null if unknown.
+ * @param array $data Raw metadata from getID3.
*/
return apply_filters( 'wp_read_video_metadata', $metadata, $file, $file_format, $data );
}
@@ -3697,7 +3741,23 @@
wp_add_id3_tag_data( $metadata, $data );
- return $metadata;
+ $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.
+ *
+ * @since 6.1.0
+ *
+ * @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.
+ * Null if unknown.
+ * @param array $data Raw metadata from getID3.
+ */
+ return apply_filters( 'wp_read_audio_metadata', $metadata, $file, $file_format, $data );
}
/**
@@ -3812,7 +3872,7 @@
$referer = wp_get_referer();
if ( $referer ) {
- if ( false !== strpos( $referer, 'upload.php' ) ) {
+ if ( str_contains( $referer, 'upload.php' ) ) {
$location = remove_query_arg( array( 'attached', 'detach' ), $referer );
}
}