shkola/wp-content/mu-plugins/object-cache-bootstrap.php
Dekart Deploy Bot 2deb14c736 fix: auto-install memcached drop-in + block plugin activation
- dekart_try_install_memcached_dropin(): auto-copy object-cache.php
  from memcached plugin to wp-content/ on plugins_loaded
- Remove 'Activate' link for memcached plugin (prevents fatal error)
- Admin notice with instructions when PHP extension is missing
- WP-CLI command: wp dekart cache-memcached
2026-07-17 16:49:56 +00:00

224 lines
7.2 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 + автоинвалидация.
* Работает с любым active drop-in (object-cache.php).
*
* УСТАНОВКА MEMCACHED НА ПРОДЕ:
* 1. Установить PHP-расширение: sudo apt install php-memcache
* 2. wp plugin install memcached (установить плагин)
* 3. Скопировать drop-in:
* cp wp-content/plugins/memcached/object-cache.php wp-content/object-cache.php
* 4. Плагин НЕ активировать — он нужен только как источник файла.
*
* @package Dekart
* @version 2.1
*/
// ============================================================
// 1. КОНСТАНТЫ ДЛЯ ПЛАГИНОВ
// ============================================================
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
// ============================================================
function dekart_detect_cache_backend(): string {
if ( class_exists( 'Memcache' ) || class_exists( 'Memcached' ) ) {
$sock = @fsockopen( '127.0.0.1', 11211, $errno, $errstr, 0.5 );
if ( $sock ) {
fclose( $sock );
return 'memcached';
}
}
if ( class_exists( 'Predis\Client' ) ) {
$sock = @fsockopen( '127.0.0.1', 6379, $errno, $errstr, 0.5 );
if ( $sock ) {
fclose( $sock );
return 'redis';
}
}
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 );
}
function my_cache_key( string $key ): string {
return 'v:' . my_cache_version() . ':' . $key;
}
// ============================================================
// 4. ИНВАЛИДАЦИЯ КЕША
// ============================================================
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;
}
add_action( 'update_option', function ( $option ) {
if ( str_starts_with( $option, 'branch_' ) ) {
my_cache_bump_version();
}
}, 10, 1 );
add_action( 'save_post', 'my_cache_bump_version' );
add_action( 'carbon_fields_post_meta_container_saved', 'my_cache_bump_version' );
// ============================================================
// 5. АВТОУСТАНОВКА DROP-IN MEMCACHED (для прода)
// ============================================================
/**
* Попробовать установить drop-in Memcached, если:
* - плагин memcached установлен,
* - object-cache.php ещё нет,
* - PHP-расширение Memcache доступно.
*/
function dekart_try_install_memcached_dropin(): void {
$target = WP_CONTENT_DIR . '/object-cache.php';
if ( file_exists( $target ) ) {
return; // drop-in уже есть
}
$source = WP_CONTENT_DIR . '/plugins/memcached/object-cache.php';
if ( ! file_exists( $source ) ) {
return; // плагин не установлен
}
if ( ! class_exists( 'Memcache' ) && ! class_exists( 'Memcached' ) ) {
return; // нет PHP-расширения
}
copy( $source, $target );
}
add_action( 'plugins_loaded', 'dekart_try_install_memcached_dropin', 0 );
// ============================================================
// 6. АДМИН-НОТИС + БЛОКИРОВКА АКТИВАЦИИ MEMCACHED PLUGIN
// ============================================================
/**
* Убрать ссылку "Активировать" у плагина Memcached Object Cache —
* он содержит только object-cache.php, активация вызывает фатальную ошибку.
* Файл копируется автоматически через dekart_try_install_memcached_dropin().
*/
add_filter( 'plugin_action_links_memcached/object-cache.php', function ( $actions ) {
unset( $actions['activate'] );
$actions['info'] = '<span style="color:#999">drop-in (копируется автоматически)</span>';
return $actions;
} );
add_action( 'admin_notices', function () {
if ( ! current_user_can( 'manage_options' ) ) {
return;
}
$source = WP_CONTENT_DIR . '/plugins/memcached/object-cache.php';
$target = WP_CONTENT_DIR . '/object-cache.php';
if ( ! file_exists( $source ) ) {
return;
}
if ( file_exists( $target ) ) {
return;
}
if ( class_exists( 'Memcache' ) || class_exists( 'Memcached' ) ) {
return;
}
printf(
'<div class="notice notice-warning is-dismissible"><p>%s</p></div>',
'<strong>Настройка кеширования:</strong> Плагин Memcached Object Cache установлен, но PHP-расширение <code>memcache</code> не найдено.
Установите его на сервере (sudo apt install php-memcache), после чего drop-in скопируется автоматически.
<strong>Не активируйте плагин</strong> — это вызовет фатальную ошибку. Он работает как drop-in.'
);
} );
// ============================================================
// 7. 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.' );
} );
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 ( file_exists( $target ) ) {
WP_CLI::success( 'Drop-in already exists at wp-content/object-cache.php' );
return;
}
if ( ! class_exists( 'Memcache' ) && ! class_exists( 'Memcached' ) ) {
WP_CLI::warning( 'PHP memcache extension not found. Install it:' );
WP_CLI::line( ' sudo apt install php-memcache' );
WP_CLI::line( ' sudo systemctl restart php8.3-fpm' );
WP_CLI::line( 'Then run this command again.' );
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 permissions.' );
}
} );
}
// ============================================================
// 8. ЛОГИРОВАНИЕ
// ============================================================
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 );
}