diff --git a/src/wp-admin/includes/misc.php b/src/wp-admin/includes/misc.php
index 3c55f3f59a..8c4caa468d 100644
--- a/src/wp-admin/includes/misc.php
+++ b/src/wp-admin/includes/misc.php
@@ -1658,6 +1658,7 @@ function wp_check_php_version() {
* @type bool $dismissible Optional. Whether the admin notice is dismissible. Default false.
* @type string $id Optional. The value of the admin notice's ID attribute. Default empty string.
* @type string[] $additional_classes Optional. A string array of class names. Default empty array.
+ * @type string[] $attributes Optional. Additional attributes for the notice div. Default empty array.
* @type bool $paragraph_wrap Optional. Whether to wrap the message in paragraph tags. Default true.
* }
* @return string The markup for an admin notice.
@@ -1668,6 +1669,7 @@ function wp_get_admin_notice( $message, $args = array() ) {
'dismissible' => false,
'id' => '',
'additional_classes' => array(),
+ 'attributes' => array(),
'paragraph_wrap' => true,
);
@@ -1681,9 +1683,10 @@ function wp_get_admin_notice( $message, $args = array() ) {
* @param array $args The arguments for the admin notice.
* @param string $message The message for the admin notice.
*/
- $args = apply_filters( 'wp_admin_notice_args', $args, $message );
- $id = '';
- $classes = 'notice';
+ $args = apply_filters( 'wp_admin_notice_args', $args, $message );
+ $id = '';
+ $classes = 'notice';
+ $attributes = '';
if ( is_string( $args['id'] ) ) {
$trimmed_id = trim( $args['id'] );
@@ -1721,11 +1724,24 @@ function wp_get_admin_notice( $message, $args = array() ) {
$classes .= ' ' . implode( ' ', $args['additional_classes'] );
}
+ if ( is_array( $args['attributes'] ) && ! empty( $args['attributes'] ) ) {
+ $attributes = '';
+ foreach ( $args['attributes'] as $attr => $val ) {
+ if ( is_bool( $val ) ) {
+ $attributes .= $val ? ' ' . $attr : '';
+ } elseif ( is_int( $attr ) ) {
+ $attributes .= ' ' . esc_attr( trim( $val ) );
+ } elseif ( $val ) {
+ $attributes .= ' ' . $attr . '="' . esc_attr( trim( $val ) ) . '"';
+ }
+ }
+ }
+
if ( false !== $args['paragraph_wrap'] ) {
$message = "
$message
";
}
- $markup = sprintf( '%3$s
', $id, $classes, $message );
+ $markup = sprintf( '%4$s
', $id, $classes, $attributes, $message );
/**
* Filters the markup for an admin notice.
diff --git a/src/wp-includes/kses.php b/src/wp-includes/kses.php
index f6bd75741d..a707c62de2 100644
--- a/src/wp-includes/kses.php
+++ b/src/wp-includes/kses.php
@@ -2645,12 +2645,14 @@ function _wp_add_global_attributes( $value ) {
'aria-describedby' => true,
'aria-details' => true,
'aria-expanded' => true,
+ 'aria-hidden' => true,
'aria-label' => true,
'aria-labelledby' => true,
- 'aria-hidden' => true,
+ 'aria-live' => true,
'class' => true,
'data-*' => true,
'dir' => true,
+ 'hidden' => true,
'id' => true,
'lang' => true,
'style' => true,
diff --git a/tests/phpunit/tests/admin/wpAdminNotice.php b/tests/phpunit/tests/admin/wpAdminNotice.php
index 2feca7de7c..d882c93457 100644
--- a/tests/phpunit/tests/admin/wpAdminNotice.php
+++ b/tests/phpunit/tests/admin/wpAdminNotice.php
@@ -212,6 +212,71 @@ class Tests_Admin_WpAdminNotice extends WP_UnitTestCase {
),
'expected' => 'A notice with additional classes that are not an array.
',
),
+ 'additional attribute with a value' => array(
+ 'message' => 'A notice with an additional attribute with a value.',
+ 'args' => array(
+ 'attributes' => array( 'aria-live' => 'assertive' ),
+ ),
+ 'expected' => 'A notice with an additional attribute with a value.
',
+ ),
+ 'additional hidden attribute' => array(
+ 'message' => 'A notice with the hidden attribute.',
+ 'args' => array(
+ 'attributes' => array( 'hidden' => true ),
+ ),
+ 'expected' => 'A notice with the hidden attribute.
',
+ ),
+ 'additional attribute no associative keys' => array(
+ 'message' => 'A notice with a boolean attribute without an associative key.',
+ 'args' => array(
+ 'attributes' => array( 'hidden' ),
+ ),
+ 'expected' => 'A notice with a boolean attribute without an associative key.
',
+ ),
+ 'additional attribute with role' => array(
+ 'message' => 'A notice with an additional attribute role.',
+ 'args' => array(
+ 'attributes' => array( 'role' => 'alert' ),
+ ),
+ 'expected' => 'A notice with an additional attribute role.
',
+ ),
+ 'multiple additional attributes' => array(
+ 'message' => 'A notice with multiple additional attributes.',
+ 'args' => array(
+ 'attributes' => array(
+ 'role' => 'alert',
+ 'data-test' => -1,
+ ),
+ ),
+ 'expected' => 'A notice with multiple additional attributes.
',
+ ),
+ 'data attribute with unsafe value' => array(
+ 'message' => 'A notice with an additional attribute with an unsafe value.',
+ 'args' => array(
+ 'attributes' => array( 'data-unsafe' => '' ),
+ ),
+ 'expected' => 'A notice with an additional attribute with an unsafe value.
',
+ ),
+ 'additional invalid attribute' => array(
+ 'message' => 'A notice with an additional attribute that is invalid.',
+ 'args' => array(
+ 'attributes' => array( 'not-valid' => 'not-valid' ),
+ ),
+ 'expected' => 'A notice with an additional attribute that is invalid.
',
+ ),
+ 'multiple attributes with "role", invalid, data-*, numeric, and boolean' => array(
+ 'message' => 'A notice with multiple attributes with "role", invalid, "data-*", numeric, and boolean.',
+ 'args' => array(
+ 'attributes' => array(
+ 'role' => 'alert',
+ 'disabled' => 'disabled',
+ 'data-name' => 'my-name',
+ 'data-id' => 1,
+ 'hidden',
+ ),
+ ),
+ 'expected' => 'A notice with multiple attributes with "role", invalid, "data-*", numeric, and boolean.
',
+ ),
'paragraph wrapping as a falsy value rather than (bool) false' => array(
'message' => 'A notice with paragraph wrapping as a falsy value rather than (bool) false.',
'args' => array(
diff --git a/tests/phpunit/tests/admin/wpGetAdminNotice.php b/tests/phpunit/tests/admin/wpGetAdminNotice.php
index b5ba311338..718fdf3d94 100644
--- a/tests/phpunit/tests/admin/wpGetAdminNotice.php
+++ b/tests/phpunit/tests/admin/wpGetAdminNotice.php
@@ -208,6 +208,64 @@ class Tests_Admin_WpGetAdminNotice extends WP_UnitTestCase {
),
'expected' => 'A notice with additional classes that are not an array.
',
),
+ 'additional attribute with a value' => array(
+ 'message' => 'A notice with an additional attribute with a value.',
+ 'args' => array(
+ 'attributes' => array( 'aria-live' => 'assertive' ),
+ ),
+ 'expected' => 'A notice with an additional attribute with a value.
',
+ ),
+ 'additional hidden attribute' => array(
+ 'message' => 'A notice with the hidden attribute.',
+ 'args' => array(
+ 'attributes' => array( 'hidden' => true ),
+ ),
+ 'expected' => 'A notice with the hidden attribute.
',
+ ),
+ 'additional attribute no associative keys' => array(
+ 'message' => 'A notice with a boolean attribute without an associative key.',
+ 'args' => array(
+ 'attributes' => array( 'hidden' ),
+ ),
+ 'expected' => 'A notice with a boolean attribute without an associative key.
',
+ ),
+ 'additional attribute with role' => array(
+ 'message' => 'A notice with an additional attribute role.',
+ 'args' => array(
+ 'attributes' => array( 'role' => 'alert' ),
+ ),
+ 'expected' => 'A notice with an additional attribute role.
',
+ ),
+ 'multiple additional attributes' => array(
+ 'message' => 'A notice with multiple additional attributes.',
+ 'args' => array(
+ 'attributes' => array(
+ 'role' => 'alert',
+ 'data-test' => -1,
+ ),
+ ),
+ 'expected' => 'A notice with multiple additional attributes.
',
+ ),
+ 'data attribute with unsafe value' => array(
+ 'message' => 'A notice with an additional attribute with an unsafe value.',
+ 'args' => array(
+ 'attributes' => array( 'data-unsafe' => '' ),
+ ),
+ 'expected' => 'A notice with an additional attribute with an unsafe value.
',
+ ),
+ 'multiple attributes with "role", invalid, data-*, numeric, and boolean' => array(
+ 'message' => 'A notice with multiple attributes with "role", invalid, "data-*", numeric, and boolean.',
+ 'args' => array(
+ 'attributes' => array(
+ 'role' => 'alert',
+ 'disabled' => 'disabled',
+ 'data-name' => 'my-name',
+ 'data-id' => 1,
+ 'hidden',
+ ),
+ ),
+ 'expected' => 'A notice with multiple attributes with "role", invalid, "data-*", numeric, and boolean.
',
+ ),
'paragraph wrapping as a falsy value rather than (bool) false' => array(
'message' => 'A notice with paragraph wrapping as a falsy value rather than (bool) false.',
'args' => array(