# xspeed/1.0.0/includes/class-admin.php

xSpeed Cache: AI-Powered Performance Hub with MCP, Caching &amp; CDN, version 1.0.0. 123 lines.

- Page: https://pluginprobe.com/plugins/xspeed/1.0.0/code/includes/class-admin.php
- Raw: https://pluginprobe.com/plugins/xspeed/1.0.0/raw/includes/class-admin.php
- Modified: 2026-05-27T11:31:36+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/xspeed/1.0.0/code/includes/class-admin.php#L10-L20`.

```php
<?php
/**
 * Admin menu + asset enqueue.
 *
 * @package XSpeed
 */

namespace XSpeed;

defined( 'ABSPATH' ) || exit;

class Admin {

	const PAGE_SLUG = 'xspeed';

	public function __construct() {
		add_action( 'admin_menu', array( $this, 'register_menu' ) );
		add_action( 'admin_enqueue_scripts', array( $this, 'enqueue' ) );
		add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_menu_styles' ) );
	}

	public function register_menu() {
		add_menu_page(
			__( 'xSpeed', 'xspeed' ),
			__( 'xSpeed', 'xspeed' ),
			'manage_options',
			self::PAGE_SLUG,
			array( $this, 'render' ),
			self::menu_icon(),
			80
		);
	}

	/**
	 * URL of the SVG menu icon — the official xSpeed brand mark. Uses
	 * fill="currentColor" which renders black in <img> context; the inline
	 * style below recolors it via CSS filter for the WP admin menu states.
	 */
	private static function menu_icon() {
		return XSPEED_URL . 'assets/icon.svg';
	}

	public function render() {
		echo '<div id="xspeed-app" class="xspeed-root"></div>';
	}

	/**
	 * Enqueue the stylesheet that recolors the menu icon to match the WP
	 * admin color scheme. Loads on every admin page (not just the plugin's
	 * page) because the menu icon is visible site-wide.
	 */
	public function enqueue_menu_styles() {
		wp_enqueue_style(
			'xspeed-menu-icon',
			XSPEED_URL . 'assets/menu-icon.css',
			array(),
			XSPEED_VERSION
		);
	}

	public function enqueue( $hook ) {
		if ( 'toplevel_page_' . self::PAGE_SLUG !== $hook ) {
			return;
		}

		$asset_js  = XSPEED_DIR . 'assets/admin.js';
		$asset_css = XSPEED_DIR . 'assets/admin.css';

		if ( file_exists( $asset_js ) ) {
			wp_enqueue_script(
				'xspeed-admin',
				XSPEED_URL . 'assets/admin.js',
				array( 'wp-api-fetch' ),
				XSPEED_VERSION,
				true
			);
		}

		if ( file_exists( $asset_css ) ) {
			wp_enqueue_style(
				'xspeed-admin',
				XSPEED_URL . 'assets/admin.css',
				array(),
				XSPEED_VERSION
			);
		}

		wp_localize_script(
			'xspeed-admin',
			'XSpeedConfig',
			array(
				'restUrl'   => esc_url_raw( rest_url( Rest_Api::NAMESPACE_V1 ) ),
				'nonce'     => wp_create_nonce( 'wp_rest' ),
				'version'   => XSPEED_VERSION,
				'bootstrap' => self::bootstrap_payload(),
			)
		);
	}

	/**
	 * Pre-rendered settings + status payload, baked into the page so the
	 * React app can mount with real values instead of showing a loading state
	 * while it waits for /settings and /status REST calls.
	 */
	private static function bootstrap_payload() {
		$opts  = Settings::get();
		$stats = Cache::get_stats();
		return array(
			'settings' => $opts,
			'status'   => array(
				'enabled' => (bool) $opts['cache_enabled'],
				'stats'   => $stats,
				'server'  => array(
					'type'          => Server::type(),
					'gzip_mode'     => Server::gzip_mode(),
					'gzip_active'   => Gzip::probe_active(),
					'nginx_snippet' => Gzip::nginx_snippet(),
				),
			),
		);
	}
}

```
