__( '24 hours', 'mcp-server-status' ), '7d' => __( '7 days', 'mcp-server-status' ), '30d' => __( '30 days', 'mcp-server-status' ), '90d' => __( '90 days', 'mcp-server-status' ), '1y' => __( '1 year', 'mcp-server-status' ), ); } /** * Transient key for a monitor/range. * * @param string $id Monitor id. * @param string $range Range. * @return string */ function mcpss_history_key( $id, $range ) { return 'mcpss_h_' . md5( $id . '|' . $range ); } /** * Delete cached history for the given monitors. * * @param array $monitors Monitors. */ function mcpss_flush_history( $monitors ) { foreach ( (array) $monitors as $m ) { if ( empty( $m['id'] ) ) { continue; } foreach ( array_keys( mcpss_history_ranges() ) as $r ) { delete_transient( mcpss_history_key( $m['id'], $r ) ); } } } /** * Fetch + sanitize history. * * @param string $id Monitor UUID. * @param string $range Range. * @return array|WP_Error */ function mcpss_get_history( $id, $range ) { if ( ! preg_match( '/^[0-9a-f-]{36}$/i', $id ) ) { return new WP_Error( 'mcpss_bad_id', __( 'History is not available for this monitor.', 'mcp-server-status' ) ); } $ranges = mcpss_history_ranges(); $range = isset( $ranges[ $range ] ) ? $range : '7d'; $key = mcpss_history_key( $id, $range ); $cached = get_transient( $key ); if ( is_array( $cached ) ) { return $cached; } $res = mcpss_api( 'GET', '/api/wp/monitors/' . rawurlencode( $id ) . '/history?range=' . rawurlencode( $range ) ); if ( is_wp_error( $res ) ) { return $res; } if ( 200 !== $res['code'] ) { $msg = isset( $res['body']['error'] ) ? (string) $res['body']['error'] : __( 'Could not load history.', 'mcp-server-status' ); return new WP_Error( 'mcpss_api', $msg ); } $b = $res['body']; $num = function ( $a, $k ) { return isset( $a[ $k ] ) && is_numeric( $a[ $k ] ) ? 0 + $a[ $k ] : null; }; $str = function ( $a, $k ) { return isset( $a[ $k ] ) && is_scalar( $a[ $k ] ) ? sanitize_text_field( (string) $a[ $k ] ) : ''; }; $sum = isset( $b['summary'] ) && is_array( $b['summary'] ) ? $b['summary'] : array(); $allowed = array(); foreach ( isset( $b['allowedRanges'] ) ? (array) $b['allowedRanges'] : array() as $r ) { if ( is_string( $r ) && isset( $ranges[ $r ] ) ) { $allowed[] = $r; } } $out = array( 'range' => isset( $b['range'], $ranges[ $b['range'] ] ) ? $b['range'] : $range, 'allowedRanges' => $allowed ? $allowed : array( '24h', '7d' ), 'locked' => array_map( 'sanitize_key', array_filter( isset( $b['locked'] ) ? (array) $b['locked'] : array(), 'is_string' ) ), 'bucketMinutes' => (int) $num( $b, 'bucketMinutes' ), 'summary' => array( 'totalChecks' => (int) $num( $sum, 'totalChecks' ), 'failedChecks' => (int) $num( $sum, 'failedChecks' ), 'uptimePct' => $num( $sum, 'uptimePct' ), 'notEnoughData' => ! empty( $sum['notEnoughData'] ), 'incidents' => (int) $num( $sum, 'incidents' ), 'avgLatencyMs' => $num( $sum, 'avgLatencyMs' ), 'downtimeMinutes' => $num( $sum, 'downtimeMinutes' ), ), 'buckets' => array(), 'incidents' => array(), 'recentChecks' => array(), 'reportUrl' => isset( $b['reportUrl'] ) ? esc_url_raw( $b['reportUrl'] ) : '', 'upgradeUrl' => isset( $b['upgradeUrl'] ) ? esc_url_raw( $b['upgradeUrl'] ) : 'https://mcpserverstatus.com/pricing', ); foreach ( array_slice( isset( $b['buckets'] ) ? (array) $b['buckets'] : array(), 0, 120 ) as $x ) { if ( is_array( $x ) ) { $st = $str( $x, 'status' ); $out['buckets'][] = array( 'start' => $str( $x, 'start' ), 'total' => (int) $num( $x, 'total' ), 'up' => (int) $num( $x, 'up' ), 'status' => in_array( $st, array( 'up', 'partial', 'down' ), true ) ? $st : 'none', 'latency' => $num( $x, 'avgLatencyMs' ), ); } } foreach ( array_slice( isset( $b['incidents'] ) ? (array) $b['incidents'] : array(), 0, 5 ) as $x ) { if ( is_array( $x ) ) { $out['incidents'][] = array( 'startedAt' => $str( $x, 'startedAt' ), 'resolvedAt' => $str( $x, 'resolvedAt' ), 'durationMinutes' => (int) $num( $x, 'durationMinutes' ), 'cause' => $str( $x, 'cause' ), ); } } foreach ( array_slice( isset( $b['recentChecks'] ) ? (array) $b['recentChecks'] : array(), 0, 10 ) as $x ) { if ( is_array( $x ) ) { $out['recentChecks'][] = array( 'timestamp' => $str( $x, 'timestamp' ), 'status' => $str( $x, 'status' ), 'latencyMs' => $num( $x, 'latencyMs' ), ); } } set_transient( $key, $out, 5 * MINUTE_IN_SECONDS ); return $out; } /** * Human duration. * * @param int $m Minutes. * @return string */ function mcpss_duration( $m ) { $m = max( 0, (int) $m ); if ( $m < 60 ) { /* translators: %d: minutes. */ return sprintf( __( '%d min', 'mcp-server-status' ), $m ); } if ( $m < 1440 ) { /* translators: 1: hours, 2: minutes. */ return sprintf( __( '%1$dh %2$dm', 'mcp-server-status' ), floor( $m / 60 ), $m % 60 ); } /* translators: 1: days, 2: hours. */ return sprintf( __( '%1$dd %2$dh', 'mcp-server-status' ), floor( $m / 1440 ), floor( ( $m % 1440 ) / 60 ) ); } /** * Locked placeholder. * * @param string $label Label. * @param string $upgrade Upgrade URL. * @param string $extra Extra class. */ function mcpss_locked( $label, $upgrade, $extra = '' ) { ?>
' . esc_html__( 'No latency data in this range yet.', 'mcp-server-status' ) . ''; } $max = max( 50, max( $vals ) ) * 1.1; $path = ''; $pen = false; foreach ( $buckets as $i => $b ) { if ( null === $b['latency'] ) { $pen = false; continue; } $x = 4 + $i * ( $w - 8 ) / ( $n - 1 ); $y = $h - 6 - ( (float) $b['latency'] / $max ) * ( $h - 14 ); $path .= ( $pen ? 'L' : 'M' ) . round( $x, 1 ) . ',' . round( $y, 1 ); $pen = true; } return '' . '0' . esc_html( round( $max ) . ' ms' ) . '
'; } /** * Render the history panel for one monitor. * * @param array $m Monitor (from mcpss_get_monitors). * @param string $range Requested range. */ function mcpss_render_history_panel( $m, $range ) { $h = mcpss_get_history( isset( $m['id'] ) ? $m['id'] : '', $range ); echo '' . esc_html( $h->get_error_message() ) . '
' . esc_html__( 'Healthy', 'mcp-server-status' ) . ' ' . esc_html__( 'Partial', 'mcp-server-status' ) . ' ' . esc_html__( 'Down', 'mcp-server-status' ) . ' ' . esc_html__( 'No data', 'mcp-server-status' ) . '
'; echo '' . esc_html__( 'No incidents in this range.', 'mcp-server-status' ) . '
'; } else { echo '' . esc_html__( 'No checks yet.', 'mcp-server-status' ) . '
'; } else { echo '| ' . esc_html( mcpss_format_datetime( $c['timestamp'] ) ) . ' | ' . esc_html( $c['status'] ) . ' | ' . esc_html( null !== $c['latencyMs'] ? number_format_i18n( $c['latencyMs'] ) . ' ms' : '—' ) . ' |