# xspeed/1.0.3/includes/class-object-cache.php

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

- Page: https://pluginprobe.com/plugins/xspeed/1.0.3/code/includes/class-object-cache.php
- Raw: https://pluginprobe.com/plugins/xspeed/1.0.3/raw/includes/class-object-cache.php
- Modified: 2026-06-01T17:33:22+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.3/code/includes/class-object-cache.php#L10-L20`.

```php
<?php
/**
 * Object_Cache — read-only detector + flusher + wp-config snippet
 * generator for the persistent object cache.
 *
 * We deliberately do NOT install our own object-cache.php drop-in
 * from this Free release — that's invasive, has many failure modes
 * (auth, TLS, cluster vs single, Redis vs Predis vs phpredis,
 * Memcache vs Memcached), and changes how every site reads/writes
 * persistent state. The Free plugin's role is:
 *
 *   1. Tell the user whether a drop-in is currently active and
 *      which backend it appears to be.
 *   2. Provide a Flush button that calls wp_cache_flush() — which
 *      works regardless of which drop-in is installed.
 *   3. Save backend-config values (host, port, password, etc.) and
 *      render a wp-config.php snippet the user can paste, so the
 *      flow is "configure here → copy snippet → install drop-in"
 *      without us writing to wp-config ourselves.
 *
 * The Pro plugin (or a later Free release once well tested) can
 * ship a drop-in that consumes these saved values automatically.
 *
 * @package XSpeed
 */

declare(strict_types=1);

namespace XSpeed;

defined( 'ABSPATH' ) || exit;

final class Object_Cache {

	/**
	 * Inspect the runtime + filesystem for a persistent object cache.
	 *
	 * @return array{
	 *   drop_in_installed: bool,
	 *   drop_in_path: string,
	 *   drop_in_label: string,
	 *   backend: string,        // redis|memcached|apcu|wp_default|unknown
	 *   wp_cache_active: bool,  // wp_using_ext_object_cache
	 *   class_available: array<string,bool>
	 * }
	 */
	public static function detect(): array {
		$dropin       = defined( 'WP_CONTENT_DIR' ) ? WP_CONTENT_DIR . '/object-cache.php' : '';
		$has_drop_in  = '' !== $dropin && file_exists( $dropin );
		$label        = $has_drop_in ? self::sniff_drop_in_label( $dropin ) : '';
		$ext_in_use   = function_exists( 'wp_using_ext_object_cache' ) ? (bool) wp_using_ext_object_cache() : false;

		// Class sniffer — independent of any plugin. Tells us what's
		// available to actually use, separate from what's wired up.
		$class_available = array(
			'Redis'     => class_exists( '\\Redis' ),
			'Memcached' => class_exists( '\\Memcached' ),
			'Memcache'  => class_exists( '\\Memcache' ),
			'APCu'      => function_exists( 'apcu_enabled' ) && @apcu_enabled(),
		);

		$backend = 'unknown';
		if ( ! $ext_in_use ) {
			$backend = 'wp_default';
		} elseif ( $has_drop_in ) {
			// Best-effort: the label usually contains the backend name.
			$lc = strtolower( $label );
			if ( false !== strpos( $lc, 'redis' ) ) {
				$backend = 'redis';
			} elseif ( false !== strpos( $lc, 'memcached' ) || false !== strpos( $lc, 'memcache' ) ) {
				$backend = 'memcached';
			} elseif ( false !== strpos( $lc, 'apcu' ) ) {
				$backend = 'apcu';
			}
		}

		return array(
			'drop_in_installed' => $has_drop_in,
			'drop_in_path'      => $dropin,
			'drop_in_label'     => $label,
			'backend'           => $backend,
			'wp_cache_active'   => $ext_in_use,
			'class_available'   => $class_available,
		);
	}

	/**
	 * Flush whatever cache backend is wired up. Works against any
	 * compliant drop-in OR the WP default in-memory cache.
	 */
	public static function flush(): bool {
		if ( ! function_exists( 'wp_cache_flush' ) ) {
			return false;
		}
		return (bool) wp_cache_flush();
	}

	/**
	 * Render a paste-into-wp-config.php snippet for the chosen backend
	 * using the supplied settings. The constant names match the
	 * conventions of the widely-used Redis Object Cache + W3TC drop-ins
	 * so users with those installed get a working configuration
	 * without any further translation.
	 */
	public static function render_config_snippet( array $opts ): string {
		$backend = (string) ( $opts['backend'] ?? 'redis' );
		$lines   = array( "/* xSpeed object cache config — paste above the \"That's all, stop editing!\" comment in wp-config.php. */" );

		if ( 'redis' === $backend ) {
			$host    = self::str( $opts, 'redis_host', '127.0.0.1' );
			$port    = self::int( $opts, 'redis_port', 6379 );
			$pass    = self::str( $opts, 'redis_password', '' );
			$db      = self::int( $opts, 'redis_database', 0 );
			$prefix  = self::str( $opts, 'key_prefix', '' );
			$timeout = self::int( $opts, 'connection_timeout', 1 );
			$persist = ! empty( $opts['persistent'] );

			$lines[] = "define( 'WP_REDIS_HOST', '" . self::esc( $host ) . "' );";
			$lines[] = "define( 'WP_REDIS_PORT', " . $port . ' );';
			if ( '' !== $pass ) {
				$lines[] = "define( 'WP_REDIS_PASSWORD', '" . self::esc( $pass ) . "' );";
			}
			$lines[] = "define( 'WP_REDIS_DATABASE', " . $db . ' );';
			if ( '' !== $prefix ) {
				$lines[] = "define( 'WP_CACHE_KEY_SALT', '" . self::esc( $prefix ) . "' );";
			}
			$lines[] = "define( 'WP_REDIS_TIMEOUT', " . $timeout . ' );';
			$lines[] = "define( 'WP_REDIS_PERSISTENT', " . ( $persist ? 'true' : 'false' ) . ' );';
		} elseif ( 'memcached' === $backend ) {
			$host    = self::str( $opts, 'memcached_host', '127.0.0.1' );
			$port    = self::int( $opts, 'memcached_port', 11211 );
			$prefix  = self::str( $opts, 'key_prefix', '' );
			$lines[] = "global \$memcached_servers;";
			$lines[] = "\$memcached_servers = array( array( '" . self::esc( $host ) . "', " . $port . ' ) );';
			if ( '' !== $prefix ) {
				$lines[] = "define( 'WP_CACHE_KEY_SALT', '" . self::esc( $prefix ) . "' );";
			}
		} else {
			$lines[] = '// No snippet for backend: ' . $backend;
		}

		return implode( "\n", $lines ) . "\n";
	}

	private static function sniff_drop_in_label( string $path ): string {
		$head = @file_get_contents( $path, false, null, 0, 2048 );
		if ( ! is_string( $head ) || '' === $head ) {
			return '';
		}
		// PluginName / Plugin Name in standard WP file header form.
		if ( preg_match( '#Plugin Name:\s*([^\r\n]+)#i', $head, $m ) ) {
			return trim( $m[1] );
		}
		// Many drop-ins just put their identity in a comment.
		if ( preg_match( '#\*\s*([A-Za-z][A-Za-z0-9 _\-]{2,40}(?:Cache|Redis|Memcached)[^\r\n]*)#i', $head, $m ) ) {
			return trim( $m[1] );
		}
		return basename( $path );
	}

	private static function str( array $opts, string $key, string $default ): string {
		return isset( $opts[ $key ] ) && '' !== $opts[ $key ] ? (string) $opts[ $key ] : $default;
	}

	private static function int( array $opts, string $key, int $default ): int {
		return isset( $opts[ $key ] ) && '' !== $opts[ $key ] ? (int) $opts[ $key ] : $default;
	}

	private static function esc( string $s ): string {
		return str_replace( array( '\\', "'" ), array( '\\\\', "\\'" ), $s );
	}
}

```
