@@ -8756,14 +8756,24 @@ function wp_fuzzy_number_match( $expected, $actual, $precision = 1 ) {
87568756 * @param array $args {
87578757 * Optional. An array of arguments for the admin notice. Default empty array.
87588758 *
8759- * @type string $type Optional. The type of admin notice.
8760- * For example, 'error', 'success', 'warning', 'info'.
8761- * Default empty string.
8762- * @type bool $dismissible Optional. Whether the admin notice is dismissible. Default false.
8763- * @type string $id Optional. The value of the admin notice's ID attribute. Default empty string.
8764- * @type string[] $additional_classes Optional. A string array of class names. Default empty array.
8765- * @type string[] $attributes Optional. Additional attributes for the notice div. Default empty array.
8766- * @type bool $paragraph_wrap Optional. Whether to wrap the message in paragraph tags. Default true.
8759+ * @type string $type Optional. The type of admin notice.
8760+ * For example, 'error', 'success', 'warning', 'info'.
8761+ * Default empty string.
8762+ * @type bool|array $dismissible {
8763+ * Optional. Whether the admin notice is dismissible. Default false.
8764+ *
8765+ * If false, the notice is not dismissible.
8766+ * If true, the notice is dismissible until the next page load.
8767+ * If an array, the notice will be dismissed either permanently,
8768+ * or until the specified expiration has occurred.
8769+ *
8770+ * @type string $slug The slug of the notice. Used to store a transient when the notice is dismissed.
8771+ * @type int $expiration Optional. Time until expiration in seconds. Default 0 (no expiration).
8772+ * }
8773+ * @type string $id Optional. The value of the admin notice's ID attribute. Default empty string.
8774+ * @type string[] $additional_classes Optional. A string array of class names. Default empty array.
8775+ * @type string[] $attributes Optional. Additional attributes for the notice div. Default empty array.
8776+ * @type bool $paragraph_wrap Optional. Whether to wrap the message in paragraph tags. Default true.
87678777 * }
87688778 * @return string The markup for an admin notice.
87698779 */
@@ -8822,6 +8832,106 @@ function wp_get_admin_notice( $message, $args = array() ) {
88228832
88238833 if ( true === $ args ['dismissible ' ] ) {
88248834 $ classes .= ' is-dismissible ' ;
8835+ } elseif ( is_array ( $ args ['dismissible ' ] ) ) {
8836+ // The "slug" key is required.
8837+ if ( ! isset ( $ args ['dismissible ' ]['slug ' ] ) || ! is_string ( $ args ['dismissible ' ]['slug ' ] ) ) {
8838+ wp_trigger_error (
8839+ __FUNCTION__ ,
8840+ sprintf (
8841+ /* translators: 1: The "slug" key, 2: The "dismissible" key. */
8842+ __ ( 'The "%1$s" key in the "%2$s" array must be a string. ' ),
8843+ 'slug ' ,
8844+ 'dismissible '
8845+ )
8846+ );
8847+ } else {
8848+ $ slug = trim ( $ args ['dismissible ' ]['slug ' ] );
8849+ if ( '' === $ slug ) {
8850+ wp_trigger_error (
8851+ __FUNCTION__ ,
8852+ sprintf (
8853+ /* translators: 1: The "slug" key, 2: The "dismissible" key. */
8854+ __ ( 'The "%1$s" key in the "%2$s" array must be a non-empty string. ' ),
8855+ 'slug ' ,
8856+ 'dismissible '
8857+ )
8858+ );
8859+ } else {
8860+ // Add a slug data attribute so a transient can be saved when the notice is dismissed.
8861+ $ args ['attributes ' ]['data-slug ' ] = $ slug ;
8862+ }
8863+
8864+ /*
8865+ * If the notice is still dismissed, return early with
8866+ * empty notice markup so that nothing can be output.
8867+ */
8868+ if ( 1 === (int ) get_site_transient ( "wp_admin_notice_dismissed_ {$ slug }" ) ) {
8869+ return '' ;
8870+ }
8871+
8872+ /*
8873+ * The "expiration" key is optional.
8874+ *
8875+ * `isset()` is not used because it will not catch `null` values, which are invalid.
8876+ */
8877+ if ( array_key_exists ( 'expiration ' , $ args ['dismissible ' ] ) ) {
8878+ if ( ! is_int ( $ args ['dismissible ' ]['expiration ' ] ) ) {
8879+ /*
8880+ * Unset the slug data attribute so that the notice appears on the next page load,
8881+ * allowing for corrections to be made without needing to delete the notice's transient.
8882+ *
8883+ * Without this, the notice would be permanently dismissed.
8884+ */
8885+ unset( $ args ['attributes ' ]['data-slug ' ] );
8886+
8887+ wp_trigger_error (
8888+ __FUNCTION__ ,
8889+ sprintf (
8890+ /* translators: 1: The "expiration" key, 2: The "dismissible" key. */
8891+ __ ( 'The "%1$s" key in the "%2$s" array must be an integer. ' ),
8892+ 'expiration ' ,
8893+ 'dismissible '
8894+ )
8895+ );
8896+ } else {
8897+ $ expiration = (int ) $ args ['dismissible ' ]['expiration ' ];
8898+ if ( 0 > $ expiration ) {
8899+ /*
8900+ * Unset the slug data attribute so that the notice appears on the next page load,
8901+ * allowing for corrections to be made without needing to delete the notice's transient.
8902+ *
8903+ * Without this, the notice would be permanently dismissed.
8904+ */
8905+ unset( $ args ['attributes ' ]['data-slug ' ] );
8906+
8907+ wp_trigger_error (
8908+ __FUNCTION__ ,
8909+ sprintf (
8910+ /* translators: 1: The "expiration" key, 2: The "dismissible" key. */
8911+ __ ( 'The "%1$s" key in the "%2$s" array must be greater than or equal to 0. ' ),
8912+ 'expiration ' ,
8913+ 'dismissible '
8914+ )
8915+ );
8916+ } else {
8917+ // Add an expiration data attribute so the notice can be dismissed for a specified duration.
8918+ $ args ['attributes ' ]['data-expiration ' ] = $ expiration ;
8919+ }
8920+ }
8921+ }
8922+
8923+ /*
8924+ * By only adding the HTML class when everything is considered valid,
8925+ * this means invalid values will result in a notice that cannot be dismissed.
8926+ *
8927+ * Even if error reporting is disabled for some reason, the developer will know
8928+ * immediately that something has gone wrong.
8929+ */
8930+ if ( isset ( $ args ['attributes ' ]['data-slug ' ] ) ) {
8931+ $ args ['attributues ' ]['data-nonce ' ] = wp_create_nonce ( 'dismiss-notice ' );
8932+ $ classes .= ' is-dismissible ' ;
8933+ }
8934+ }
88258935 }
88268936
88278937 if ( is_array ( $ args ['additional_classes ' ] ) && ! empty ( $ args ['additional_classes ' ] ) ) {
0 commit comments