fix(current): guard get_query_var when $wp_query is null (template-switching 500)#1127
fix(current): guard get_query_var when $wp_query is null (template-switching 500)#1127superdav42 merged 1 commit intomainfrom
Conversation
The lazy-load entry path added in PR #1118 made `Current::get_customer()` call `Current::load_currents()` whenever the cache is null. That worked for normal init/wp pipeline calls, but broke the wu-ajax pipeline: `Light_Ajax::process_light_ajax` dispatches `wu_ajax_*` handlers at `plugins_loaded` priority 20 and `die()`s before WordPress core gets to `parse_query`. The handler for `wu_switch_template` reads `Site::is_customer_allowed()`, which calls `get_customer()`, which (after #1118) calls `load_currents()` on the still-cold cache. Inside `load_currents()` the frontend branch reads `get_query_var('site_hash')` and the membership branch reads `get_query_var('membership_hash')`. `get_query_var()` is `$wp_query->get($var, $default)`, and at `plugins_loaded` `$wp_query` is still null. PHP 8+ fatals with `Call to a member function get() on null`, the AJAX handler returns HTTP 500 with no JSON body, and the customer-panel template-switching UI surfaces the generic "A network error occurred. Please check your connection and try again." banner. A real customer hit this on production immediately after #1118 landed; backtrace points squarely at class-current.php line 253. Guard both `get_query_var()` reads with a `$query_vars_ready` check that confirms `parse_query` has fired and `$GLOBALS['wp_query']` is a real `WP_Query` instance. When the query var system is not ready, substitute an empty-string default — `wu_request()` will still pick up `$_REQUEST` overrides if present, and the wu-ajax pipeline never carries pretty-URL `site_hash` / `membership_hash` query vars anyway (it is a flat `?wu-ajax=1` POST), so nothing functional is lost. Once WordPress reaches `wp` and reruns `load_currents()`, the guard is true and the original behaviour is preserved verbatim. Add a regression test that nulls `$GLOBALS['wp_query']` to simulate the early-call condition and asserts `load_currents()` completes without fataling. Verified by reverting the fix and confirming the test reproduces the production fatal exactly. PHPCS clean. PHPStan clean. All Current_Test cases pass (11 / 11, 16 assertions). Resolves the customer-reported "A network error occurred" / 500 on the customer-panel template-switching page.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughThis PR adds defensive logic to ChangesQuery Variable Safety Hardening
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
🔨 Build Complete - Ready for Testing!📦 Download Build Artifact (Recommended)Download the zip build, upload to WordPress and test:
🌐 Test in WordPress Playground (Very Experimental)Click the link below to instantly test this PR in your browser - no installation needed! Login credentials: |
|
Performance Test Results Performance test results for fdd0e44 are in 🛎️! Note: the numbers in parentheses show the difference to the previous (baseline) test run. Differences below 2% or 0.5 in absolute values are not shown. URL:
|
SummaryFix a PHP 8+ fatal in Root causePR #1118 added a lazy-load entry from FixCompute Test plan
Files changed
aidevops.sh v3.14.75 plugin for OpenCode v1.14.33 with claude-sonnet-4-6 spent 1d 23h on this as a headless worker. Merged via PR #1127 to main. |
Summary
Fix a PHP 8+ fatal in
Current::load_currents()that surfaces in productionas "A network error occurred. Please check your connection and try again."
on the customer-panel Switch Template page (and any other wu-ajax
endpoint that reads
is_customer_allowed()).Root cause
PR #1118 added a lazy-load entry from
Current::get_customer()/get_membership()so callers that arrive before theinit/wpcachewarm-up still get a populated value. That fix is correct in spirit but
exposes a latent hazard inside
load_currents()itself: both pretty-URLhash overrides call
get_query_var().get_query_var()is$wp_query->get($var, $default). The wu-ajaxpipeline (
Light_Ajax::process_light_ajax) dispatcheswu_ajax_*handlers at
plugins_loadedpriority 20 — long before WordPress reachesparse_query. At that point$wp_queryisnull, and PHP 8+ fatalswith
Call to a member function get() on null. The AJAX handler dieswith HTTP 500 and no JSON body, so the JS error callback shows the
generic network-error banner.
Backtrace from a real customer (production):
Fix
Compute
$query_vars_ready = did_action('parse_query') && $GLOBALS['wp_query'] instanceof WP_Queryonce at the top of
load_currents(). When false, substitute an emptystring for both
get_query_var()calls.wu_request()still picks up$_REQUESToverrides if present, and the wu-ajax pipeline carries norewrite-driven
site_hash/membership_hashanyway (it is a flat?wu-ajax=1POST), so nothing functional is lost. Once WP reacheswpand re-runs
load_currents(), the guard is true and the originalbehaviour is preserved verbatim.
Test plan
test_load_currents_survives_when_wp_query_is_nullnulls
$GLOBALS['wp_query']and assertsload_currents()runs tocompletion. Verified by reverting the fix and confirming the test
reproduces the production fatal exactly:
Current_Testsuite: 11 tests, 16 assertions, all pass.(verified by running the same scope on
origin/main).Files changed
inc/class-current.php— guard bothget_query_var()calls.tests/WP_Ultimo/Current_Test.php— regression test.Resolves the customer-reported 500 / "A network error occurred" banner
on the customer-panel template-switching page reported after #1118
landed.
aidevops.sh v3.14.75 plugin for OpenCode v1.14.33 with claude-sonnet-4-6 spent 1d 23h on this as a headless worker.
Summary by CodeRabbit
Bug Fixes
Performance