Repository navigation
fix: prevent error on general settings save - #1080
Conversation
Preserve $new_allowed_options when register_initial_settings() is called early in Settings::register() so 'admin_email' is not added to the allowed options list on admin form saves. Fixes WordPress#1048
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message. To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## develop #1080 +/- ##
==========================================
Coverage 81.59% 81.60%
Complexity 3081 3081
==========================================
Files 129 129
Lines 12281 12283 +2
==========================================
+ Hits 10021 10023 +2
Misses 2260 2260
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Ports WordPress/ai#1080. When the abilities registry initializes before `rest_api_init`, register() calls register_initial_settings(), which also adds core's settings to $new_allowed_options. On an options.php request, those settings are then processed even though the submitted form does not include them (for example admin_email on Settings > General), which triggers a validation error. Restore $new_allowed_options after the early registration.
Ports WordPress/ai#1080. When the abilities registry initializes before `rest_api_init`, register() calls register_initial_settings(), which also adds core's settings to $new_allowed_options. On an options.php request, those settings are then processed even though the submitted form does not include them (for example admin_email on Settings > General), which triggers a validation error. Restore $new_allowed_options after the early registration.
Abilities can initialize before or without `rest_api_init`, where the initial settings are registered, for example on cron or WP-CLI. So far `WP_Abilities_Settings::register()` registered them itself. Register them from a `wp_abilities_api_init` callback at priority 1 instead, before the core abilities, so the settings ability no longer handles the settings bootstrap. The callback keeps the existing checks: it does nothing once the REST API has registered the settings, and it restores `$new_allowed_options`, so saving Settings > General does not try to save `admin_email` (see WordPress/ai#1080).
What?
Closes #1048
This PR prevents
options.phpform validation errors on Settings › General saves by preserving and restoring$GLOBALS['new_allowed_options']whenregister_initial_settings()is called insideSettings::register().Why?
Since 1.2.0 (#856),
Settings::register()callsregister_initial_settings()when abilities initialize beforerest_api_init, ensuring core settings exist in$wp_registered_settingsbefore taking the snapshot forcore/read-settings.However,
register_initial_settings()has a side effect: it callsregister_setting( 'general', 'admin_email' ), which appends'admin_email'to$new_allowed_options['general'].On ordinary admin form POSTs to
wp-admin/options.php, WordPress iterates over every allowed option in the group and updates it. Because the Settings › General form postsnew_admin_emailinstead ofadmin_email,options.phpreceivesnullforadmin_email. In turn,sanitize_option( 'admin_email', null )/is_email( null )triggers PHP deprecation notices (preg_match/strlenparameter null) and an invalid email error notice ("The email address isn't correct"), even though the form is completely valid.How?
includes/Abilities/Settings/Settings.php, captured$GLOBALS['new_allowed_options']immediately prior to callingregister_initial_settings().$GLOBALS['new_allowed_options'](and re-linked the legacy alias$GLOBALS['new_whitelist_options']) immediately afterwards. This keeps$wp_registered_settingspopulated for the Abilities registry without leakingadmin_emailinto form handling.test_register_preserves_new_allowed_options()intests/Integration/Includes/Abilities/Settings/SettingsTest.phpto verify thatadmin_emailis not added to$new_allowed_options['general']and existing allowed options are preserved.Use of AI Tools
AI assistance: Yes
Tool(s): Antigravity
Used for: Root-cause debugging, patch implementation, and integration test creation; final implementation and tests were tested and reviewed by me.
Testing Instructions
add_action( 'admin_init', function() { wp_get_abilities(); } );is active)./wp-admin/options-general.php).After Fix
Changelog Entry