'', 'monitor' => '', 'footer' => 0, 'alignment' => 'center', ); } /** * Get settings merged with defaults. * * @return array */ function mcpss_get_settings() { $opts = get_option( MCPSS_OPTION, array() ); return wp_parse_args( is_array( $opts ) ? $opts : array(), mcpss_defaults() ); } /** * Turn a slug or a mcpserverstatus.com URL into a clean slug. * * @param string $input Raw input. * @return string */ function mcpss_parse_slug( $input ) { $input = trim( (string) $input ); if ( '' === $input ) { return ''; } if ( preg_match( '#mcpserverstatus\.com/(?:mcp-servers|badge)/([^/?\#]+)#i', $input, $m ) ) { $input = $m[1]; } $input = preg_replace( '/\.svg$/i', '', $input ); return sanitize_title( $input ); } /** * Sanitize a monitor public ID (or badge URL). * * @param string $input Raw input. * @return string */ function mcpss_parse_monitor( $input ) { $input = trim( (string) $input ); if ( preg_match( '#/badge/m/([^/?\#]+)#i', $input, $m ) ) { $input = $m[1]; } $input = preg_replace( '/\.svg$/i', '', $input ); return preg_replace( '/[^A-Za-z0-9_-]/', '', $input ); } /** * Build badge HTML. Output is fully escaped. * * @param string $slug Server slug. * @param string $monitor Monitor public ID (takes priority). * @param string $alignment left|center|right|none. * @return string */ function mcpss_badge_html( $slug, $monitor = '', $alignment = 'none' ) { $slug = mcpss_parse_slug( $slug ); $monitor = mcpss_parse_monitor( $monitor ); if ( '' === $slug && '' === $monitor ) { return ''; } if ( '' !== $monitor ) { $img = MCPSS_BASE . '/badge/m/' . rawurlencode( $monitor ) . '.svg'; $link = '' !== $slug ? MCPSS_BASE . '/mcp-servers/' . rawurlencode( $slug ) : MCPSS_BASE; } else { $img = MCPSS_BASE . '/badge/' . rawurlencode( $slug ) . '.svg'; $link = MCPSS_BASE . '/mcp-servers/' . rawurlencode( $slug ); } $alignment = in_array( $alignment, array( 'left', 'center', 'right' ), true ) ? $alignment : 'none'; $style = 'none' === $alignment ? '' : ' style="text-align:' . esc_attr( $alignment ) . ';"'; return sprintf( '
', esc_attr( $alignment ), $style, esc_url( $link ), esc_url( $img ), esc_attr__( 'MCP server status', 'mcp-server-status' ) ); } /** * [mcp_status slug="..." monitor="..." align="..."] shortcode. * * @param array $atts Attributes. * @return string */ function mcpss_shortcode( $atts ) { $s = mcpss_get_settings(); $atts = shortcode_atts( array( 'slug' => $s['slug'], 'monitor' => '', 'align' => 'none', ), $atts, 'mcp_status' ); return mcpss_badge_html( $atts['slug'], $atts['monitor'], $atts['align'] ); } /** * Footer badge (opt-in only). */ function mcpss_footer_badge() { $s = mcpss_get_settings(); if ( empty( $s['footer'] ) ) { return; } $html = mcpss_badge_html( $s['slug'], $s['monitor'], $s['alignment'] ); if ( '' !== $html ) { echo ''; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- built from escaped parts in mcpss_badge_html(). } } /** * Register the dynamic block. */ function mcpss_register_block() { if ( function_exists( 'register_block_type' ) ) { register_block_type( MCPSS_DIR . 'blocks/badge', array( 'render_callback' => 'mcpss_render_block' ) ); } } /** * Block render callback. * * @param array $attrs Block attributes. * @return string */ function mcpss_render_block( $attrs ) { $s = mcpss_get_settings(); $slug = ! empty( $attrs['slug'] ) ? $attrs['slug'] : $s['slug']; $mon = isset( $attrs['monitor'] ) ? $attrs['monitor'] : ''; $al = isset( $attrs['align'] ) ? $attrs['align'] : 'none'; return mcpss_badge_html( $slug, $mon, $al ); } /** * Settings link on Plugins screen. * * @param array $links Links. * @return array */ function mcpss_action_links( $links ) { $links[] = '' . esc_html__( 'Settings', 'mcp-server-status' ) . ''; return $links; }