$state['failures'] + 1, 'message' => $message, 'at' => time(), ), false ); } public static function recordSuccess(): void { if ( 0 !== self::state()['failures'] ) { delete_option( self::OPTION ); } } /** Autoloaded, so checkout asks the database nothing once it is set. */ public static function noteFirstRate(): void { if ( 0 === self::firstRateAt() ) { update_option( self::FIRST_RATE, time(), true ); } } public static function firstRateAt(): int { return (int) get_option( self::FIRST_RATE, 0 ); } public static function isFailing(): bool { return self::state()['failures'] >= self::THRESHOLD; } /** @return array{failures: int, message: string, at: int} */ public static function state(): array { $saved = get_option( self::OPTION, array() ); $saved = is_array( $saved ) ? $saved : array(); return array( 'failures' => (int) ( $saved['failures'] ?? 0 ), 'message' => (string) ( $saved['message'] ?? '' ), 'at' => (int) ( $saved['at'] ?? 0 ), ); } }