shkola/wp-content/mu-plugins/object-cache-bootstrap.php
Dekart Deploy Bot 76303d3a3b feat: add MU-plugin for cache backend auto-detection + versioned cache invalidation
- Auto-detects Memcached/Redis via fsockopen
- Versioned cache key helper (my_cache_key)
- Auto-flush on option/post/CF changes (no manual wp cache flush)
- WP-CLI command: wp dekart cache-flush
- Admin bar shows backend + cache version
2026-07-17 16:09:56 +00:00

165 lines
5.6 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 + Predis).
* Prod → Memcached (через Memcached Object Cache plugin, устанавливается вручную).
*
* @package Dekart
*/
// ============================================================
// 1. АВТООПРЕДЕЛЕНИЕ BACKEND
// ============================================================
/**
* Определить доступный backend для object cache.
*
* @return string 'memcached' | 'redis' | 'none'
*/
function dekart_detect_cache_backend(): string {
// 1. Приоритет: Memcached (проверка порта)
$memcached_sock = @fsockopen( '127.0.0.1', 11211, $errno, $errstr, 0.5 );
if ( $memcached_sock ) {
fclose( $memcached_sock );
return 'memcached';
}
// 2. Redis: проверяем через Predis (установлен composer)
if ( class_exists( 'Predis\Client' ) ) {
$redis_sock = @fsockopen( '127.0.0.1', 6379, $errno, $errstr, 0.5 );
if ( $redis_sock ) {
fclose( $redis_sock );
return 'redis';
}
}
// 3. Ничего не доступно
return 'none';
}
// ============================================================
// 2. КОНСТАНТЫ ДЛЯ ПЛАГИНОВ
// ============================================================
$backend = dekart_detect_cache_backend();
// Redis: define константы для redis-cache plugin
if ( 'redis' === $backend ) {
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 );
}
}
// ============================================================
// 3. ЛОГИРОВАНИЕ (dev only)
// ============================================================
if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
error_log( '[Object Cache] Backend detected: ' . $backend );
if ( 'none' === $backend ) {
error_log( '[Object Cache] WARNING: No cache backend available. Site will run without object cache.' );
}
}
// ============================================================
// 4. VERSIONED CACHE KEY
// ============================================================
/**
* Получить текущую версию кеша.
*/
function my_cache_version(): int {
return (int) get_option( 'my_cache_version', 1 );
}
/**
* Обернуть ключ кеша с версией.
* Позволяет инвалидировать весь кеш без flush — достаточно изменить версию.
*
* @param string $key Исходный ключ.
* @return string Ключ с префиксом версии.
*/
function my_cache_key( string $key ): string {
return 'v:' . my_cache_version() . ':' . $key;
}
// ============================================================
// 5. ИНВАЛИДАЦИЯ КЕША
// ============================================================
/**
* Увеличить версию кеша + сбросить object cache.
* Все кешированные данные сбрасываются — при следующем запросе читаются свежие.
*/
function my_cache_bump_version(): void {
// Сбрасываем object cache (Redis / Memcached)
wp_cache_flush();
// Обновляем версию для my_cache_key()
$v = my_cache_version();
update_option( 'my_cache_version', $v + 1, false );
if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
error_log( sprintf( '[Object Cache] Flushed + version bumped: %d → %d', $v, $v + 1 ) );
}
}
// ============================================================
// 6. ХУКИ АВТОИНВАЛИДАЦИИ
// ============================================================
// Опции: при любом изменении сбрасываем версию
add_action( 'update_option', 'my_cache_bump_version' );
add_action( 'added_option', 'my_cache_bump_version' );
add_action( 'deleted_option', 'my_cache_bump_version' );
// Посты: при сохранении (включая ACF, Carbon Fields)
add_action( 'save_post', 'my_cache_bump_version' );
// Carbon Fields: сохранение мета-боксов
add_action( 'carbon_fields_post_meta_container_saved', 'my_cache_bump_version' );
// ============================================================
// 7. ХЕЛПЕР: ПРОМЫВКА КЕША ИЗ АДМИНКИ
// ============================================================
/**
* Добавить кнопку "Сбросить кеш" в админ-бар (только для админов).
*/
add_action( 'admin_bar_menu', function ( WP_Admin_Bar $wp_admin_bar ) {
if ( ! current_user_can( 'manage_options' ) ) {
return;
}
// Показываем текущий backend
$backend_label = 'none' === $backend ? 'no-cache' : $backend;
$wp_admin_bar->add_node( array(
'id' => 'dekart-cache-status',
'title' => sprintf(
'<span style="font-size:12px;opacity:0.7">Cache: %s | v%s</span>',
$backend_label,
my_cache_version()
),
'href' => '#',
) );
}, 100 );
// ============================================================
// 8. WP-CLI: командa для сброса версии
// ============================================================
if ( defined( 'WP_CLI' ) && WP_CLI ) {
WP_CLI::add_command( 'dekart cache-flush', function () {
my_cache_bump_version();
WP_CLI::success( 'Cache version bumped. All versioned cache keys are invalidated.' );
} );
}