Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
08ee01b
Site Health: Cache the full results and a timestamp in the status tra…
gziolo Jun 15, 2026
b8ee347
Tests: Fix Site Health AJAX tests on multisite
gziolo Jun 15, 2026
d3a5e8a
Fix PHPStan `argument.type` error for mixed being passed to `json_enc…
westonruter Jun 15, 2026
24aa96a
Fix PHPStan `argument.type` error for `wp_unslash()` expecting `array…
westonruter Jun 15, 2026
26bf323
Simply accessing counts
westonruter Jun 15, 2026
768e598
Add void return type hints
westonruter Jun 15, 2026
1914559
Update dispatch_result_request method to always return array
westonruter Jun 15, 2026
46c32aa
Use native property type hint
westonruter Jun 15, 2026
4572595
fixup! Update dispatch_result_request method to always return array
westonruter Jun 15, 2026
75cc4e8
Fix PHPStan issues in tests
westonruter Jun 15, 2026
3ca1452
Site Health: Cache the full results in a dedicated, non-autoloaded tr…
gziolo Jun 16, 2026
5326eeb
Apply suggestions from code review
gziolo Jun 22, 2026
d381c19
Site Health: Refine the detail cache types and parameter naming.
gziolo Jun 22, 2026
840067f
Site Health: Seed the JS results array from PHP.
gziolo Jun 23, 2026
7f5fdcc
Site Health: Cache only locale-independent result data.
gziolo Jun 23, 2026
a6d1561
Site Health: Reduce duplication in the status cache accessors.
gziolo Jun 23, 2026
e8cd113
Merge branch 'trunk' into fix/65232-cache-site-health-results
westonruter Jul 9, 2026
ac94106
Merge branch 'trunk' into fix/65232-cache-site-health-results
westonruter Jul 9, 2026
3c8ed42
Add type definition for tests
westonruter Jul 9, 2026
069c8d9
Fix return type of get_instance() method
westonruter Jul 9, 2026
a135f1e
Specify shape of $counts param for set_site_status_counts
westonruter Jul 9, 2026
e67b256
Add array type for $counts param for normalize_status_counts()
westonruter Jul 9, 2026
00b290c
Reformat return array shape
westonruter Jul 9, 2026
99b88ba
Factor out array shape into reusable type
westonruter Jul 9, 2026
a8f86c9
Reduce specificity of pre-normalized types
westonruter Jul 9, 2026
abe39f3
Merge branch 'trunk' into fix/65232-cache-site-health-results
westonruter Jul 9, 2026
1c5ac6d
Eliminate redundnat type guards when reading from cache
westonruter Jul 9, 2026
a86ed9c
Leverage JSON schema for validation and use object for results instea…
westonruter Jul 10, 2026
61b1c6f
Merge branch 'trunk' into fix/65232-cache-site-health-results
westonruter Jul 10, 2026
17a9824
Refactor handling of test results
westonruter Jul 10, 2026
f577e0a
Fix error when saving transient with identical value
westonruter Jul 10, 2026
48380a1
Fix ajax tests
westonruter Jul 10, 2026
0718c3f
Site Health: Compute detailed status counts at runtime
gziolo Jul 24, 2026
b718838
Site Health: Specialize the detailed status cache reader
gziolo Jul 24, 2026
f727ddb
Site Health: Fix storing test results in JavaScript
gziolo Jul 24, 2026
26799d5
Site Health: Clarify detailed result documentation
gziolo Jul 24, 2026
a84ac00
Site Health: Validate scheduled test results
gziolo Jul 24, 2026
9ea12a3
Site Health: Compare detail cache with correct transient
gziolo Jul 24, 2026
832da82
Site Health: Ignore results without test identifiers
gziolo Jul 24, 2026
3e59308
Site Health: Clarify detail result validation
gziolo Jul 24, 2026
52ca604
Site Health: Return first AJAX save error
gziolo Jul 24, 2026
e3a9e4e
Site Health: Require detailed status timestamps
gziolo Jul 24, 2026
58edf87
Site Health: Store freshest verified results
gziolo Jul 24, 2026
165fbeb
Site Health: Add status cache error messages
gziolo Jul 24, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 21 additions & 4 deletions src/js/_enqueues/admin/site-health.js
Original file line number Diff line number Diff line change
Expand Up @@ -156,10 +156,14 @@ jQuery( function( $ ) {

count = SiteHealth.site_status.issues[ issue.status ];

// If no test name is supplied, append a placeholder for markup references.
if ( typeof issue.test === 'undefined' ) {
issue.test = issue.status + count;
}
/*
* Collect the test name and status so they can be cached server-side. These
* include the asynchronous tests that only run in the browser. Labels are left
* out on purpose, as they are translated and the cache is shared across locales.
*/
SiteHealth.site_status.results[ issue.test ] = {
status: issue.status
};
Comment thread
gziolo marked this conversation as resolved.

if ( 'critical' === issue.status ) {
heading = sprintf(
Expand Down Expand Up @@ -250,6 +254,7 @@ jQuery( function( $ ) {
}

if ( isStatusTab ) {
// Refresh the lightweight counts first, so a large detailed payload can't block them.
$.post(
ajaxurl,
{
Expand All @@ -259,6 +264,18 @@ jQuery( function( $ ) {
}
);

// Send the per-test results separately, as a best-effort detailed cache update.
if ( Object.keys( SiteHealth.site_status.results ).length > 0 ) {
$.post(
ajaxurl,
{
'action': 'health-check-site-status-result',
'_wpnonce': SiteHealth.nonce.site_status_result,
'results': JSON.stringify( SiteHealth.site_status.results )
}
);
}

if ( 100 === val ) {
$( '.site-status-all-clear' ).removeClass( 'hide' );
$( '.site-status-has-issues' ).addClass( 'hide' );
Expand Down
41 changes: 40 additions & 1 deletion src/wp-admin/includes/ajax-actions.php
Original file line number Diff line number Diff line change
Expand Up @@ -5457,7 +5457,13 @@ function wp_ajax_health_check_loopback_requests() {
/**
* Handles site health check to update the result status via AJAX.
*
* The aggregate counts and the full per-test results are sent as two independent
* requests, so a large results payload cannot prevent the lightweight counts from being
* refreshed. Each is handled on its own here, and either may be omitted.
*
* @since 5.2.0
* @since 7.1.0 The submitted counts are validated, and the optional full per-test results
* are sanitized and cached separately as the authoritative detailed results.
*/
function wp_ajax_health_check_site_status_result() {
check_ajax_referer( 'health-check-site-status-result' );
Expand All @@ -5466,7 +5472,40 @@ function wp_ajax_health_check_site_status_result() {
wp_send_json_error();
}

set_transient( 'health-check-site-status-result', wp_json_encode( $_POST['counts'] ) );
if ( ! class_exists( 'WP_Site_Health' ) ) {
require_once ABSPATH . 'wp-admin/includes/class-wp-site-health.php';
}

$save_results = array();

// Refresh the lightweight, autoloaded aggregate counts used by the admin menu and Dashboard.
// TODO: We don't need to keep this anymore. We can just obtain the counts at runtime from the stored results.
if ( isset( $_POST['counts'] ) && is_array( $_POST['counts'] ) ) {
$counts = wp_unslash( $_POST['counts'] );
$save_results[] = WP_Site_Health::set_site_status_counts( $counts );
}

/*
* Cache the full per-test results as the authoritative detailed results. These include
* the asynchronous tests that require JavaScript to run. The values are sanitized in
* WP_Site_Health::update_site_status_detail().
*/
if ( isset( $_POST['results'] ) && is_string( $_POST['results'] ) ) {
$results = json_decode( wp_unslash( $_POST['results'] ), true );
Comment thread
gziolo marked this conversation as resolved.

if ( is_array( $results ) ) {
$save_results[] = WP_Site_Health::update_site_status_detail( $results );
}
}

if ( count( $save_results ) === 0 ) {
wp_send_json_error();
}

$errors = array_filter( $save_results, 'is_wp_error' );
if ( count( $errors ) > 0 ) {
wp_send_json_error( reset( $errors ) );
}

wp_send_json_success();
}
Expand Down
Loading
Loading