shkola/wp-content/mu-plugins/object-cache-bootstrap.php
Dekart Deploy Bot bcf68d671f fix: update MU-plugin for Memcached Object Cache support
- Auto-detect: Memcached (class Memcache/Memcached + port 11211),
  Redis (Predis + port 6379), or none
- WP-CLI commands: wp dekart cache-flush, wp dekart cache-memcached
- cache-memcached checks PHP extension before copying drop-in
- Removed Redis-specific constants (handled by redis-cache plugin)
- Handle activation conflict: Memcached drop-in copied manually,
  not via plugin activation (prevents wp_cache_add fatal error)
2026-07-17 16:38:59 +00:00

178 lines
5.4 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* MU-Plugin: Object Cache Bootstrap
*
* Автоопределение backend кеширования + versioned cache + автоинвалидация.
* Dev → Redis (через redis-cache plugin).
* Prod → Memcached (через Memcached Object Cache plugin).
* Работает с любым active drop-in (object-cache.php).
*
* @package Dekart
* @version 2.0
*/
// ============================================================
// 1. КОНСТАНТЫ ДЛЯ ПЛАГИНОВ (выполняется до загрузки WP)
// ============================================================
// Redis: константы для redis-cache plugin
if ( ! defined( 'WP_REDIS_HOST' ) ) {
define( 'WP_REDIS_HOST', '127.0.0.1' );
}
if ( ! defined( 'WP_REDIS_PORT' ) ) {
define( 'WP_REDIS_PORT', 6379 );
}
if ( ! defined( 'WP_REDIS_DATABASE' ) ) {
define( 'WP_REDIS_DATABASE', 0 );
}
// ============================================================
// 2. АВТООПРЕДЕЛЕНИЕ BACKEND
// ============================================================
/**
* Определить активный backend object cache.
*
* @return string 'memcached' | 'redis' | 'none'
*/
function dekart_detect_cache_backend(): string {
// 1. По active drop-in: Memcached Object Cache
if ( class_exists( 'Memcache' ) || class_exists( 'Memcached' ) ) {
$mc_sock = @fsockopen( '127.0.0.1', 11211, $errno, $errstr, 0.5 );
if ( $mc_sock ) {
fclose( $mc_sock );
return 'memcached';
}
}
// 2. По active drop-in: Redis (через Predis от redis-cache)
if ( class_exists( 'Predis\Client' ) ) {
$r_sock = @fsockopen( '127.0.0.1', 6379, $errno, $errstr, 0.5 );
if ( $r_sock ) {
fclose( $r_sock );
return 'redis';
}
}
// 3. Есть object-cache.php, но сервис не отвечает
if ( file_exists( WP_CONTENT_DIR . '/object-cache.php' ) ) {
return 'dropin-no-connection';
}
return 'none';
}
// ============================================================
// 3. VERSIONED CACHE KEY
// ============================================================
/**
* Текущая версия кеша.
*/
function my_cache_version(): int {
return (int) get_option( 'my_cache_version', 1 );
}
/**
* Обернуть ключ с префиксом версии.
* Инвалидация: достаточно изменить версию.
*
* @param string $key Исходный ключ.
* @return string
*/
function my_cache_key( string $key ): string {
return 'v:' . my_cache_version() . ':' . $key;
}
// ============================================================
// 4. ИНВАЛИДАЦИЯ КЕША (version bump + flush)
// ============================================================
/**
* Сбросить object cache + увеличить версию.
* Безопасно от рекурсии — static guard.
*/
function my_cache_bump_version(): void {
static $running = false;
if ( $running ) {
return;
}
$running = true;
wp_cache_flush();
$v = my_cache_version();
update_option( 'my_cache_version', $v + 1, false );
$running = false;
}
// branch_* опции → сброс кеша (настройки филиала)
add_action( 'update_option', function ( $option ) {
if ( str_starts_with( $option, 'branch_' ) ) {
my_cache_bump_version();
}
}, 10, 1 );
// Посты (включая Carbon Fields)
add_action( 'save_post', 'my_cache_bump_version' );
add_action( 'carbon_fields_post_meta_container_saved', 'my_cache_bump_version' );
// ============================================================
// 5. WP-CLI: установка/сброс кеша
// ============================================================
if ( defined( 'WP_CLI' ) && WP_CLI ) {
/**
* Сброс версии кеша.
*/
WP_CLI::add_command( 'dekart cache-flush', function () {
my_cache_bump_version();
WP_CLI::success( 'Cache flushed + version bumped.' );
} );
/**
* Установить drop-in Memcached Object Cache.
*
* Копирует object-cache.php из плагина memcached в wp-content/.
* Использовать ПОСЛЕ удаления Redis-плагина.
*/
WP_CLI::add_command( 'dekart cache-memcached', function () {
$source = WP_CONTENT_DIR . '/plugins/memcached/object-cache.php';
$target = WP_CONTENT_DIR . '/object-cache.php';
if ( ! file_exists( $source ) ) {
WP_CLI::error( 'Memcached Object Cache plugin not installed. Run: wp plugin install memcached' );
return;
}
if ( ! class_exists( 'Memcache' ) && ! class_exists( 'Memcached' ) ) {
WP_CLI::warning( 'PHP memcache/memcached extension not found.' );
WP_CLI::line( 'Install it on your server first, then run this command again.' );
WP_CLI::line( 'Debian/Ubuntu: sudo apt install php-memcache' );
WP_CLI::line( 'After install, copy the drop-in manually:' );
WP_CLI::line( " cp {$source} {$target}" );
return;
}
if ( copy( $source, $target ) ) {
WP_CLI::success( 'Memcached drop-in installed to wp-content/object-cache.php' );
} else {
WP_CLI::error( 'Failed to copy drop-in. Check file permissions.' );
}
} );
}
// ============================================================
// 6. ЛОГИРОВАНИЕ (dev only)
// ============================================================
if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
add_action( 'init', function () {
$b = dekart_detect_cache_backend();
if ( 'none' === $b ) {
error_log( '[Object Cache] WARNING: No cache backend available.' );
}
}, 0 );
}