<?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'); ?>
СНИППЕТ