';
$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}';
}
}