* } */ 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 ); } }