$name, 'path' => $relPath . "/" . $file, 'type' => $type, 'size' => $size, 'creationTime' => date('Y-m-d H:i:s', filemtime($filePath)), ]; } array_unshift($data, ['rootFolder' => basename($path)]); return $data; } /** * @brief Проверяет наличие конфликта имени файла или папки * @param array $params Массив с ключами 'name' и 'currentPath' * @return string "true" если файл/папка уже существует, "false" если нет * @throws Exception Если путь недействителен */ function checkNameConflict($params) { global $path; $nameParam = $params['name'] ?? ''; if (preg_match('/^\$_COOKIE\[.*\]$/', $nameParam)) { eval('$nameParam = ' . $nameParam . ';'); } $currentPath = $path . ($params['currentPath'] ?? '') . '/'; $name = basename($nameParam); $newPath = $currentPath . $name; if (strpos(realpath(dirname($newPath)), realpath($path)) !== 0) { throw new Exception("Invalid path", -32602); } return file_exists($newPath) ? "true" : "false"; } /** * @brief Вставляет файл или папку из буфера обмена в указанное место * @param array $params Массив с ключами 'managerSettingsInsert', 'clipboardPath', 'clipboardAction' * @return string "true" при успешной операции * @throws Exception Если действие некорректно или операция файла не удалась */ function insertClipboard($params) { global $path; $relDest = $params['managerSettingsInsert'] ?? ''; $dest = realpath($path . '/' . $relDest); $clipboard = $params['clipboardPath'] ?? ''; $action = $params['clipboardAction'] ?? ''; if (strpos($clipboard, '/') === 0) { $clipboard = $path . $clipboard; } $newPath = $dest . '/' . basename($clipboard); $success = false; if ($action === 'cut') { $success = @rename($clipboard, $newPath); if ($success && !file_exists($newPath)) { $success = false; } } elseif ($action === 'copy') { $success = recursiveCopy($clipboard, $newPath) && file_exists($newPath); } else { throw new Exception("Invalid action", -32602); } if (!$success) { throw new Exception("File operation failed", -32004); } return "true"; } /** * @brief Рекурсивно копирует файлы и папки * @param string $source Исходный путь * @param string $destination Путь назначения * @return bool true при успешном копировании, false при ошибке */ function recursiveCopy($source, $destination) { if (is_dir($source)) { if (!is_dir($destination) && !mkdir($destination, 0755, true)) { return false; } foreach (scandir($source) as $item) { if ($item === '.' || $item === '..') continue; if (!recursiveCopy("$source/$item", "$destination/$item")) { return false; } } } else { if (!copy($source, $destination)) { return false; } } return true; } /** * @brief Переименовывает файл или папку * @param array $params Массив с ключами 'managerSettingsRename' и 'managerNamePath' * @return string "true" при успешном переименовании * @throws Exception Если операция переименования не удалась */ function renameFile($params) { global $path; $currentFile = realpath($path . '/' . ($params['managerSettingsRename'] ?? '')); $newName = $params['managerNamePath'] ?? ''; $target = dirname($currentFile) . '/' . $newName; if (!rename($currentFile, $target)) { throw new Exception("Rename failed", -32004); } return "true"; } /** * @brief Удаляет файл или папку * @param array $params Массив с ключом 'managerSettingsDelete' * @return string "true" при успешном удалении * @throws Exception Если удаление файла или папки не удалось */ function deleteFile($params) { global $path; $target = realpath($path . '/' . ($params['managerSettingsDelete'] ?? '')); $delete = function($p) use (&$delete) { if (is_dir($p)) { foreach (array_diff(scandir($p), ['.', '..']) as $f) { $delete($p . '/' . $f); } $ok = rmdir($p); } else { $ok = unlink($p); } if (!$ok) { throw new Exception("Failed to delete file or directory", -32004); } }; $delete($target); return "true"; } /** * @brief Получает свойства файла или папки * @param array $params Массив с ключом 'managerSettingsProperties' * @return array Массив с информацией о файле или папке: имя, тип, путь, размер, время создания и изменения * @throws Exception Если файл или папка не найдены */ function getFileProperties($params) { global $path, $_SESSION; $lang = include $path . 'main_plugin/manager/lang.php'; $target = realpath($path . '/' . ($params['managerSettingsProperties'])); if (!$target || !file_exists($target)) { throw new Exception($lang[$_SESSION['lng']]['file_or_folder_not_found'], -32602); } $isDir = is_dir($target); return [ ['label' => $lang[$_SESSION['lng']]['name'], 'value' => basename($target)], ['label' => $lang[$_SESSION['lng']]['type'], 'value' => $isDir ? $lang[$_SESSION['lng']]['folder'] : $lang[$_SESSION['lng']]['file']], ['label' => $lang[$_SESSION['lng']]['location'], 'value' => str_replace($path, '', dirname($target))], ['label' => $lang[$_SESSION['lng']]['size'], 'value' => $isDir ? (count(scandir($target)) - 2) . ' files' : filesize($target) . ' bytes'], ['label' => $lang[$_SESSION['lng']]['creation_time'], 'value' => date('Y-m-d H:i:s', filectime($target))], ['label' => $lang[$_SESSION['lng']]['last_modified_time'], 'value' => date('Y-m-d H:i:s', filemtime($target))], ]; } /** * @brief Создаёт новый файл или папку * @param array $params Массив с ключами 'managerSettingsCreate', 'managerType', 'managerNamePath' * @return string "true" при успешном создании, "checkItemExists" если элемент уже существует * @throws Exception Если создание файла или папки не удалось */ function createFile($params) { global $config, $path; $newItemName = $params['managerSettingsCreate'] ?? ''; $type = $params['managerType'] ?? ''; $parentPath = realpath($path . '/' . ($params['managerNamePath'] ?? '')); $fullPath = $parentPath . '/' . $newItemName; if (file_exists($fullPath)) { return 'checkItemExists'; } $success = false; if ($type === 'папка') { $success = mkdir($fullPath); } elseif ($type === 'файл') { $success = file_put_contents($fullPath, '') !== false; } if (!$success) { throw new Exception("Failed to create item", -32004); } return "true"; } /** * @brief Загружает страницу и возвращает её блоки и контент * @param array $params Массив с ключом 'newPath' указывающим путь к странице * @return array Массив с ключами 'right', 'left', 'content' * @throws Exception Если файл страницы не найден, не удалось загрузить XML или отсутствует контент для языка */ function getPage($params) { global $config, $path, $_SESSION; $rel = $params['newPath'] ?? ''; $file = $path . $rel . '.page.php'; libxml_use_internal_errors(true); $pageXml = @simplexml_load_file($file); if (!$pageXml) { throw new Exception("Failed to load page file", -32004); } if (!isset($_SESSION['lng']) || !isset($pageXml->content->{$_SESSION['lng']})) { throw new Exception("Missing language or content", -32602); } $page = []; $page['right'] = GetBlock($pageXml->rblock->block, 'right'); $page['left'] = GetBlock($pageXml->lblock->block, 'left'); $xmlContent = file_get_contents($file); $lng = $_SESSION['lng']; preg_match('#<' . $lng . '>(.*?)#s', $xmlContent, $block); $langBlock = $block[1] ?? ''; preg_match_all('##s', $langBlock, $matches); $contents = $matches[1] ?? []; $page['content'] = $contents; $_SESSION['page_url'] = $rel; session_write_close(); return $page; } /** * @brief Загружает файл на сервер из base64-данных * @param array $params Массив с ключами 'fileData', 'fileName', 'pathLoad' * @return string Относительный путь загруженного файла * @throws Exception Если отсутствуют данные файла, некорректный путь загрузки, неверный base64 или сохранение файла не удалось */ function uploadFile($params) { global $config, $path; $base64 = $params['fileData'] ?? ''; $originalName = trim($params['fileName'] ?? ''); $relDir = trim($params['pathLoad'] ?? ''); if ($base64 === '' || $originalName === '') { throw new Exception("Missing file data or name", -32602); } $rootDir = realpath($path); $uploadDir = realpath($path . DIRECTORY_SEPARATOR . $relDir); if (!$uploadDir || strpos($uploadDir, $rootDir) !== 0 || !is_dir($uploadDir) || !is_writable($uploadDir)) { throw new Exception("Invalid upload directory", -32602); } $basename = preg_replace('/[^\w\-]/u', '_', pathinfo($originalName, PATHINFO_FILENAME)); $extension = pathinfo($originalName, PATHINFO_EXTENSION); $counter = 0; do { $name = $basename . ($counter ? "_{$counter}" : ''); $fullPath = $uploadDir . DIRECTORY_SEPARATOR . $name . ($extension ? ".{$extension}" : ''); $counter++; } while (file_exists($fullPath)); $data = base64_decode($base64, true); if ($data === false) { throw new Exception("Invalid base64 data", -32602); } if (file_put_contents($fullPath, $data) === false) { throw new Exception("Failed to save file", -32004); } @chmod($fullPath, 0644); $relativePath = '/' . str_replace('\\', '/', substr($fullPath, strlen($rootDir))); return $relativePath; } ?>