Skip to content
53 changes: 36 additions & 17 deletions src/wp-admin/includes/template.php
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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 .= "<div id='$css_id' class='$css_class'> \n";
$output .= "<p><strong>{$details['message']}</strong></p>";
$output .= "</div> \n";
wp_admin_notice(
"<strong>{$details['message']}</strong>",
array(
'type' => $type,
'code' => $details['code'],
'id' => $css_id,
'paragraph_wrap' => true,
'dismissible' => true,
'additional_classes' => $additional_classes,
)
);
}

echo $output;
}

/**
Expand Down
25 changes: 16 additions & 9 deletions tests/phpunit/tests/admin/includesTemplate.php
Original file line number Diff line number Diff line change
Expand Up @@ -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' ),
);
}

Expand Down
Loading