Files
profile/inc/sql_result.php
Profile Profile ed4d79b706 add files inc
2026-03-09 20:51:08 +03:00

221 lines
9.0 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
add_action('wp_footer', 'display_sql_queries_in_footer', 9999);
function display_sql_queries_in_footer() {
if (!current_user_can('administrator')) {
return;
}
global $wpdb;
if (empty($wpdb->queries)) {
echo '<div style="background: #fff; padding: 20px; margin: 20px; border: 1px solid #ccc; font-family: monospace; font-size: 14px; position: relative; z-index: 99999;">';
echo '<p>Нет данных о запросах. Убедитесь, что в wp-config.php добавлена строка:</p>';
echo '<code style="background: #f4f4f4; padding: 5px; display: block;">define( \'SAVEQUERIES\', true );</code>';
echo '</div>';
return;
}
$queries = $wpdb->queries;
$total_time = 0;
foreach ($queries as $query) {
$total_time += $query[1];
}
echo '<div id="sql-debug-panel" style="background: #fff; padding: 20px; margin: 20px; border: 1px solid #ccc; font-family: monospace; font-size: 14px; position: relative; z-index: 99999;">';
// Панель управления сортировкой
echo '<div style="margin-bottom: 20px; padding: 10px; background: #f5f5f5; border-radius: 5px;">';
echo '<h3 style="margin-top: 0; display: inline-block; margin-right: 20px;">SQL Запросы</h3>';
echo '<button onclick="sortQueries(\'time-desc\')" style="margin-right: 10px; padding: 5px 10px; background: #e74c3c; color: white; border: none; border-radius: 3px; cursor: pointer;">Самые медленные</button>';
echo '<button onclick="sortQueries(\'time-asc\')" style="margin-right: 10px; padding: 5px 10px; background: #27ae60; color: white; border: none; border-radius: 3px; cursor: pointer;">Самые быстрые</button>';
echo '<button onclick="sortQueries(\'default\')" style="margin-right: 10px; padding: 5px 10px; background: #3498db; color: white; border: none; border-radius: 3px; cursor: pointer;">По умолчанию</button>';
echo '<span style="margin-left: 20px; font-weight: bold;">Всего запросов: ' . count($queries) . '</span>';
echo '</div>';
echo '<table id="sql-queries-table" style="width: 100%; border-collapse: collapse; margin-top: 15px;">';
echo '<thead>';
echo '<tr style="background: #2c3e50; color: #fff; cursor: pointer;">';
echo '<th style="padding: 8px; border: 1px solid #ddd; text-align: left;" onclick="sortQueries(\'time-desc\')">Время ⬇</th>';
echo '<th style="padding: 8px; border: 1px solid #ddd; text-align: left;">Запрос</th>';
echo '<th style="padding: 8px; border: 1px solid #ddd; text-align: left;">Вызвавший код</th>';
echo '</tr>';
echo '</thead>';
echo '<tbody>';
foreach ($queries as $query) {
$time = number_format($query[1] * 1000, 2);
$time_seconds = $query[1];
$color = '#27ae60';
if ($query[1] > 0.1) $color = '#f39c12';
if ($query[1] > 0.5) $color = '#e74c3c';
echo '<tr class="sql-query-row">';
echo '<td style="padding: 8px; border: 1px solid #ddd; color: ' . $color . '; font-weight: bold;" data-time="' . $time_seconds . '">' . $time . ' ms</td>';
echo '<td style="padding: 8px; border: 1px solid #ddd; word-break: break-all;">' . htmlspecialchars($query[0]) . '</td>';
echo '<td style="padding: 8px; border: 1px solid #ddd; font-size: 12px; color: #666;">' . $query[2] . '</td>';
echo '</tr>';
}
echo '</tbody>';
echo '</table>';
echo '<div style="margin-top: 15px; padding: 10px; background: #f8f9fa; border-left: 4px solid #3498db;">';
echo 'Общее время SQL запросов: <strong>' . number_format($total_time * 1000, 2) . ' ms</strong><br>';
echo 'Среднее время на запрос: <strong>' . number_format(($total_time / count($queries)) * 1000, 2) . ' ms</strong>';
echo '</div>';
echo '</div>';
// Добавляем JavaScript для сортировки
echo '
<script>
function sortQueries(sortType) {
const table = document.getElementById("sql-queries-table");
const tbody = table.querySelector("tbody");
const rows = Array.from(tbody.querySelectorAll("tr.sql-query-row"));
// Сбрасываем классы активной сортировки у заголовков
const headers = table.querySelectorAll("th");
headers.forEach(header => {
header.innerHTML = header.innerHTML.replace(" ⬇", "").replace(" ⬆", "");
});
// Добавляем индикатор сортировки
if (sortType === "time-desc") {
headers[0].innerHTML = "Время ⬇";
} else if (sortType === "time-asc") {
headers[0].innerHTML = "Время ⬆";
}
rows.sort((a, b) => {
const timeA = parseFloat(a.querySelector("td[data-time]").getAttribute("data-time"));
const timeB = parseFloat(b.querySelector("td[data-time]").getAttribute("data-time"));
switch(sortType) {
case "time-desc":
return timeB - timeA; // Самые медленные first
case "time-asc":
return timeA - timeB; // Самые быстрые first
case "default":
return 0; // Оригинальный порядок
default:
return 0;
}
});
// Очищаем и перезаполняем tbody
while (tbody.firstChild) {
tbody.removeChild(tbody.firstChild);
}
rows.forEach(row => {
tbody.appendChild(row);
});
}
// Добавляем поиск по запросам
function addSearchFeature() {
const panel = document.getElementById("sql-debug-panel");
const searchHtml = \`
<div style="margin-bottom: 15px;">
<input type="text" id="sql-search" placeholder="Поиск по запросам..."
style="padding: 8px; width: 300px; border: 1px solid #ddd; border-radius: 3px;">
<button onclick="filterQueries()" style="padding: 8px 15px; background: #3498db; color: white; border: none; border-radius: 3px; cursor: pointer;">Поиск</button>
<button onclick="clearSearch()" style="padding: 8px 15px; background: #95a5a6; color: white; border: none; border-radius: 3px; cursor: pointer;">Очистить</button>
</div>
\`;
const controlsDiv = panel.querySelector("div");
controlsDiv.insertAdjacentHTML("afterend", searchHtml);
}
function filterQueries() {
const searchTerm = document.getElementById("sql-search").value.toLowerCase();
const rows = document.querySelectorAll("tr.sql-query-row");
rows.forEach(row => {
const queryText = row.querySelector("td:nth-child(2)").textContent.toLowerCase();
const callerText = row.querySelector("td:nth-child(3)").textContent.toLowerCase();
if (queryText.includes(searchTerm) || callerText.includes(searchTerm)) {
row.style.display = "";
} else {
row.style.display = "none";
}
});
}
function clearSearch() {
document.getElementById("sql-search").value = "";
const rows = document.querySelectorAll("tr.sql-query-row");
rows.forEach(row => {
row.style.display = "";
});
}
// Инициализируем поиск при загрузке
document.addEventListener("DOMContentLoaded", function() {
addSearchFeature();
});
</script>
';
}
// Добавляем стили и скрипты
add_action('wp_enqueue_scripts', 'add_sql_debug_styles');
function add_sql_debug_styles() {
if (!current_user_can('administrator')) {
return;
}
wp_enqueue_style('sql-debug-style', false);
echo '
<style>
#sql-debug-panel {
max-height: 600px;
overflow-y: auto;
position: fixed;
bottom: 20px;
right: 20px;
width: 90%;
max-width: 1200px;
box-shadow: 0 0 20px rgba(0,0,0,0.3);
border-radius: 8px;
}
.sql-query-row:hover {
background-color: #f8f9fa !important;
}
.sort-btn {
margin-right: 10px;
padding: 8px 15px;
border: none;
border-radius: 4px;
cursor: pointer;
font-weight: bold;
transition: background-color 0.3s;
}
.sort-btn:hover {
opacity: 0.9;
}
.sort-desc { background: #e74c3c; color: white; }
.sort-asc { background: #27ae60; color: white; }
.sort-default { background: #3498db; color: white; }
#sql-search {
padding: 8px;
width: 300px;
border: 1px solid #ddd;
border-radius: 4px;
margin-right: 10px;
}
</style>
';
}