'; $out .= '' . self::dot( $state ) . ' ' . esc_html( self::rollup_label( $state ) ) . ''; foreach ( $services as $service ) { // Non-scalar name/state (an array or object in the remote JSON) // would otherwise trigger an "Array to string conversion" // warning on cast; treat a non-scalar name as no name at all. $raw_name = isset( $service['name'] ) ? $service['name'] : ''; if ( ! is_scalar( $raw_name ) ) { continue; } $name = (string) $raw_name; if ( '' === $name ) { continue; } $raw_state = isset( $service['state'] ) ? $service['state'] : ''; $svc_state = is_scalar( $raw_state ) ? (string) $raw_state : ''; // The dot is the only visual cue for state; a sighted user reads // its color, so a screen-reader-only label carries the same // information for everyone else instead of relying on color alone. $out .= '' . self::dot( $svc_state ) . '' . esc_html( Yopingme_Widget::status_label( $svc_state ) ) . '' . ' ' . esc_html( $name ) . ''; } $href = esc_url( $page_url ); // Mandatory link contract: never render a strip without the link. // If the URL was rejected (malformed or non-http scheme), return nothing. if ( '' === $href ) { return ''; } $out .= '' . esc_html( __( 'View full status page', 'yopingme' ) ) . ''; $out .= ''; return $out; } /** * A colored state dot. Colors come from the dashboard widget so both * surfaces always agree; unknown states get its gray default. * * @param string $state Service or rollup state. * @return string */ private static function dot( $state ) { return ''; } /** * The strip's CSS: enough to read as one line with wrapping, restylable * by the theme via the class names, no more. * * @return string */ private static function css() { return '.yopingme-status{display:flex;flex-wrap:wrap;gap:.75em;align-items:center;font-size:.95em}' . '.yopingme-status-dot{display:inline-block;width:.6em;height:.6em;border-radius:50%;vertical-align:baseline}' . '.yopingme-status-overall{font-weight:600}' // The link flows as an ordinary item rather than being pushed // right with margin-left:auto. Themes set the content width, and // an auto margin only looks deliberate in the narrow band where // the strip nearly fills the line: wider leaves the link marooned // across a gap, narrower drops it onto a line of its own. . '.yopingme-status-link{white-space:nowrap}' // Most themes already ship .screen-reader-text; this is a minimal // fallback (WordPress's own clip pattern) for themes that do not, // so the per-service state label stays hidden visually everywhere. . '.yopingme-status .screen-reader-text{border:0;clip:rect(1px,1px,1px,1px);clip-path:inset(50%);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;word-wrap:normal!important}'; } }