Premium Analytics: add API proxy REST controller#49506
Conversation
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
Thank you for your PR! When contributing to Jetpack, we have a few suggestions that can help us test and review your patch:
This comment will be updated as you work on your PR and make changes. If you think that some of those checks are not needed for your PR, please explain why you think so. Thanks for cooperation 🤖 Follow this PR Review Process:
If you have questions about anything, reach out in #jetpack-developers for guidance! Premium Analytics plugin: No scheduled milestone found for this plugin. If you have any questions about the release process, please ask in the #jetpack-releases channel on Slack. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Migrate WooCommerce Analytics' ApiProxy into the premium-analytics package as Api_Proxy_Controller. It forwards authenticated dashboard requests to the connected site's WPCOM analytics endpoint via Jetpack\Connection\Client, caches successful responses in a 5-minute transient keyed on the request signature, and returns them. Strips the WC-specific surface from the source: WC_REST_Controller parent becomes WP_REST_Controller, the view_woocommerce_reports permission becomes manage_options, and the LoggerTrait/Utilities/ RegistrableInterface dependencies are dropped (the controller registers its own route on rest_api_init from Analytics::init()).
- Declare the endpoint route arg with a sanitize_callback. - Return 502 (and skip caching) when a 200 response body isn't decodable JSON. - Strip the _locale routing param alongside rest_route from forwarded params. - Cast the site ID to int when building the WPCOM path. - Cover the new json-decode-failure and routing-param-stripping paths in tests.
657b0be to
be78b1c
Compare
Code Coverage SummaryCoverage changed in 1 file.
1 file is newly checked for coverage.
|
…ate plugin lock - Suppress PhanPluginMixedKeyNoKey on the register_rest_route args (the mixed key/no-key shape is required by the WP API; phan #4852). - Suppress PhanUndeclaredMethod on the Closure::call() rebinding in the cache-key test helper. - Refresh projects/plugins/premium-analytics/composer.lock for the new jetpack-connection dependency.
🤖 Review-cycle summary —
|
| Source | Item | Resolution |
|---|---|---|
| claude[bot] | Endpoint param lacked sanitize_callback |
Declared endpoint route arg with sanitize_text_field (be78b1c) |
| claude[bot] | Silent json_decode failure on a 200 body |
Return 502 api_error + skip caching when a 200 body isn't decodable (be78b1c) |
| claude[bot] | _locale query param leaked to WPCOM |
Stripped alongside rest_route (be78b1c) |
| claude[bot] | Empty site-ID edge case | Cast blog ID to int, path uses %d (be78b1c) |
| claude[bot] | Multisite cache key / CACHE_TTL constant |
Explained, no change — transients are per-site-scoped; *_IN_SECONDS in class consts is an established phan-safe pattern |
| CI (phan) | PhanPluginMixedKeyNoKey on register_rest_route |
Suppressed with documented reason (inherent to the WP API; phan #4852) (07b5e13) |
| CI (phan) | PhanUndeclaredMethod on test Closure::call() |
Suppressed inline (07b5e13) |
| CI (lock files) | Plugin lock stale after new jetpack-connection dep |
Refreshed plugins/premium-analytics/composer.lock + changelog (07b5e13, 8ae8284) |
Rebase: PR 1 (Sync_Status_Tracker) landed on trunk and touched composer.json + class-analytics.php; rebased keeping both sides (both require entries, both use imports, both init calls).
Flaky CI: PHP tests: PHP 8.4 WP latest failed once on a Docker-registry timeout pulling mariadb:12.0 (container init, tests never ran); reran and passed. All other matrix cells were green throughout.
Unaddressed (flagged for owner): None.
CI: all required checks passing.
Fixes https://linear.app/a8c/issue/WOOA7S-1438/pr-2-migrate-api-proxy-rest-controller-to-premium-analytics
Why
The extracted analytics dashboard's data layer needs an authenticated, same-origin way to read WPCOM analytics for the connected site. This adds the server-side proxy that forwards those reads to WPCOM and briefly caches the result, so the dashboard can render real data without each request leaving the WordPress origin or re-authenticating.
Proposed changes
Api_Proxy_Controller(src/REST/class-api-proxy-controller.php) — aWP_REST_Controllerthat registersGET /jetpack-premium-analytics/v1/proxy/(?P<endpoint>.*)onrest_api_init.endpointplus its query params to/sites/<blog_id>/analytics/<endpoint>viaJetpack\Connection\Client::wpcom_json_api_request_as_blog(), using the connected site's blog ID.200) responses in a 5-minute transient keyed on the request signature (endpoint + sorted query params), prefixed with the package slug. Cache hits are served without contacting WPCOM. Pagination headers (x-wp-total,x-wp-totalpages) are forwarded back.manage_options; return a403 no_connectionerror when Jetpack isn't connected and500 api_erroron a transport/upstream failure.Api_Proxy_Controller::register()intoAnalytics::init(); add theautomattic/jetpack-connectionruntime dependency and theautomattic/jetpack-test-environmentdev dependency.This migrates WooCommerce Analytics'
ApiProxy, stripping the WC-specific surface:WC_REST_Controller→WP_REST_Controller,view_woocommerce_reports→manage_options, and theLoggerTrait/Utilities/RegistrableInterfacedependencies (the controller registers its own route). Per the issue, caching is implemented as a server-side transient (the source only setCache-Controlheaders).API changes
Adds
GET /jetpack-premium-analytics/v1/proxy/<endpoint>(admin-only), which proxies to the WPCOM analytics API for the connected blog and caches successful responses for 5 minutes.Request
Verification output (live, Jetpack-connected dev site — blog 254382938)
Related product discussion/links
Does this pull request change what data or activity we track or use?
No. This relays existing analytics reads from the connected site to WPCOM over the existing Jetpack blog token; it introduces no new tracking or data collection. The 5-minute transient stores only the proxied response payload.
Testing instructions
Acceptance criteria from the issue:
jp build packages/premium-analyticssucceedsjp test php packages/premium-analyticspasses (new test included — 8 tests, 14 assertions)jp phan packages/premium-analyticspasses — deferred to CI (see note above; not runnable on host PHP 8.5)jp changelog add packages/premium-analyticsentry includedTo verify locally:
premium-analyticsplugin on a Jetpack-connected site (requires Gutenberg active).wp eval 'do_action("rest_api_init"); print_r(array_filter(array_keys(rest_get_server()->get_routes()), fn($r)=>str_contains($r,"premium-analytics/v1/proxy")));'GET /wp-json/jetpack-premium-analytics/v1/proxy/reports/totals→401/403./sites/<blog_id>/analytics/reports/totalsand the upstream status + body are returned.