// The mime type must be allowed.
$allowed = get_allowed_mime_types();
if ( ! in_array( $type, $allowed, true ) ) {
* Filters the "real" file type of the given file.
* @since 5.1.0 The $real_mime parameter was added.
* @param array $wp_check_filetype_and_ext {
* Values for the extension, mime type, and corrected filename.
* @type string|false $ext File extension, or false if the file doesn't match a mime type.
* @type string|false $type File mime type, or false if the file doesn't match a mime type.
* @type string|false $proper_filename File name with its correct extension, or false if it cannot be determined.
* @param string $file Full path to the file.
* @param string $filename The name of the file (may differ from $file due to
* $file being in a tmp directory).
* @param string[] $mimes Array of mime types keyed by their file extension regex.
* @param string|false $real_mime The actual mime type or false if the type cannot be determined.
return apply_filters( 'wp_check_filetype_and_ext', compact( 'ext', 'type', 'proper_filename' ), $file, $filename, $mimes, $real_mime );
* Returns the real mime type of an image file.
* This depends on exif_imagetype() or getimagesize() to determine real mime types.
* @param string $file Full path to the file.
* @return string|false The actual mime type or false if the type cannot be determined.
function wp_get_image_mime( $file ) {
* Use exif_imagetype() to check the mimetype if available or fall back to
* getimagesize() if exif isn't avaialbe. If either function throws an Exception
* we assume the file could not be validated.
if ( is_callable( 'exif_imagetype' ) ) {
$imagetype = exif_imagetype( $file );
$mime = ( $imagetype ) ? image_type_to_mime_type( $imagetype ) : false;
} elseif ( function_exists( 'getimagesize' ) ) {
$imagesize = wp_getimagesize( $file );
$mime = ( isset( $imagesize['mime'] ) ) ? $imagesize['mime'] : false;
} catch ( Exception $e ) {
* Retrieve list of mime types and file extensions.
* @since 4.2.0 Support was added for GIMP (.xcf) files.
* @since 4.9.2 Support was added for Flac (.flac) files.
* @since 4.9.6 Support was added for AAC (.aac) files.
* @return string[] Array of mime types keyed by the file extension regex corresponding to those types.
function wp_get_mime_types() {
* Filters the list of mime types and file extensions.
* This filter should be used to add, not remove, mime types. To remove
* mime types, use the {@see 'upload_mimes'} filter.
* @param string[] $wp_get_mime_types Mime types keyed by the file extension regex
* corresponding to those types.
'jpg|jpeg|jpe' => 'image/jpeg',
'tiff|tif' => 'image/tiff',
'asf|asx' => 'video/x-ms-asf',
'wmv' => 'video/x-ms-wmv',
'wmx' => 'video/x-ms-wmx',
'mov|qt' => 'video/quicktime',
'mpeg|mpg|mpe' => 'video/mpeg',
'mp4|m4v' => 'video/mp4',
'mkv' => 'video/x-matroska',
'3gp|3gpp' => 'video/3gpp', // Can also be audio.
'3g2|3gp2' => 'video/3gpp2', // Can also be audio.
'txt|asc|c|cc|h|srt' => 'text/plain',
'tsv' => 'text/tab-separated-values',
'ics' => 'text/calendar',
'rtx' => 'text/richtext',
'htm|html' => 'text/html',
'dfxp' => 'application/ttaf+xml',
'mp3|m4a|m4b' => 'audio/mpeg',
'ra|ram' => 'audio/x-realaudio',
'ogg|oga' => 'audio/ogg',
'mid|midi' => 'audio/midi',
'wma' => 'audio/x-ms-wma',
'wax' => 'audio/x-ms-wax',
'mka' => 'audio/x-matroska',
// Misc application formats.
'rtf' => 'application/rtf',
'js' => 'application/javascript',
'pdf' => 'application/pdf',
'swf' => 'application/x-shockwave-flash',
'class' => 'application/java',
'tar' => 'application/x-tar',
'zip' => 'application/zip',
'gz|gzip' => 'application/x-gzip',
'rar' => 'application/rar',
'7z' => 'application/x-7z-compressed',
'exe' => 'application/x-msdownload',
'psd' => 'application/octet-stream',
'xcf' => 'application/octet-stream',
'doc' => 'application/msword',
'pot|pps|ppt' => 'application/vnd.ms-powerpoint',
'wri' => 'application/vnd.ms-write',
'xla|xls|xlt|xlw' => 'application/vnd.ms-excel',
'mdb' => 'application/vnd.ms-access',
'mpp' => 'application/vnd.ms-project',
'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'docm' => 'application/vnd.ms-word.document.macroEnabled.12',
'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template',
'dotm' => 'application/vnd.ms-word.template.macroEnabled.12',
'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'xlsm' => 'application/vnd.ms-excel.sheet.macroEnabled.12',
'xlsb' => 'application/vnd.ms-excel.sheet.binary.macroEnabled.12',
'xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template',
'xltm' => 'application/vnd.ms-excel.template.macroEnabled.12',
'xlam' => 'application/vnd.ms-excel.addin.macroEnabled.12',
'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
'pptm' => 'application/vnd.ms-powerpoint.presentation.macroEnabled.12',
'ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow',
'ppsm' => 'application/vnd.ms-powerpoint.slideshow.macroEnabled.12',
'potx' => 'application/vnd.openxmlformats-officedocument.presentationml.template',
'potm' => 'application/vnd.ms-powerpoint.template.macroEnabled.12',
'ppam' => 'application/vnd.ms-powerpoint.addin.macroEnabled.12',
'sldx' => 'application/vnd.openxmlformats-officedocument.presentationml.slide',
'sldm' => 'application/vnd.ms-powerpoint.slide.macroEnabled.12',
'onetoc|onetoc2|onetmp|onepkg' => 'application/onenote',
'oxps' => 'application/oxps',
'xps' => 'application/vnd.ms-xpsdocument',
'odt' => 'application/vnd.oasis.opendocument.text',
'odp' => 'application/vnd.oasis.opendocument.presentation',
'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
'odg' => 'application/vnd.oasis.opendocument.graphics',
'odc' => 'application/vnd.oasis.opendocument.chart',
'odb' => 'application/vnd.oasis.opendocument.database',
'odf' => 'application/vnd.oasis.opendocument.formula',
'wp|wpd' => 'application/wordperfect',
'key' => 'application/vnd.apple.keynote',
'numbers' => 'application/vnd.apple.numbers',
'pages' => 'application/vnd.apple.pages',
* Retrieves the list of common file extensions and their types.
* @return array[] Multi-dimensional array of file extensions types keyed by the type of file.
function wp_get_ext_types() {
* Filters file type based on the extension name.
* @param array[] $ext2type Multi-dimensional array of file extensions types keyed by the type of file.
'image' => array( 'jpg', 'jpeg', 'jpe', 'gif', 'png', 'bmp', 'tif', 'tiff', 'ico', 'heic' ),
'audio' => array( 'aac', 'ac3', 'aif', 'aiff', 'flac', 'm3a', 'm4a', 'm4b', 'mka', 'mp1', 'mp2', 'mp3', 'ogg', 'oga', 'ram', 'wav', 'wma' ),
'video' => array( '3g2', '3gp', '3gpp', 'asf', 'avi', 'divx', 'dv', 'flv', 'm4v', 'mkv', 'mov', 'mp4', 'mpeg', 'mpg', 'mpv', 'ogm', 'ogv', 'qt', 'rm', 'vob', 'wmv' ),
'document' => array( 'doc', 'docx', 'docm', 'dotm', 'odt', 'pages', 'pdf', 'xps', 'oxps', 'rtf', 'wp', 'wpd', 'psd', 'xcf' ),
'spreadsheet' => array( 'numbers', 'ods', 'xls', 'xlsx', 'xlsm', 'xlsb' ),
'interactive' => array( 'swf', 'key', 'ppt', 'pptx', 'pptm', 'pps', 'ppsx', 'ppsm', 'sldx', 'sldm', 'odp' ),
'text' => array( 'asc', 'csv', 'tsv', 'txt' ),
'archive' => array( 'bz2', 'cab', 'dmg', 'gz', 'rar', 'sea', 'sit', 'sqx', 'tar', 'tgz', 'zip', '7z' ),
'code' => array( 'css', 'htm', 'html', 'php', 'js' ),
* Retrieve list of allowed mime types and file extensions.
* @param int|WP_User $user Optional. User to check. Defaults to current user.
* @return string[] Array of mime types keyed by the file extension regex corresponding
function get_allowed_mime_types( $user = null ) {
$t = wp_get_mime_types();
unset( $t['swf'], $t['exe'] );
if ( function_exists( 'current_user_can' ) ) {
$unfiltered = $user ? user_can( $user, 'unfiltered_html' ) : current_user_can( 'unfiltered_html' );
if ( empty( $unfiltered ) ) {
unset( $t['htm|html'], $t['js'] );
* Filters list of allowed mime types and file extensions.
* @param array $t Mime types keyed by the file extension regex corresponding to those types.
* @param int|WP_User|null $user User ID, User object or null if not provided (indicates current user).
return apply_filters( 'upload_mimes', $t, $user );
* Display "Are You Sure" message to confirm the action being taken.
* If the action has the nonce explain message, then it will be displayed
* along with the "Are you sure?" message.
* @param string $action The nonce action.
function wp_nonce_ays( $action ) {
if ( 'log-out' === $action ) {
/* translators: %s: Site title. */
__( 'You are attempting to log out of %s' ),
$redirect_to = isset( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : '';
/* translators: %s: Logout URL. */
__( 'Do you really want to <a href="%s">log out</a>?' ),
wp_logout_url( $redirect_to )
$html = __( 'The link you followed has expired.' );
if ( wp_get_referer() ) {
$wp_http_referer = remove_query_arg( 'updated', wp_get_referer() );
$wp_http_referer = wp_validate_redirect( esc_url_raw( $wp_http_referer ) );
esc_url( $wp_http_referer ),
__( 'Please try again.' )
wp_die( $html, __( 'Something went wrong.' ), 403 );
* Kills WordPress execution and displays HTML page with an error message.
* This function complements the `die()` PHP function. The difference is that
* HTML will be displayed to the user. It is recommended to use this function
* only when the execution should not continue any further. It is not recommended
* to call this function very often, and try to handle as many errors as possible
* silently or more gracefully.
* As a shorthand, the desired HTTP response code may be passed as an integer to
* the `$title` parameter (the default title would apply) or the `$args` parameter.
* @since 4.1.0 The `$title` and `$args` parameters were changed to optionally accept
* an integer to be used as the response code.
* @since 5.1.0 The `$link_url`, `$link_text`, and `$exit` arguments were added.
* @since 5.3.0 The `$charset` argument was added.
* @since 5.5.0 The `$text_direction` argument has a priority over get_language_attributes()
* in the default handler.
* @global WP_Query $wp_query WordPress Query object.
* @param string|WP_Error $message Optional. Error message. If this is a WP_Error object,
* and not an Ajax or XML-RPC request, the error's messages are used.
* @param string|int $title Optional. Error title. If `$message` is a `WP_Error` object,
* error data with the key 'title' may be used to specify the title.
* If `$title` is an integer, then it is treated as the response
* @param string|array|int $args {
* Optional. Arguments to control behavior. If `$args` is an integer, then it is treated
* as the response code. Default empty array.
* @type int $response The HTTP response code. Default 200 for Ajax requests, 500 otherwise.
* @type string $link_url A URL to include a link to. Only works in combination with $link_text.
* @type string $link_text A label for the link to include. Only works in combination with $link_url.
* @type bool $back_link Whether to include a link to go back. Default false.
* @type string $text_direction The text direction. This is only useful internally, when WordPress is still
* loading and the site's locale is not set up yet. Accepts 'rtl' and 'ltr'.
* Default is the value of is_rtl().
* @type string $charset Character set of the HTML output. Default 'utf-8'.
* @type string $code Error code to use. Default is 'wp_die', or the main error code if $message
* @type bool $exit Whether to exit the process after completion. Default true.
function wp_die( $message = '', $title = '', $args = array() ) {
$args = array( 'response' => $args );
} elseif ( is_int( $title ) ) {
$args = array( 'response' => $title );
* Filters the callback for killing WordPress execution for Ajax requests.
* @param callable $function Callback function name.
$function = apply_filters( 'wp_die_ajax_handler', '_ajax_wp_die_handler' );
} elseif ( wp_is_json_request() ) {
* Filters the callback for killing WordPress execution for JSON requests.
* @param callable $function Callback function name.
$function = apply_filters( 'wp_die_json_handler', '_json_wp_die_handler' );
} elseif ( defined( 'REST_REQUEST' ) && REST_REQUEST && wp_is_jsonp_request() ) {
* Filters the callback for killing WordPress execution for JSONP REST requests.
* @param callable $function Callback function name.
$function = apply_filters( 'wp_die_jsonp_handler', '_jsonp_wp_die_handler' );
} elseif ( defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST ) {
* Filters the callback for killing WordPress execution for XML-RPC requests.
* @param callable $function Callback function name.
$function = apply_filters( 'wp_die_xmlrpc_handler', '_xmlrpc_wp_die_handler' );
} elseif ( wp_is_xml_request()
( function_exists( 'is_feed' ) && is_feed()
|| function_exists( 'is_comment_feed' ) && is_comment_feed()
|| function_exists( 'is_trackback' ) && is_trackback() ) ) {
* Filters the callback for killing WordPress execution for XML requests.
* @param callable $function Callback function name.
$function = apply_filters( 'wp_die_xml_handler', '_xml_wp_die_handler' );
* Filters the callback for killing WordPress execution for all non-Ajax, non-JSON, non-XML requests.
* @param callable $function Callback function name.
$function = apply_filters( 'wp_die_handler', '_default_wp_die_handler' );
call_user_func( $function, $message, $title, $args );
* Kills WordPress execution and displays HTML page with an error message.
* This is the default handler for wp_die(). If you want a custom one,
* you can override this using the {@see 'wp_die_handler'} filter in wp_die().
* @param string|WP_Error $message Error message or WP_Error object.
* @param string $title Optional. Error title. Default empty.
* @param string|array $args Optional. Arguments to control behavior. Default empty array.
function _default_wp_die_handler( $message, $title = '', $args = array() ) {
list( $message, $title, $parsed_args ) = _wp_die_process_input( $message, $title, $args );
if ( is_string( $message ) ) {
if ( ! empty( $parsed_args['additional_errors'] ) ) {
wp_list_pluck( $parsed_args['additional_errors'], 'message' )
$message = "<ul>\n\t\t<li>" . implode( "</li>\n\t\t<li>", $message ) . "</li>\n\t</ul>";
'<div class="wp-die-message">%s</div>',
$have_gettext = function_exists( '__' );
if ( ! empty( $parsed_args['link_url'] ) && ! empty( $parsed_args['link_text'] ) ) {
$link_url = $parsed_args['link_url'];
if ( function_exists( 'esc_url' ) ) {
$link_url = esc_url( $link_url );
$link_text = $parsed_args['link_text'];
$message .= "\n<p><a href='{$link_url}'>{$link_text}</a></p>";
if ( isset( $parsed_args['back_link'] ) && $parsed_args['back_link'] ) {
$back_text = $have_gettext ? __( '« Back' ) : '« Back';
$message .= "\n<p><a href='javascript:history.back()'>$back_text</a></p>";
if ( ! did_action( 'admin_head' ) ) :
if ( ! headers_sent() ) {
header( "Content-Type: text/html; charset={$parsed_args['charset']}" );
status_header( $parsed_args['response'] );
$text_direction = $parsed_args['text_direction'];
$dir_attr = "dir='$text_direction'";
// If `text_direction` was not explicitly passed,
// use get_language_attributes() if available.
if ( empty( $args['text_direction'] )
&& function_exists( 'language_attributes' ) && function_exists( 'is_rtl' )
$dir_attr = get_language_attributes();
<html <?php echo $dir_attr; ?>>
<meta http-equiv="Content-Type" content="text/html; charset=<?php echo $parsed_args['charset']; ?>" />
<meta name="viewport" content="width=device-width">
if ( function_exists( 'wp_robots' ) && function_exists( 'wp_robots_no_robots' ) && function_exists( 'add_filter' ) ) {
add_filter( 'wp_robots', 'wp_robots_no_robots' );