diff --git a/src/js/_enqueues/admin/common.js b/src/js/_enqueues/admin/common.js index 2a7daba0d2dc4..57d6fa927b27c 100644 --- a/src/js/_enqueues/admin/common.js +++ b/src/js/_enqueues/admin/common.js @@ -1087,7 +1087,11 @@ $( function() { if ( ! $headerEnd.length ) { $headerEnd = $( '.wrap h1, .wrap h2' ).first(); } - $( 'div.updated, div.error, div.notice' ).not( '.inline, .below-h2' ).insertAfter( $headerEnd ); + if ( $( '#wp-admin-notices' ).length ) { + $( '#wp-admin-notices' ).insertAfter( $headerEnd ); + } else { + $( 'div.updated, div.error, div.notice' ).not( '.inline, .below-h2' ).insertAfter( $headerEnd ); + } /** * Makes notices dismissible. diff --git a/src/js/_enqueues/wp/updates.js b/src/js/_enqueues/wp/updates.js index ef4b47e66093e..504e3a2a5e1db 100644 --- a/src/js/_enqueues/wp/updates.js +++ b/src/js/_enqueues/wp/updates.js @@ -267,6 +267,8 @@ $notice.replaceWith( $adminNotice ); } else if ( $headerEnd.length ) { $headerEnd.after( $adminNotice ); + } else if ( $( '#wp-admin-notices' ).length ) { + $( '#wp-admin-notices' ).append( $adminNotice ); } else { if ( 'customize' === pagenow ) { $( '.customize-themes-notifications' ).append( $adminNotice ); diff --git a/src/wp-admin/admin-header.php b/src/wp-admin/admin-header.php index e1e9ba0f6562b..f70edb156359d 100644 --- a/src/wp-admin/admin-header.php +++ b/src/wp-admin/admin-header.php @@ -78,6 +78,8 @@ $admin_title = sprintf( __( 'Recovery Mode — %s' ), $admin_title ); } +wp_capture_admin_notices(); + /** * Filters the title tag content for an admin page. * @@ -290,35 +292,7 @@ $current_screen->render_screen_meta(); -if ( is_network_admin() ) { - /** - * Prints network admin screen notices. - * - * @since 3.1.0 - */ - do_action( 'network_admin_notices' ); -} elseif ( is_user_admin() ) { - /** - * Prints user admin screen notices. - * - * @since 3.1.0 - */ - do_action( 'user_admin_notices' ); -} else { - /** - * Prints admin screen notices. - * - * @since 3.1.0 - */ - do_action( 'admin_notices' ); -} - -/** - * Prints generic admin screen notices. - * - * @since 3.1.0 - */ -do_action( 'all_admin_notices' ); +wp_render_admin_notices(); if ( 'options-general.php' === $parent_file ) { require ABSPATH . 'wp-admin/options-head.php'; diff --git a/src/wp-admin/includes/admin-filters.php b/src/wp-admin/includes/admin-filters.php index 5337cc02c88c9..cb0a0779077dd 100644 --- a/src/wp-admin/includes/admin-filters.php +++ b/src/wp-admin/includes/admin-filters.php @@ -116,6 +116,9 @@ // Theme Install hooks. add_action( 'install_themes_pre_theme-information', 'install_theme_information' ); +// Admin notices hooks. +add_filter( 'admin_title', 'wp_prepend_admin_notices_count_to_admin_title' ); + // User hooks. add_action( 'admin_init', 'default_password_nag_handler' ); diff --git a/src/wp-admin/includes/admin-notices.php b/src/wp-admin/includes/admin-notices.php new file mode 100644 index 0000000000000..d4df1629bd1bd --- /dev/null +++ b/src/wp-admin/includes/admin-notices.php @@ -0,0 +1,163 @@ + $html, + 'count' => wp_count_admin_notices_from_html( $html ), + ); + + return $wp_captured_admin_notices; +} + +/** + * Determines whether admin notices are present for the current screen. + * + * @since 7.1.0 + * + * @return bool Whether admin notices are present. + */ +function wp_has_admin_notices() { + $notices = wp_capture_admin_notices(); + + return $notices['count'] > 0; +} + +/** + * Returns the number of admin notices for the current screen. + * + * @since 7.1.0 + * + * @return int The number of admin notices. + */ +function wp_get_admin_notices_count() { + $notices = wp_capture_admin_notices(); + + return $notices['count']; +} + +/** + * Counts non-inline admin notices in the given HTML markup. + * + * @since 7.1.0 + * + * @param string $html Admin notices HTML markup. + * @return int The number of admin notices. + */ +function wp_count_admin_notices_from_html( $html ) { + if ( '' === trim( $html ) ) { + return 0; + } + + $count = 0; + + if ( preg_match_all( '/