<?php
function simple_file_manager_menu() {
add_menu_page(
'Файловый менеджер', // Название страницы
'Файловый менеджер', // Название меню
'manage_options', // Уровень доступа
'simple-file-manager', // Уникальный идентификатор
'simple_file_manager_page' // Функция, которая выводит содержимое страницы
);
}
add_action('admin_menu', 'simple_file_manager_menu');
// Регистрация виджета
function simple_file_manager_widget() {
wp_add_dashboard_widget(
'simple_file_manager_widget', // Уникальный идентификатор
'Файловый менеджер', // Название виджета
'simple_file_manager_widget_display' // Функция, которая выводит содержимое виджета
);
}
add_action('wp_dashboard_setup', 'simple_file_manager_widget');
function simple_file_manager_page() {
$total_space_mb = disk_total_space("/") / 1048576; // Общее место в МБ
$used_space_mb = ($total_space_mb - (disk_free_space("/") / 1048576)); // Занятое место в МБ
$used_space_percent = ($used_space_mb / $total_space_mb) * 100; // Заполненность в %
$free_space_mb = disk_free_space("/") / 1048576; // Свободное место в МБ
?>
<div class="wrap">
<h1>Файловый менеджер</h1>
<div style="margin-bottom: 20px;">
<div style="margin-bottom: 20px;">
<div style="background-color: #e0e0e0; border-radius: 3px; overflow: hidden;">
<div style="width: <?php echo $used_space_percent; ?>%; background-color: #76c7c0; height: 20px; text-align: center; color: white;">
<?php echo round($used_space_mb, 2) . ' МБ из ' . round($total_space_mb, 2) . ' МБ (осталось: ' . round($free_space_mb, 2) . ' МБ)'; ?>
</div>
</div>
</div>
<button id="back-button" style="display:none;">Назад</button>
<button id="root-button">В корень</button>
</div>
<table id="file-manager" style="width:100%; border-collapse: collapse;">
<thead>
<tr>
<th onclick="sortFiles('name')">Имя файла <span id="name-sort-icon"></span></th>
<th onclick="sortFiles('size')">Размер <span id="size-sort-icon"></span></th>
<th onclick="sortFiles('date')">Дата создания <span id="date-sort-icon"></span></th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
<script>
let currentPath = '';
let filesData = [];
let currentSortKey = '';
let currentSortOrder = 'asc'; // 'asc' или 'desc'
document.getElementById('root-button').addEventListener('click', () => {
currentPath = '';
fetchFiles();
});
document.getElementById('back-button').addEventListener('click', () => {
const pathParts = currentPath.split('/').filter(part => part);
pathParts.pop(); // Удаляем последний элемент
currentPath = pathParts.join('/') + '/';
fetchFiles();
});
async function fetchFiles() {
const response = await fetch(`<?php echo admin_url('admin-ajax.php'); ?>?action=get_files&path=${encodeURIComponent(currentPath)}`);
filesData = await response.json();
renderFiles();
}
function renderFiles() {
const tbody = document.querySelector('#file-manager tbody');
tbody.innerHTML = '';
for (const item of filesData) {
const tr = document.createElement('tr');
const nameCell = document.createElement('td');
const sizeCell = document.createElement('td');
const dateCell = document.createElement('td');
if (item.isDirectory) {
nameCell.innerHTML = `<a href="#" onclick="navigateTo('${currentPath}${item.name}/'); return false;">${item.name}/</a>`;
} else {
nameCell.textContent = item.name;
}
sizeCell.textContent = item.size;
dateCell.textContent = item.date;
tr.appendChild(nameCell);
tr.appendChild(sizeCell);
tr.appendChild(dateCell);
tbody.appendChild(tr);
}
document.getElementById('back-button').style.display = currentPath ? 'block' : 'none';
}
function navigateTo(path) {
currentPath = path;
fetchFiles();
}
function sortFiles(key) {
if (currentSortKey === key) {
currentSortOrder = currentSortOrder === 'asc' ? 'desc' : 'asc';
} else {
currentSortOrder = 'asc';
}
currentSortKey = key;
filesData.sort((a, b) => {
if (key === 'name') {
return currentSortOrder === 'asc' ? a.name.localeCompare(b.name) : b.name.localeCompare(a.name);
} else if (key === 'size') {
return currentSortOrder === 'asc' ? a.size - b.size : b.size - a.size;
} else if (key === 'date') {
return currentSortOrder === 'asc' ? new Date(a.date) - new Date(b.date) : new Date(b.date) - new Date(a.date);
}
});
updateSortIcons();
renderFiles();
}
function updateSortIcons() {
document.getElementById('name-sort-icon').textContent = currentSortKey === 'name' ? (currentSortOrder === 'asc' ? '↑' : '↓') : '';
document.getElementById('size-sort-icon').textContent = currentSortKey === 'size' ? (currentSortOrder === 'asc' ? '↑' : '↓') : '';
document.getElementById('date-sort-icon').textContent = currentSortKey === 'date' ? (currentSortOrder === 'asc' ? '↑' : '↓') : '';
}
// Начинаем с корневого каталога
fetchFiles();
</script>
<style>
#file-manager th {
cursor: pointer;
background-color: #f1f1f1;
border-bottom: 2px solid #ccc;
padding: 10px;
}
#file-manager td {
padding: 10px;
border-bottom: 1px solid #eaeaea;
}
#file-manager tr:hover {
background-color: #f9f9f9;
}
#back-button, #root-button {
margin-right: 10px;
padding: 5px 10px;
}
</style>
<?php
}
function simple_file_manager_widget_display() {
$total_space_mb = disk_total_space("/") / 1048576; // Общее место в МБ
$used_space_mb = ($total_space_mb - (disk_free_space("/") / 1048576)); // Занятое место в МБ
$used_space_percent = ($used_space_mb / $total_space_mb) * 100; // Заполненность в %
$free_space_mb = disk_free_space("/") / 1048576; // Свободное место в МБ
?>
<div id="file-manager-widget" style="overflow-y: auto; max-height: 400px;">
<div style="margin-bottom: 20px;">
<div style="background-color: #e0e0e0; border-radius: 3px; overflow: hidden;">
<div style="width: <?php echo $used_space_percent; ?>%; background-color: #76c7c0; height: 20px; text-align: center; color: white;">
<?php echo round($used_space_mb, 2) . ' МБ из ' . round($total_space_mb, 2) . ' МБ (осталось: ' . round($free_space_mb, 2) . ' МБ)'; ?>
</div>
</div>
</div>
<button id="back-button" style="display:none;">Назад</button>
<button id="root-button">В корень</button>
<table id="file-manager" style="width:100%; border-collapse: collapse;">
<thead>
<tr>
<th onclick="sortFiles('name')">Имя файла <span id="name-sort-icon"></span></th>
<th onclick="sortFiles('size')">Размер <span id="size-sort-icon"></span></th>
<th onclick="sortFiles('date')">Дата создания <span id="date-sort-icon"></span></th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
<script>
let currentPath = '';
let filesData = [];
let currentSortKey = '';
let currentSortOrder = 'asc'; // 'asc' или 'desc'
document.getElementById('root-button').addEventListener('click', () => {
currentPath = '';
fetchFiles();
});
document.getElementById('back-button').addEventListener('click', () => {
const pathParts = currentPath.split('/').filter(part => part);
pathParts.pop(); // Удаляем последний элемент
currentPath = pathParts.join('/') + '/';
fetchFiles();
});
async function fetchFiles() {
const response = await fetch(`<?php echo admin_url('admin-ajax.php'); ?>?action=get_files&path=${encodeURIComponent(currentPath)}`);
filesData = await response.json();
renderFiles();
}
function renderFiles() {
const tbody = document.querySelector('#file-manager tbody');
tbody.innerHTML = '';
for (const item of filesData) {
const tr = document.createElement('tr');
const nameCell = document.createElement('td');
const sizeCell = document.createElement('td');
const dateCell = document.createElement('td');
if (item.isDirectory) {
nameCell.innerHTML = `<a href="#" onclick="navigateTo('${currentPath}${item.name}/'); return false;">${item.name}/</a>`;
} else {
nameCell.textContent = item.name;
}
sizeCell.textContent = item.size;
dateCell.textContent = item.date;
tr.appendChild(nameCell);
tr.appendChild(sizeCell);
tr.appendChild(dateCell);
tbody.appendChild(tr);
}
document.getElementById('back-button').style.display = currentPath ? 'block' : 'none';
}
function navigateTo(path) {
currentPath = path;
fetchFiles();
}
function sortFiles(key) {
if (currentSortKey === key) {
currentSortOrder = currentSortOrder === 'asc' ? 'desc' : 'asc';
} else {
currentSortOrder = 'asc';
}
currentSortKey = key;
filesData.sort((a, b) => {
if (key === 'name') {
return currentSortOrder === 'asc' ? a.name.localeCompare(b.name) : b.name.localeCompare(a.name);
} else if (key === 'size') {
return currentSortOrder === 'asc' ? a.size - b.size : b.size - a.size;
} else if (key === 'date') {
return currentSortOrder === 'asc' ? new Date(a.date) - new Date(b.date) : new Date(b.date) - new Date(a.date);
}
});
updateSortIcons();
renderFiles();
}
function updateSortIcons() {
document.getElementById('name-sort-icon').textContent = currentSortKey === 'name' ? (currentSortOrder === 'asc' ? '↑' : '↓') : '';
document.getElementById('size-sort-icon').textContent = currentSortKey === 'size' ? (currentSortOrder === 'asc' ? '↑' : '↓') : '';
document.getElementById('date-sort-icon').textContent = currentSortKey === 'date' ? (currentSortOrder === 'asc' ? '↑' : '↓') : '';
}
// Начинаем с корневого каталога
fetchFiles();
</script>
<style>
#file-manager th {
cursor: pointer;
background-color: #f1f1f1;
border-bottom: 2px solid #ccc;
padding: 10px;
}
#file-manager td {
padding: 10px;
border-bottom: 1px solid #eaeaea;
}
#file-manager tr:hover {
background-color: #f9f9f9;
}
#back-button, #root-button {
margin-right: 10px;
padding: 5px 10px;
margin-bottom: 10px;
}
</style>
<?php
}
function get_files() {
$path = isset($_GET['path']) ? $_GET['path'] : '';
$fullPath = ABSPATH . $path; // Путь к директории
if (!is_dir($fullPath)) {
wp_send_json_error('Директория не найдена');
return;
}
$files = array();
$dir = opendir($fullPath);
while (($file = readdir($dir)) !== false) {
if ($file != '.' && $file != '..') {
$filePath = $fullPath . '/' . $file;
$size = is_dir($filePath) ? get_directory_size($filePath) : filesize($filePath);
$date = date("Y-m-d H:i:s", filemtime($filePath));
$files[] = array(
'name' => $file,
'size' => formatSize($size),
'date' => $date,
'isDirectory' => is_dir($filePath)
);
}
}
closedir($dir);
wp_send_json($files);
}
function get_directory_size($dir) {
$size = 0;
$files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir));
foreach ($files as $file) {
if ($file->isFile()) {
$size += $file->getSize();
}
}
return $size;
}
function formatSize($size) {
if ($size < 1024) return $size . ' Б';
if ($size < 1048576) return round($size / 1024, 2) . ' КБ';
if ($size < 1073741824) return round($size / 1048576, 2) . ' МБ';
return round($size / 1073741824, 2) . ' ГБ';
}
add_action('wp_ajax_get_files', 'get_files');
?>