diff --git a/src/wp-admin/options.php b/src/wp-admin/options.php index a8c7497ed8..3e2e104214 100644 --- a/src/wp-admin/options.php +++ b/src/wp-admin/options.php @@ -279,6 +279,23 @@ if ( 'update' === $action ) { // We are saving settings sent from a settings pag $_POST['gmt_offset'] = $_POST['timezone_string']; $_POST['gmt_offset'] = preg_replace( '/UTC\+?/', '', $_POST['gmt_offset'] ); $_POST['timezone_string'] = ''; + } elseif ( isset( $_POST['timezone_string'] ) && ! in_array( $_POST['timezone_string'], timezone_identifiers_list( DateTimeZone::ALL_WITH_BC ), true ) ) { + // Reset to the current value. + $current_timezone_string = get_option( 'timezone_string' ); + + if ( ! empty( $current_timezone_string ) ) { + $_POST['timezone_string'] = $current_timezone_string; + } else { + $_POST['gmt_offset'] = get_option( 'gmt_offset' ); + $_POST['timezone_string'] = ''; + } + + add_settings_error( + 'general', + 'settings_updated', + __( 'The timezone you have entered is not valid. Please select a valid timezone.' ), + 'error' + ); } // Handle translation installation. diff --git a/tests/e2e/specs/general-settings-invalid-timezone.test.js b/tests/e2e/specs/general-settings-invalid-timezone.test.js new file mode 100644 index 0000000000..9dca6306a4 --- /dev/null +++ b/tests/e2e/specs/general-settings-invalid-timezone.test.js @@ -0,0 +1,28 @@ +import { test, expect } from '@wordpress/e2e-test-utils-playwright'; + +test.describe( 'Settings -> General', () => { + const invalidTimezones = [ '', '0', 'Barry/Gary' ]; + + for ( const invalidTimezone of invalidTimezones ) { + test( `Does not allow saving an invalid timezone string with "${invalidTimezone}"`, async ( { admin, page } ) => { + await admin.visitAdminPage( '/options-general.php' ); + + // Set the timezone to a valid value. + await page.locator( '#timezone_string' ).evaluate( timezone => timezone.value = 'Europe/Lisbon' ); + + // Save changes. + await page.locator( '#submit' ).click(); + + // Set the timezone to an invalid value. + await page.locator( '#timezone_string' ).evaluate( ( timezone, invalidTimezone ) => { + timezone.options[0].value = invalidTimezone; + timezone.value = invalidTimezone; + }, invalidTimezone ); + + // Save changes. + await page.locator( '#submit' ).click(); + + await expect( page.locator( '#timezone_string' ) ).toHaveValue( 'Europe/Lisbon' ); + } ); + } +} );