feat: resolve WPGraphQL settings outside the admin (at the /graphql endpoint)#3878
Merged
Conversation
…ndpoint) Extracted from #3784. Initializes the settings registry on every request instead of only on `admin_init`, so registered settings are available in non-admin contexts such as a /graphql request. - Settings::init_registry() now runs on `init` (priority 11, after register_settings) in addition to the existing admin path. - SettingsRegistry::init_registry() fires `graphql_init_settings` and ensures each section's option exists + is registered. It's idempotent (guarded per-instance) so reaching it via both `init` and `admin_init` in one request can't double-fire. admin_init() now delegates to it for the registration work and keeps only the admin-UI scaffolding. - Experimental: the Admin class is now initialized in all contexts (it only does registration work), so the GraphQL endpoint can resolve experiment settings without depending on an admin request. Also folds in a lint-only eslint-disable comment in the legacy wpgraphiql GraphiQLToolbar (import/no-unresolved for @graphiql/react) so it isn't stranded when the IDE branch is reduced to plugins/wp-graphql-ide/**.
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #3878 +/- ##
=========================================
- Coverage 84.5% 83.5% -1.0%
- Complexity 4360 5284 +924
=========================================
Files 221 286 +65
Lines 19438 22753 +3315
=========================================
+ Hits 16431 18995 +2564
- Misses 3007 3758 +751
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
Regression caught by tests/e2e/specs/settings-registry-options-page.spec.js: init_registry() created each section's option via add_option( $id, [] ). An array value serializes, and WordPress renders serialized options as a disabled "SERIALIZED DATA" input on /wp-admin/options.php — so the e2e test that edits graphql_experiments_settings there could no longer fill the field. Revert to add_option( $id ) (WP's empty-string default), matching the long-standing behavior. sanitize_options() already tolerates a string value, so nothing downstream needs the [] seed.
The previous approach (seeding each option in init_registry, which runs on every `init`) was the root of two test failures: - add_option($id, []) stored a serialized array -> WordPress renders it as a disabled "SERIALIZED DATA" input on /wp-admin/options.php, breaking settings-registry-options-page.spec.js. - add_option($id) stored an empty string -> on a /graphql or test request the option now exists as a scalar, so callers that array-write onto it (GraphQLHeadersCept: `$opt['query_analyzer_enabled'] = 'off'`) hit a PHP 8 "Cannot access offset of type string on string" TypeError. On main this works because the option doesn't exist yet (false auto-vivifies to array). Fix: init_registry() no longer creates the option row — it only fires graphql_init_settings and register_setting() so settings resolve at the endpoint. Option creation moves back to admin_init() (lazy, empty-string default), matching main's long-standing behavior. Reads are unaffected: get_graphql_setting() already defaults a missing option to [].
jasonbahl
added a commit
that referenced
this pull request
Jun 4, 2026
Sync main (split PRs #3877/#3878/#3879 + asset-pipeline #3880/#3882/#3883) into the IDE rebuild branch. Conflicts were all IDE release-metadata + the plugin header; resolved as: - package.json / wpgraphql-ide.php Version / readme.txt Stable tag: 4.5.0 (the release-please manifest value; release-please bumps to 5.0.0 at release — the in-repo version tracks the last release per the plugin's CLAUDE.md). - CHANGELOG.md / readme.txt changelog: union — keep the 5.0.0 notes AND main's released 4.5.0 entry. - Requires at least: 6.1 (not the 7.0 the branch had staged). WordPress 7.0's i18n features (.l10n.php 6.5, JIT textdomain 6.7) degrade gracefully and no runtime gate gates on 7.0, so there's no reason to lock out current installs. Dropped the "raised floor to 7.0" breaking-change note and aligned CLAUDE.md + i18n docs to 6.1. - Tested up to: 7.0 (WordPress 7.0 is released).
jasonbahl
added a commit
to josephfusco/wp-graphql
that referenced
this pull request
Jun 4, 2026
Sync main (split PRs wp-graphql#3877/wp-graphql#3878/wp-graphql#3879 + asset pipeline wp-graphql#3880/wp-graphql#3882/wp-graphql#3883) onto the IDE rebuild branch, on top of Joe's floor/CI commits (floor 6.1, WP 7.0 CI coverage + tested-up-to). Conflicts (all IDE release metadata) resolved as: - Version / Stable tag / package.json: 4.5.0 (release-please manifest value; release-please bumps to 5.0.0 at release — in-repo version tracks last release per the plugin's CLAUDE.md). - CHANGELOG.md / readme.txt changelog: union — keep the 5.0.0 notes AND main's released 4.5.0 entry. Dropped the now-inaccurate "raised floor to 7.0" breaking-change note (Joe set the floor to 6.1) and the 7.0-floor framing in the i18n docs. - Requires at least: 6.1 / Tested up to: 7.0 — kept Joe's values.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Initializes the WPGraphQL settings registry on every request (not just
admin_init), so registered settings resolve in non-admin contexts such as a/graphqlrequest.Why
Extracted from #3784 (the IDE 5.0 rebuild) so the core feature lands as its own minor without inheriting that PR's
feat!major. The rebuilt IDE — and any consumer reading settings via GraphQL — depends on settings being available at the endpoint.Changes
Settings::init_registry()runs oninit(priority 11) alongside the existing admin path.SettingsRegistry::init_registry()firesgraphql_init_settings, ensures each section's option exists, and registers it. Idempotent (per-instance guard) so theinit+admin_initpaths can't double-fire in one request.admin_init()delegates registration to it and keeps only admin-UI scaffolding.Experimental:Adminis initialized in all contexts (registration-only work) so the endpoint can resolve experiment settings.import/no-unresolvedeslint-disable comment in the legacywpgraphiqlGraphiQLToolbar(folded in here so it isn't lost when the IDE branch is reduced toplugins/wp-graphql-ide/**).Backward-compatible — additive new public methods and an action that fires earlier/more often. No breaking changes.