diff --git a/src/wp-admin/includes/template.php b/src/wp-admin/includes/template.php
index b535b3acbfc66..93428dcc4ae6d 100644
--- a/src/wp-admin/includes/template.php
+++ b/src/wp-admin/includes/template.php
@@ -1974,6 +1974,8 @@ function get_settings_errors( $setting = '', $sanitize = false ) {
* @since 3.0.0
* @since 5.3.0 Legacy `error` and `updated` CSS classes are mapped to
* `notice-error` and `notice-success`.
+ * @since 7.2.0 Uses `wp_admin_notice()` to echo the notices so that the CSS
+ * classes, filters, and hooks are handled consistently.
*
* @param string $setting Optional slug title of a specific setting whose errors you want.
* @param bool $sanitize Whether to re-sanitize the setting value before returning errors.
@@ -1992,32 +1994,49 @@ function settings_errors( $setting = '', $sanitize = false, $hide_on_update = fa
return;
}
- $output = '';
-
foreach ( $settings_errors as $key => $details ) {
- if ( 'updated' === $details['type'] ) {
- $details['type'] = 'success';
+ $type = trim( $details['type'] );
+
+ if ( 'updated' === $type ) {
+ $type = 'success';
}
- if ( in_array( $details['type'], array( 'error', 'success', 'warning', 'info' ), true ) ) {
- $details['type'] = 'notice-' . $details['type'];
+ $additional_classes = array( 'settings-error' );
+
+ /*
+ * Backward compatibility: `wp_admin_notice()` generates the admin notice
+ * CSS classes based on the passed message type. For example, 'error',
+ * 'success', 'warning', 'info'. Custom types will be treated as
+ * additional classes and appended to the end of the CSS classes.
+ */
+ if ( ! in_array( $type, array( 'error', 'success', 'warning', 'info' ), true ) ) {
+ $additional_classes = array_merge( $additional_classes, explode( ' ', $type ) );
+ $type = '';
}
- $css_id = sprintf(
+ /*
+ * Note that the setting error code contains underscores, for example:
+ * `settings_updated`. This will build a CSS ID selector that contains
+ * underscores, which are currently not allowed by the WordPress CSS
+ * Coding Standards. Kept for backwards compatibility.
+ */
+ $css_id = sprintf(
'setting-error-%s',
- esc_attr( $details['code'] )
- );
- $css_class = sprintf(
- 'notice %s settings-error is-dismissible',
- esc_attr( $details['type'] )
+ $details['code'],
);
- $output .= "
\n";
- $output .= "
{$details['message']}
";
- $output .= "
\n";
+ wp_admin_notice(
+ "{$details['message']}",
+ array(
+ 'type' => $type,
+ 'code' => $details['code'],
+ 'id' => $css_id,
+ 'paragraph_wrap' => true,
+ 'dismissible' => true,
+ 'additional_classes' => $additional_classes,
+ )
+ );
}
-
- echo $output;
}
/**
diff --git a/tests/phpunit/tests/admin/includesTemplate.php b/tests/phpunit/tests/admin/includesTemplate.php
index 4b9b8bc68034e..5e50cf8180e98 100644
--- a/tests/phpunit/tests/admin/includesTemplate.php
+++ b/tests/phpunit/tests/admin/includesTemplate.php
@@ -442,21 +442,28 @@ public function test_settings_errors_css_classes( $type, $expected ) {
$wp_settings_errors = null;
- $expected = sprintf( 'notice %s settings-error is-dismissible', $expected );
-
$this->assertStringContainsString( $expected, $output );
$this->assertStringNotContainsString( 'notice-notice-', $output );
}
public function data_settings_errors_css_classes() {
return array(
- array( 'error', 'notice-error' ),
- array( 'success', 'notice-success' ),
- array( 'warning', 'notice-warning' ),
- array( 'info', 'notice-info' ),
- array( 'updated', 'notice-success' ),
- array( 'notice-error', 'notice-error' ),
- array( 'error my-own-css-class hello world', 'error my-own-css-class hello world' ),
+ // The admin notices default types will generate CSS classes in this order.
+ array( 'error', 'notice notice-error is-dismissible settings-error' ),
+ array( 'success', 'notice notice-success is-dismissible settings-error' ),
+ array( 'warning', 'notice notice-warning is-dismissible settings-error' ),
+ array( 'info', 'notice notice-info is-dismissible settings-error' ),
+ array( 'updated', 'notice notice-success is-dismissible settings-error' ),
+ /*
+ * Backward compatibility: custom types and anything else (e.g.
+ * strings with spaces) are now passed as additional_classes. As
+ * such, the classes will be appended to the end of the generated
+ * class attribute.
+ */
+ array( 'notice-error', 'notice is-dismissible settings-error notice-error' ),
+ array( 'custom', 'notice is-dismissible settings-error custom' ),
+ array( 'error my-own-css-class hello world', 'notice is-dismissible settings-error error my-own-css-class hello world' ),
+ array( 'error my-notice-is-awesome hello world', 'notice is-dismissible settings-error error my-notice-is-awesome hello world' ),
);
}