$icon_colors = $_wp_admin_css_colors[ $color_scheme ]->icon_colors;
} elseif ( ! empty( $_wp_admin_css_colors['fresh']->icon_colors ) ) {
$icon_colors = $_wp_admin_css_colors['fresh']->icon_colors;
// Fall back to the default set of icon colors if the default scheme is missing.
echo '<script type="text/javascript">var _wpColorScheme = ' . wp_json_encode( array( 'icons' => $icon_colors ) ) . ";</script>\n";
* Displays the viewport meta in the admin.
function wp_admin_viewport_meta() {
* Filters the viewport meta in the admin.
* @param string $viewport_meta The viewport meta.
$viewport_meta = apply_filters( 'admin_viewport_meta', 'width=device-width,initial-scale=1.0' );
if ( empty( $viewport_meta ) ) {
echo '<meta name="viewport" content="' . esc_attr( $viewport_meta ) . '">';
* Adds viewport meta for mobile in Customizer.
* Hooked to the {@see 'admin_viewport_meta'} filter.
* @param string $viewport_meta The viewport meta.
* @return string Filtered viewport meta.
function _customizer_mobile_viewport_meta( $viewport_meta ) {
return trim( $viewport_meta, ',' ) . ',minimum-scale=0.5,maximum-scale=1.2';
* Check lock status for posts displayed on the Posts screen
* @param array $response The Heartbeat response.
* @param array $data The $_POST data sent.
* @param string $screen_id The screen ID.
* @return array The Heartbeat response.
function wp_check_locked_posts( $response, $data, $screen_id ) {
if ( array_key_exists( 'wp-check-locked-posts', $data ) && is_array( $data['wp-check-locked-posts'] ) ) {
foreach ( $data['wp-check-locked-posts'] as $key ) {
$post_id = absint( substr( $key, 5 ) );
$user_id = wp_check_post_lock( $post_id );
$user = get_userdata( $user_id );
if ( $user && current_user_can( 'edit_post', $post_id ) ) {
/* translators: %s: User's display name. */
'text' => sprintf( __( '%s is currently editing' ), $user->display_name ),
if ( get_option( 'show_avatars' ) ) {
$send['avatar_src'] = get_avatar_url( $user->ID, array( 'size' => 18 ) );
$send['avatar_src_2x'] = get_avatar_url( $user->ID, array( 'size' => 36 ) );
$checked[ $key ] = $send;
if ( ! empty( $checked ) ) {
$response['wp-check-locked-posts'] = $checked;
* Check lock status on the New/Edit Post screen and refresh the lock
* @param array $response The Heartbeat response.
* @param array $data The $_POST data sent.
* @param string $screen_id The screen ID.
* @return array The Heartbeat response.
function wp_refresh_post_lock( $response, $data, $screen_id ) {
if ( array_key_exists( 'wp-refresh-post-lock', $data ) ) {
$received = $data['wp-refresh-post-lock'];
$post_id = absint( $received['post_id'] );
if ( ! current_user_can( 'edit_post', $post_id ) ) {
$user_id = wp_check_post_lock( $post_id );
$user = get_userdata( $user_id );
/* translators: %s: User's display name. */
'text' => sprintf( __( '%s has taken over and is currently editing.' ), $user->display_name ),
if ( get_option( 'show_avatars' ) ) {
$error['avatar_src'] = get_avatar_url( $user->ID, array( 'size' => 64 ) );
$error['avatar_src_2x'] = get_avatar_url( $user->ID, array( 'size' => 128 ) );
$send['lock_error'] = $error;
$new_lock = wp_set_post_lock( $post_id );
$send['new_lock'] = implode( ':', $new_lock );
$response['wp-refresh-post-lock'] = $send;
* Check nonce expiration on the New/Edit Post screen and refresh if needed
* @param array $response The Heartbeat response.
* @param array $data The $_POST data sent.
* @param string $screen_id The screen ID.
* @return array The Heartbeat response.
function wp_refresh_post_nonces( $response, $data, $screen_id ) {
if ( array_key_exists( 'wp-refresh-post-nonces', $data ) ) {
$received = $data['wp-refresh-post-nonces'];
$response['wp-refresh-post-nonces'] = array( 'check' => 1 );
$post_id = absint( $received['post_id'] );
if ( ! current_user_can( 'edit_post', $post_id ) ) {
$response['wp-refresh-post-nonces'] = array(
'getpermalinknonce' => wp_create_nonce( 'getpermalink' ),
'samplepermalinknonce' => wp_create_nonce( 'samplepermalink' ),
'closedpostboxesnonce' => wp_create_nonce( 'closedpostboxes' ),
'_ajax_linking_nonce' => wp_create_nonce( 'internal-linking' ),
'_wpnonce' => wp_create_nonce( 'update-post_' . $post_id ),
* Add the latest Heartbeat and REST-API nonce to the Heartbeat response.
* @param array $response The Heartbeat response.
* @return array The Heartbeat response.
function wp_refresh_heartbeat_nonces( $response ) {
// Refresh the Rest API nonce.
$response['rest_nonce'] = wp_create_nonce( 'wp_rest' );
// Refresh the Heartbeat nonce.
$response['heartbeat_nonce'] = wp_create_nonce( 'heartbeat-nonce' );
* Disable suspension of Heartbeat on the Add/Edit Post screens.
* @global string $pagenow
* @param array $settings An array of Heartbeat settings.
* @return array Filtered Heartbeat settings.
function wp_heartbeat_set_suspension( $settings ) {
if ( 'post.php' === $pagenow || 'post-new.php' === $pagenow ) {
$settings['suspension'] = 'disable';
* Autosave with heartbeat
* @param array $response The Heartbeat response.
* @param array $data The $_POST data sent.
* @return array The Heartbeat response.
function heartbeat_autosave( $response, $data ) {
if ( ! empty( $data['wp_autosave'] ) ) {
$saved = wp_autosave( $data['wp_autosave'] );
if ( is_wp_error( $saved ) ) {
$response['wp_autosave'] = array(
'message' => $saved->get_error_message(),
} elseif ( empty( $saved ) ) {
$response['wp_autosave'] = array(
'message' => __( 'Error while saving.' ),
/* translators: Draft saved date format, see https://www.php.net/manual/datetime.format.php */
$draft_saved_date_format = __( 'g:i:s a' );
$response['wp_autosave'] = array(
/* translators: %s: Date and time. */
'message' => sprintf( __( 'Draft saved at %s.' ), date_i18n( $draft_saved_date_format ) ),
* Remove single-use URL parameters and create canonical link based on new URL.
* Remove specific query string parameters from a URL, create the canonical link,
* put it in the admin header, and change the current URL to match.
function wp_admin_canonical_url() {
$removable_query_args = wp_removable_query_args();
if ( empty( $removable_query_args ) ) {
// Ensure we're using an absolute URL.
$current_url = set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] );
$filtered_url = remove_query_arg( $removable_query_args, $current_url );
<link id="wp-admin-canonical" rel="canonical" href="<?php echo esc_url( $filtered_url ); ?>" />
if ( window.history.replaceState ) {
window.history.replaceState( null, null, document.getElementById( 'wp-admin-canonical' ).href + window.location.hash );
* Send a referrer policy header so referrers are not sent externally from administration screens.
function wp_admin_headers() {
$policy = 'strict-origin-when-cross-origin';
* Filters the admin referrer policy header value.
* @since 4.9.5 The default value was changed to 'strict-origin-when-cross-origin'.
* @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy
* @param string $policy The admin referrer policy header value. Default 'strict-origin-when-cross-origin'.
$policy = apply_filters( 'admin_referrer_policy', $policy );
header( sprintf( 'Referrer-Policy: %s', $policy ) );
* Outputs JS that reloads the page if the user navigated to it with the Back or Forward button.
* Used on the Edit Post and Add New Post screens. Needed to ensure the page is not loaded from browser cache,
* so the post title and editor content are the last saved versions. Ideally this script should run first in the head.
function wp_page_reload_on_back_button_js() {
if ( typeof performance !== 'undefined' && performance.navigation && performance.navigation.type === 2 ) {
document.location.reload( true );
* Send a confirmation request email when a change of site admin email address is attempted.
* The new site admin address will not become active until confirmed.
* @since 4.9.0 This function was moved from wp-admin/includes/ms.php so it's no longer Multisite specific.
* @param string $old_value The old site admin email address.
* @param string $value The proposed new site admin email address.
function update_option_new_admin_email( $old_value, $value ) {
if ( get_option( 'admin_email' ) === $value || ! is_email( $value ) ) {
$hash = md5( $value . time() . wp_rand() );
$new_admin_email = array(
update_option( 'adminhash', $new_admin_email );
$switched_locale = switch_to_locale( get_user_locale() );
/* translators: Do not translate USERNAME, ADMIN_URL, EMAIL, SITENAME, SITEURL: those are placeholders. */
You recently requested to have the administration email address on
If this is correct, please click on the following link to change it:
You can safely ignore and delete this email if you do not want to
This email has been sent to ###EMAIL###
* Filters the text of the email sent when a change of site admin email address is attempted.
* The following strings have a special meaning and will get replaced dynamically:
* ###USERNAME### The current user's username.
* ###ADMIN_URL### The link to click on to confirm the email change.
* ###EMAIL### The proposed new site admin email address.
* ###SITENAME### The name of the site.
* ###SITEURL### The URL to the site.
* @since 4.9.0 This filter is no longer Multisite specific.
* @param string $email_text Text in the email.
* @param array $new_admin_email {
* Data relating to the new site admin email address.
* @type string $hash The secure hash used in the confirmation link URL.
* @type string $newemail The proposed new site admin email address.
$content = apply_filters( 'new_admin_email_content', $email_text, $new_admin_email );
$current_user = wp_get_current_user();
$content = str_replace( '###USERNAME###', $current_user->user_login, $content );
$content = str_replace( '###ADMIN_URL###', esc_url( self_admin_url( 'options.php?adminhash=' . $hash ) ), $content );
$content = str_replace( '###EMAIL###', $value, $content );
$content = str_replace( '###SITENAME###', wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ), $content );
$content = str_replace( '###SITEURL###', home_url(), $content );
/* translators: New admin email address notification email subject. %s: Site title. */
__( '[%s] New Admin Email Address' ),
wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES )
if ( $switched_locale ) {
restore_previous_locale();
* Appends '(Draft)' to draft page titles in the privacy page dropdown
* so that unpublished content is obvious.
* @param string $title Page title.
* @param WP_Post $page Page data object.
* @return string Page title.
function _wp_privacy_settings_filter_draft_page_titles( $title, $page ) {
if ( 'draft' === $page->post_status && 'privacy' === get_current_screen()->id ) {
/* translators: %s: Page title. */
$title = sprintf( __( '%s (Draft)' ), $title );
* Checks if the user needs to update PHP.
* @since 5.1.1 Added the {@see 'wp_is_php_version_acceptable'} filter.
* @return array|false Array of PHP version data. False on failure.
function wp_check_php_version() {
$response = get_site_transient( 'php_check_' . $key );
if ( false === $response ) {
$url = 'http://api.wordpress.org/core/serve-happy/1.0/';
if ( wp_http_supports( array( 'ssl' ) ) ) {
$url = set_url_scheme( $url, 'https' );
$url = add_query_arg( 'php_version', $version, $url );
$response = wp_remote_get( $url );
if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) {
* Response should be an array with:
* 'recommended_version' - string - The PHP version recommended by WordPress.
* 'is_supported' - boolean - Whether the PHP version is actively supported.
* 'is_secure' - boolean - Whether the PHP version receives security updates.
* 'is_acceptable' - boolean - Whether the PHP version is still acceptable for WordPress.
$response = json_decode( wp_remote_retrieve_body( $response ), true );
if ( ! is_array( $response ) ) {
set_site_transient( 'php_check_' . $key, $response, WEEK_IN_SECONDS );
if ( isset( $response['is_acceptable'] ) && $response['is_acceptable'] ) {
* Filters whether the active PHP version is considered acceptable by WordPress.
* Returning false will trigger a PHP version warning to show up in the admin dashboard to administrators.
* This filter is only run if the wordpress.org Serve Happy API considers the PHP version acceptable, ensuring
* that this filter can only make this check stricter, but not loosen it.
* @param bool $is_acceptable Whether the PHP version is considered acceptable. Default true.
* @param string $version PHP version checked.
$response['is_acceptable'] = (bool) apply_filters( 'wp_is_php_version_acceptable', true, $version );