feat: detailed cache diagnostics with file checks
- AJAX returns structured log array (type + text per step) - Checks: all system files, PHP extension, drop-in status, WP_CACHE_KEY_SALT, versioned cache, object cache, transients - Drop-in auto-copy with success/fail/permission diagnostics - JS renders log as color-coded list with summary line - Fix for previous commit: plugin memcached not found typo
This commit is contained in:
parent
60a0847501
commit
7566f4da53
@ -2323,25 +2323,34 @@ function dekart_flush_cache_page() {
|
||||
?>
|
||||
<div class="wrap">
|
||||
<h1>🗄️ Сброс кеша</h1>
|
||||
<p class="desc" style="margin:16px 0;color:#646970;font-size:13px">Полная очистка объектного кеша (Memcached/Redis), инвалидация versioned cache ключей, сброс транзиентов.<br><br>
|
||||
Если drop-in Memcached ещё не установлен — кнопка автоматически скопирует его из плагина. Активировать плагин Memcached не нужно.</p>
|
||||
<p class="desc" style="margin:16px 0;color:#646970;font-size:13px">Полная диагностика и очистка: проверка файлов, установка drop-in, сброс кеша и транзиентов.</p>
|
||||
<button type="button" id="dekart-flush-cache-btn" class="button button-hero button-secondary" style="display:inline-flex;align-items:center;gap:8px">
|
||||
<span class="dashicons dashicons-update" style="font-size:20px;width:20px;height:20px"></span> Сбросить кэш сейчас
|
||||
<span class="dashicons dashicons-update" style="font-size:20px;width:20px;height:20px"></span> Выполнить проверку и сброс
|
||||
</button>
|
||||
<span id="dekart-flush-cache-status" style="margin-left:16px;display:none"></span>
|
||||
<div id="dekart-flush-cache-log" style="margin-top:20px;max-width:700px;display:none"></div>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
var btn = document.getElementById('dekart-flush-cache-btn');
|
||||
var status = document.getElementById('dekart-flush-cache-status');
|
||||
var log = document.getElementById('dekart-flush-cache-log');
|
||||
if (!btn) return;
|
||||
|
||||
function addLog(type, text) {
|
||||
var icons = { ok: '✅', fail: '❌', warn: '⚠️', info: 'ℹ️', doing: '🔄' };
|
||||
var colors = { ok: '#00a32a', fail: '#d63638', warn: '#dba617', info: '#2271b1', doing: '#646970' };
|
||||
var line = document.createElement('div');
|
||||
line.style.cssText = 'padding:6px 10px;margin:2px 0;border-radius:4px;background:#f6f7f7;font-size:13px;line-height:1.5';
|
||||
line.innerHTML = (icons[type] || '') + ' <span style="color:' + (colors[type] || '#333') + '">' + text + '</span>';
|
||||
log.appendChild(line);
|
||||
}
|
||||
|
||||
btn.addEventListener('click', function() {
|
||||
if (btn.disabled) return;
|
||||
btn.disabled = true;
|
||||
btn.innerHTML = '<span style="display:inline-block;animation:spin 1s linear infinite">↻</span> Сброс...';
|
||||
status.style.display = 'inline';
|
||||
status.innerHTML = '⏳';
|
||||
status.style.color = '#646970';
|
||||
btn.innerHTML = '<span style="display:inline-block;animation:spin 1s linear infinite">↻</span> Выполнение...';
|
||||
log.style.display = 'block';
|
||||
log.innerHTML = '';
|
||||
addLog('doing', 'Запуск диагностики...');
|
||||
|
||||
var data = new FormData();
|
||||
data.set('action', 'dekart_flush_cache');
|
||||
@ -2350,22 +2359,28 @@ function dekart_flush_cache_page() {
|
||||
fetch(ajaxurl, { method: 'POST', body: data })
|
||||
.then(function(r) { return r.json(); })
|
||||
.then(function(j) {
|
||||
if (j.success) {
|
||||
status.innerHTML = '✅ ' + (j.data.message || 'Кэш сброшен');
|
||||
status.style.color = '#00a32a';
|
||||
log.innerHTML = '';
|
||||
if (j.success && j.data && j.data.log) {
|
||||
j.data.log.forEach(function(item) {
|
||||
addLog(item.type, item.text);
|
||||
});
|
||||
if (j.data.summary) {
|
||||
var s = document.createElement('div');
|
||||
s.style.cssText = 'margin-top:12px;padding:10px 14px;border-radius:6px;font-weight:600;font-size:14px;background:' + (j.data.summary.type === 'ok' ? '#edfaef' : '#fcf0f1') + ';color:' + (j.data.summary.type === 'ok' ? '#00a32a' : '#d63638');
|
||||
s.innerHTML = (j.data.summary.type === 'ok' ? '✅' : '❌') + ' ' + j.data.summary.text;
|
||||
log.appendChild(s);
|
||||
}
|
||||
} else {
|
||||
status.innerHTML = '❌ ' + (j.data.message || 'Ошибка');
|
||||
status.style.color = '#d63638';
|
||||
addLog('fail', j.data && j.data.message ? j.data.message : 'Неизвестная ошибка');
|
||||
}
|
||||
})
|
||||
.catch(function() {
|
||||
status.innerHTML = '❌ Ошибка соединения';
|
||||
status.style.color = '#d63638';
|
||||
log.innerHTML = '';
|
||||
addLog('fail', 'Ошибка соединения с сервером');
|
||||
})
|
||||
.finally(function() {
|
||||
btn.disabled = false;
|
||||
btn.innerHTML = '<span class="dashicons dashicons-update" style="font-size:20px;width:20px;height:20px"></span> Сбросить кэш сейчас';
|
||||
setTimeout(function() { status.style.display = 'none'; }, 5000);
|
||||
btn.innerHTML = '<span class="dashicons dashicons-update" style="font-size:20px;width:20px;height:20px"></span> Выполнить проверку и сброс';
|
||||
});
|
||||
});
|
||||
})();
|
||||
@ -2436,45 +2451,105 @@ function dekart_ajax_flush_cache() {
|
||||
wp_send_json_error( array( 'message' => 'Нет прав' ) );
|
||||
}
|
||||
|
||||
$messages = array();
|
||||
$log = array();
|
||||
$errors = 0;
|
||||
$abspath = defined( 'ABSPATH' ) ? ABSPATH : dirname( __DIR__, 4 ) . '/';
|
||||
|
||||
// 0. Установка Memcached drop-in (если ещё не скопирован)
|
||||
$source = WP_CONTENT_DIR . '/plugins/memcached/object-cache.php';
|
||||
$target = WP_CONTENT_DIR . '/object-cache.php';
|
||||
if ( ! file_exists( $target ) ) {
|
||||
if ( file_exists( $source ) ) {
|
||||
if ( copy( $source, $target ) ) {
|
||||
$messages[] = 'drop-in installed';
|
||||
} else {
|
||||
$messages[] = '⚠ drop-in copy failed (permissions?)';
|
||||
}
|
||||
// ── 1. Проверка файлов ──
|
||||
$files = array(
|
||||
'MU-плагин (object-cache-bootstrap)' => WP_CONTENT_DIR . '/mu-plugins/object-cache-bootstrap.php',
|
||||
'Плагин Memcached (object-cache.php)' => WP_CONTENT_DIR . '/plugins/memcached/object-cache.php',
|
||||
'Тема (functions.php)' => get_template_directory() . '/functions.php',
|
||||
'wp-config.php' => $abspath . 'wp-config.php',
|
||||
);
|
||||
$log[] = array( 'type' => 'info', 'text' => '🔍 Проверка файлов системы:' );
|
||||
foreach ( $files as $label => $path ) {
|
||||
if ( file_exists( $path ) ) {
|
||||
$size = size_format( filesize( $path ) );
|
||||
$log[] = array( 'type' => 'ok', 'text' => "{$label} — найден ({$size})" );
|
||||
} else {
|
||||
$messages[] = '⚠ plugin memcached not found';
|
||||
$log[] = array( 'type' => 'warn', 'text' => "{$label} — отсутствует" );
|
||||
}
|
||||
}
|
||||
|
||||
// 1. Versioned cache bump (MU-плагин)
|
||||
// ── 2. PHP extension Memcache ──
|
||||
$log[] = array( 'type' => 'info', 'text' => '🔍 Проверка PHP-расширения:' );
|
||||
if ( class_exists( 'Memcache' ) || class_exists( 'Memcached' ) ) {
|
||||
$ext = class_exists( 'Memcached' ) ? 'memcached' : 'memcache';
|
||||
$log[] = array( 'type' => 'ok', 'text' => "PHP-расширение {$ext} — установлено" );
|
||||
} else {
|
||||
$log[] = array( 'type' => 'warn', 'text' => 'PHP-расширение memcache/memcached — не найдено (обратитесь в хостинг)' );
|
||||
}
|
||||
|
||||
// ── 3. Memcached drop-in ──
|
||||
$source = WP_CONTENT_DIR . '/plugins/memcached/object-cache.php';
|
||||
$target = WP_CONTENT_DIR . '/object-cache.php';
|
||||
|
||||
$log[] = array( 'type' => 'info', 'text' => '🔍 Проверка drop-in Memcached:' );
|
||||
if ( file_exists( $target ) ) {
|
||||
$size = size_format( filesize( $target ) );
|
||||
$log[] = array( 'type' => 'ok', 'text' => "Drop-in уже установлен: wp-content/object-cache.php ({$size})" );
|
||||
} else {
|
||||
if ( file_exists( $source ) ) {
|
||||
$copied = copy( $source, $target );
|
||||
if ( $copied ) {
|
||||
$size = size_format( filesize( $target ) );
|
||||
$log[] = array( 'type' => 'ok', 'text' => "Drop-in скопирован: plugins/memcached/object-cache.php → wp-content/object-cache.php ({$size})" );
|
||||
} else {
|
||||
$log[] = array( 'type' => 'fail', 'text' => 'Ошибка копирования! Проверьте права на wp-content/' );
|
||||
$errors++;
|
||||
}
|
||||
} else {
|
||||
$log[] = array( 'type' => 'warn', 'text' => 'Плагин Memcached не установлен. Установите: wp plugin install memcached' );
|
||||
}
|
||||
}
|
||||
|
||||
// ── 4. Проверка WP_CACHE_KEY_SALT ──
|
||||
$log[] = array( 'type' => 'info', 'text' => '🔍 Проверка изоляции ключей кеша:' );
|
||||
if ( defined( 'WP_CACHE_KEY_SALT' ) && WP_CACHE_KEY_SALT !== '' ) {
|
||||
$log[] = array( 'type' => 'ok', 'text' => 'WP_CACHE_KEY_SALT = ' . WP_CACHE_KEY_SALT . ' (изоляция активна)' );
|
||||
} else {
|
||||
$log[] = array( 'type' => 'fail', 'text' => 'WP_CACHE_KEY_SALT не задан! Добавьте в wp-config.php: define( "WP_CACHE_KEY_SALT", DB_NAME );' );
|
||||
$errors++;
|
||||
}
|
||||
|
||||
// ── 5. Versioned cache bump (MU-плагин) ──
|
||||
$log[] = array( 'type' => 'info', 'text' => '🔍 Инвалидация versioned cache:' );
|
||||
if ( function_exists( 'my_cache_bump_version' ) ) {
|
||||
my_cache_bump_version();
|
||||
$messages[] = 'version bumped';
|
||||
$log[] = array( 'type' => 'ok', 'text' => 'Версия кеша обновлена (my_cache_bump_version)' );
|
||||
} else {
|
||||
$log[] = array( 'type' => 'warn', 'text' => 'my_cache_bump_version() не найдена — MU-плагин не активен' );
|
||||
}
|
||||
|
||||
// 2. WP object cache flush (Memcached/Redis drop-in)
|
||||
// ── 6. WP object cache flush ──
|
||||
$log[] = array( 'type' => 'info', 'text' => '🔍 Очистка объектного кеша:' );
|
||||
if ( function_exists( 'wp_cache_flush' ) ) {
|
||||
wp_cache_flush();
|
||||
$messages[] = 'wp_cache_flush';
|
||||
$flushed = wp_cache_flush();
|
||||
if ( $flushed ) {
|
||||
$log[] = array( 'type' => 'ok', 'text' => 'wp_cache_flush() — успешно' );
|
||||
} else {
|
||||
$log[] = array( 'type' => 'warn', 'text' => 'wp_cache_flush() — не выполнен (кеш не активен?)' );
|
||||
}
|
||||
} else {
|
||||
$log[] = array( 'type' => 'warn', 'text' => 'wp_cache_flush() — функция не найдена (drop-in не установлен)' );
|
||||
}
|
||||
|
||||
// 3. Transients — все сразу
|
||||
// ── 7. Transients ──
|
||||
$log[] = array( 'type' => 'info', 'text' => '🔍 Очистка транзиентов:' );
|
||||
global $wpdb;
|
||||
$wpdb->query( "DELETE FROM {$wpdb->options} WHERE option_name LIKE '_transient_%' OR option_name LIKE '_transient_timeout_%'" );
|
||||
$deleted = $wpdb->query( "DELETE FROM {$wpdb->options} WHERE option_name LIKE '_transient_%' OR option_name LIKE '_transient_timeout_%'" );
|
||||
$log[] = array( 'type' => 'ok', 'text' => "Удалено {$deleted} записей _transient_* из wp_options" );
|
||||
|
||||
$messages[] = 'transients clean';
|
||||
|
||||
// 4. CSS/JS кеш — сброс через filemtime (версии ассетов обновятся сами)
|
||||
// ── Итог ──
|
||||
if ( $errors === 0 ) {
|
||||
$summary = array( 'type' => 'ok', 'text' => 'Всё выполнено успешно. Ошибок нет.' );
|
||||
} else {
|
||||
$summary = array( 'type' => 'fail', 'text' => "Выполнено с {$errors} ошибкой(ами). Проверьте лог выше." );
|
||||
}
|
||||
|
||||
wp_send_json_success( array(
|
||||
'message' => 'Кэш сброшен: ' . implode( ', ', $messages ),
|
||||
'actions' => $messages,
|
||||
'log' => $log,
|
||||
'summary' => $summary,
|
||||
) );
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user