| @@ -233,8 +233,35 @@ | ||
| 233 | 233 | return array_map( array( self::class, 'to_run' ), $rows ); |
| 234 | 234 | } |
| 235 | 235 | |
| 236 | 236 | /** |
| 237 | + * The most recent SUCCESSFUL run, straight from the table. | |
| 238 | + * | |
| 239 | + * Score::latest() used to scan the capped history window for the first | |
| 240 | + * `ok` row, which meant a run of failures could push the last real audit | |
| 241 | + * out of the window and leave the site reporting no score at all — the | |
| 242 | + * exact outcome the optimize report exists to prevent, and most likely on | |
| 243 | + * the sites with no PSI key, since the shared quota refuses often. | |
| 244 | + * Asking the store for the newest `ok` row cannot be crowded out. | |
| 245 | + * | |
| 246 | + * @return array<string,mixed>|null | |
| 247 | + */ | |
| 248 | + public static function latest_ok(): ?array { | |
| 249 | + global $wpdb; | |
| 250 | + | |
| 251 | + if ( ! self::has_db() ) { | |
| 252 | + return null; | |
| 253 | + } | |
| 254 | + | |
| 255 | + $table = self::table(); | |
| 256 | + | |
| 257 | + // phpcs:ignore WordPress.DB.DirectDatabaseQuery, WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- own table, no user input in the query. | |
| 258 | + $row = $wpdb->get_row( "SELECT * FROM {$table} WHERE ok = 1 ORDER BY ran_at DESC, id DESC LIMIT 1", ARRAY_A ); | |
| 259 | + | |
| 260 | + return is_array( $row ) ? self::to_run( $row ) : null; | |
| 261 | + } | |
| 262 | + | |
| 263 | + /** | |
| 237 | 264 | * Whether a run with this provider + timestamp is already stored. |
| 238 | 265 | * |
| 239 | 266 | * The Hub is polled repeatedly while a test runs, and the finished result |
| 240 | 267 | * comes back on every poll after it completes — without this, one test |