diff --git a/src/wp-admin/includes/template.php b/src/wp-admin/includes/template.php index 418bfd7def697..7e2c66819b1a9 100644 --- a/src/wp-admin/includes/template.php +++ b/src/wp-admin/includes/template.php @@ -1876,6 +1876,15 @@ function add_settings_error( $setting, $code, $message, $type = 'error' ) { ); } +/** + * Stores settings errors for retrieval on the next Network Admin page load. + * + * @since x.x.x + */ +function set_network_settings_errors() { + set_site_transient( 'settings_errors', get_settings_errors(), 30 ); +} + /** * Fetches settings errors registered by add_settings_error(). * @@ -1883,7 +1892,8 @@ function add_settings_error( $setting, $code, $message, $type = 'error' ) { * pageload and returns them. * * If changes were just submitted ($_GET['settings-updated']) and settings errors were saved - * to the 'settings_errors' transient then those errors will be returned instead. This + * to the 'settings_errors' transient then those errors will be returned instead. In Network + * Admin, the same applies to $_GET['updated'] and the 'settings_errors' site transient. This * is used to pass errors back across pageloads. * * Use the $sanitize argument to manually re-sanitize the option before returning errors. @@ -1892,6 +1902,7 @@ function add_settings_error( $setting, $code, $message, $type = 'error' ) { * action hook). * * @since 3.0.0 + * @since x.x.x Added support for network settings errors stored in a site transient. * * @global array[] $wp_settings_errors Storage array of errors registered during this pageload * @@ -1924,10 +1935,13 @@ function get_settings_errors( $setting = '', $sanitize = false ) { sanitize_option( $setting, get_option( $setting ) ); } - // If settings were passed back from options.php then use them. + // If settings were passed back from options.php or network/settings.php then use them. if ( isset( $_GET['settings-updated'] ) && $_GET['settings-updated'] && get_transient( 'settings_errors' ) ) { $wp_settings_errors = array_merge( (array) $wp_settings_errors, get_transient( 'settings_errors' ) ); delete_transient( 'settings_errors' ); + } elseif ( is_network_admin() && isset( $_GET['updated'] ) && 'true' === $_GET['updated'] && get_site_transient( 'settings_errors' ) ) { + $wp_settings_errors = array_merge( (array) $wp_settings_errors, get_site_transient( 'settings_errors' ) ); + delete_site_transient( 'settings_errors' ); } // Check global in case errors have been added on this pageload. diff --git a/src/wp-admin/network/settings.php b/src/wp-admin/network/settings.php index 1e13084a858c1..818236e24ddef 100644 --- a/src/wp-admin/network/settings.php +++ b/src/wp-admin/network/settings.php @@ -131,6 +131,8 @@ */ do_action( 'update_wpmu_options' ); + set_network_settings_errors(); + wp_redirect( add_query_arg( 'updated', 'true', network_admin_url( 'settings.php' ) ) ); exit; } @@ -138,14 +140,20 @@ require_once ABSPATH . 'wp-admin/admin-header.php'; if ( isset( $_GET['updated'] ) ) { - wp_admin_notice( - __( 'Settings saved.' ), - array( - 'type' => 'success', - 'dismissible' => true, - 'id' => 'message', - ) - ); + $settings_errors = get_settings_errors(); + + if ( $settings_errors ) { + settings_errors(); + } elseif ( 'true' === $_GET['updated'] ) { + wp_admin_notice( + __( 'Settings saved.' ), + array( + 'type' => 'success', + 'dismissible' => true, + 'id' => 'message', + ) + ); + } } ?> diff --git a/tests/phpunit/tests/admin/includesTemplate.php b/tests/phpunit/tests/admin/includesTemplate.php index 4b9b8bc68034e..bfa9a93052304 100644 --- a/tests/phpunit/tests/admin/includesTemplate.php +++ b/tests/phpunit/tests/admin/includesTemplate.php @@ -425,6 +425,46 @@ public function test_get_settings_errors_sources() { $wp_settings_errors = null; } + /** + * @ticket 18088 + * @covers ::get_settings_errors + * @covers ::set_network_settings_errors + * @global array $wp_settings_errors + */ + public function test_get_settings_errors_from_network_transient() { + global $current_screen, $wp_settings_errors; + + $previous_screen = $current_screen; + $error = array( + 'setting' => 'new_admin_email', + 'code' => 'invalid_new_admin_email', + 'message' => 'Invalid email address.', + 'type' => 'error', + ); + + set_current_screen( 'dashboard-network' ); + $wp_settings_errors = null; + add_settings_error( $error['setting'], $error['code'], $error['message'], $error['type'] ); + set_network_settings_errors(); + + $_GET['updated'] = 'false'; + $wp_settings_errors = null; + $errors_when_false = get_settings_errors(); + + $_GET['updated'] = 'true'; + $wp_settings_errors = null; + $errors_when_true = get_settings_errors(); + $transient = get_site_transient( 'settings_errors' ); + + unset( $_GET['updated'] ); + $current_screen = $previous_screen; + $wp_settings_errors = null; + + $this->assertSame( array(), $errors_when_false ); + $this->assertSame( array( $error ), $errors_when_true ); + $this->assertFalse( $transient ); + } + /** * @ticket 44941 * @covers ::settings_errors