salt_keys( DB_NAME ); } }, 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. АДМИН-НОТИСЫ // ============================================================ /** * Убрать ссылку "Активировать" у плагина Memcached Object Cache. * Плагин — только источник object-cache.php, активация вызывает фатальную ошибку. */ add_filter( 'plugin_action_links_memcached/object-cache.php', function ( $actions ) { unset( $actions['activate'] ); $actions['info'] = '⚠ установите drop-in вручную'; 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; // drop-in уже стоит } if ( class_exists( 'Memcache' ) || class_exists( 'Memcached' ) ) { $conn = @fsockopen( '127.0.0.1', 11211, $errno, $errstr, 0.5 ); if ( $conn ) { fclose( $conn ); printf( '

%s

', 'Кеширование: Memcached доступен. Установите drop-in командой: cp ' . esc_html( str_replace( ABSPATH, '', $source ) ) . ' ' . esc_html( str_replace( ABSPATH, '', $target ) ) . ' или через WP-CLI: wp dekart cache-memcached' ); return; } printf( '

%s

', 'Кеширование: PHP-расширение Memcache установлено, но сервер Memcached (127.0.0.1:11211) не отвечает. Запустите Memcached на сервере или обратитесь в хостинг.' ); return; } printf( '

%s

', 'Кеширование: Плагин Memcached Object Cache установлен, но PHP-расширение memcache не найдено. Установите его на сервере (через панель хостинга: PHP → Расширения → memcache). Не активируйте плагин — он работает как drop-in.' ); } ); // ============================================================ // 6. 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.' ); } } ); } // ============================================================ // 7. ЛОГИРОВАНИЕ // ============================================================ 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 ); }