Upload files to "public"
This commit is contained in:
commit
7a9e6fd1d6
35
public/create-folder.php
Normal file
35
public/create-folder.php
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
function join_paths() {
|
||||||
|
$paths = array();
|
||||||
|
|
||||||
|
foreach (func_get_args() as $arg) {
|
||||||
|
if ($arg !== '') { $paths[] = $arg; }
|
||||||
|
}
|
||||||
|
|
||||||
|
return preg_replace('#/+#','/',join('/', $paths));
|
||||||
|
}
|
||||||
|
|
||||||
|
$request_body = file_get_contents('php://input');
|
||||||
|
$data = json_decode($request_body);
|
||||||
|
|
||||||
|
$filesDir = "../../files/"; // Musi kończyć się slashem!
|
||||||
|
$redirectRoute = "/pen"; // Adres względny do któego ma przekierować, jeżeli masz index.php w public/upload to powinno być to /upload
|
||||||
|
|
||||||
|
$targetName = $data->name;
|
||||||
|
$targetPath = $data->path;
|
||||||
|
|
||||||
|
$fullTargetPath = join_paths($filesDir, $targetPath, $targetName);
|
||||||
|
|
||||||
|
if (!file_exists($fullTargetPath)) {
|
||||||
|
if (mkdir($fullTargetPath)) { // Skopiuj zuploadowany plik do poprawnego miejsca na serwerze
|
||||||
|
http_response_code(200);
|
||||||
|
header('Location: '.$redirectRoute); // Przekieruj z powrotem do strony głównej
|
||||||
|
} else { // W razie gdyby coś nie wyszło po stronie serwera podczas kopiowania pliku
|
||||||
|
http_response_code(500);
|
||||||
|
echo "500 - Sorry, there was an error creating your folder.";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
http_response_code(409);
|
||||||
|
echo "409 - File already exists";
|
||||||
|
}
|
||||||
|
?>
|
29
public/file.php
Normal file
29
public/file.php
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
function join_paths() {
|
||||||
|
$paths = array();
|
||||||
|
|
||||||
|
foreach (func_get_args() as $arg) {
|
||||||
|
if ($arg !== '') { $paths[] = $arg; }
|
||||||
|
}
|
||||||
|
|
||||||
|
return preg_replace('#/+#','/',join('/', $paths));
|
||||||
|
}
|
||||||
|
|
||||||
|
$filesDir = "../../files/"; // Musi kończyć się slashem!
|
||||||
|
|
||||||
|
$dirList = preg_grep('/^([^.])/', scandir($filesDir)); // Skanuj
|
||||||
|
if (in_array($_GET['name'], $dirList) && file_exists(join_paths($filesDir, $_GET['name']))) {
|
||||||
|
header('Content-Description: File Transfer'); // Ustaw headery które będą pokazywać przeglądarce, że zasób jest plikiem do pobrania, oraz będą wysyłać metadane pliku
|
||||||
|
header('Content-Type: application/octet-stream');
|
||||||
|
header('Content-Disposition: attachment; filename=' . basename(join_paths($filesDir, $_GET['name'])));
|
||||||
|
header('Content-Transfer-Encoding: binary');
|
||||||
|
header('Expires: 0');
|
||||||
|
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
|
||||||
|
header('Pragma: public');
|
||||||
|
header('Content-Length: ' . filesize(join_paths($filesDir, $_GET['name'])));
|
||||||
|
ob_clean();
|
||||||
|
flush(); // Wyczyść bufer outputu, żeby nie obciążać pliku
|
||||||
|
readfile(join_paths($filesDir, $_GET['name'])); // Zwróć plik do klienta
|
||||||
|
exit;
|
||||||
|
} else { http_response_code(404); echo "<h1>404 - Not Found (Requested file not found)</h1>"; }
|
||||||
|
?>
|
186
public/index.php
Normal file
186
public/index.php
Normal file
@ -0,0 +1,186 @@
|
|||||||
|
<?php
|
||||||
|
function join_paths() {
|
||||||
|
$paths = array();
|
||||||
|
|
||||||
|
foreach (func_get_args() as $arg) {
|
||||||
|
if ($arg !== '') { $paths[] = $arg; }
|
||||||
|
}
|
||||||
|
|
||||||
|
return preg_replace('#/+#','/',join('/', $paths));
|
||||||
|
}
|
||||||
|
|
||||||
|
$filesDir = "../../files/"; // Musi kończyć się slashem!
|
||||||
|
$maxFolderSize = 250000000; // Maks. rozmiar folderu z plikami (w bajtach)
|
||||||
|
|
||||||
|
$directorySize = getDirectorySize($filesDir);
|
||||||
|
if (isset($_GET["path"])) {
|
||||||
|
$path = $_GET["path"];
|
||||||
|
|
||||||
|
if (is_dir(join_paths($filesDir, $path)) && !str_contains($path, "../")) {
|
||||||
|
$filesDir = join_paths($filesDir, $path);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
header('Location: '."?path=/");
|
||||||
|
}
|
||||||
|
|
||||||
|
$dirList = preg_grep('/^([^.])/', scandir($filesDir)); // Pobierz listę plików z pominięciem nazw zaczętych kropką ('.')
|
||||||
|
|
||||||
|
function formatBytes($bytes, $precision = 2) {
|
||||||
|
$units = array('B', 'KB', 'MB', 'GB', 'TB');
|
||||||
|
|
||||||
|
$bytes = max($bytes, 0);
|
||||||
|
$pow = floor(($bytes ? log($bytes) : 0) / log(1024));
|
||||||
|
$pow = min($pow, count($units) - 1);
|
||||||
|
|
||||||
|
$bytes /= pow(1024, $pow);
|
||||||
|
|
||||||
|
return round($bytes, $precision) . $units[$pow];
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDirectorySize($path){
|
||||||
|
$bytestotal = 0;
|
||||||
|
$path = realpath($path);
|
||||||
|
if($path!==false && $path!='' && file_exists($path)){
|
||||||
|
foreach(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS)) as $object){
|
||||||
|
$bytestotal += $object->getSize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $bytestotal;
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="pl">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Upload service</title>
|
||||||
|
<link rel="stylesheet" href="style.css">
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;700&family=Quicksand:wght@400;700&display=swap" rel="stylesheet">
|
||||||
|
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" />
|
||||||
|
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="box">
|
||||||
|
<div class="pobieranie">
|
||||||
|
<h1>Udostępnij plik</h1>
|
||||||
|
<button id="uploadButton">Prześlij plik</button>
|
||||||
|
<h3>Zajęte miejsce: <?php echo formatBytes($directorySize)."/".formatBytes($maxFolderSize); ?> (<?php echo round($directorySize / $maxFolderSize * 100, 2); ?>%)</h3>
|
||||||
|
<h2 class="path"><?php echo $path; ?></h2>
|
||||||
|
<h3><a href="?path=<?php echo dirname($path); ?>">Wróć </a> | <a href="#" onclick="createFolderPrompt()">Utwórz folder</a></h3>
|
||||||
|
<p>
|
||||||
|
<div class="pliki">
|
||||||
|
<?php
|
||||||
|
if (empty($dirList)) { // Wyświetl ładną wiadomość, jeśli lista plików jest pusta
|
||||||
|
echo "Nothing to see here (yet)";
|
||||||
|
} else {
|
||||||
|
foreach ($dirList as $fName) {
|
||||||
|
$uriFname = urlencode($fName);
|
||||||
|
if (is_dir(join_paths($filesDir, $fName))) {
|
||||||
|
// Folder
|
||||||
|
echo "<div class=\"plik folder\"><a href=\"?path=".join_paths($path, $uriFname)."\" class=\"name\"><span class=\"material-symbols-outlined\">folder</span> $fName</a><a href=\"#\" data-path=\"".join_paths($path, $uriFname)."\" class=\"delete\"><span class=\"material-symbols-outlined\">delete</span></a><br></div>"; // Pętla wyświetlająca każdy element z $dirList w formie linku
|
||||||
|
} else {
|
||||||
|
// Plik
|
||||||
|
echo "<div class=\"plik\"><a href=\"file.php?name=".join_paths($path, $uriFname)."\" target=\"_blank\" class=\"name\"><span class=\"material-symbols-outlined\">draft</span> $fName</a><a href=\"#\" data-path=\"".join_paths($path, $uriFname)."\" class=\"delete\"><span class=\"material-symbols-outlined\">delete</span></a><br></div>"; // Pętla wyświetlająca każdy element z $dirList w formie linku
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</div>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const params = new URLSearchParams(window.location.search);
|
||||||
|
|
||||||
|
function createFolderPrompt() {
|
||||||
|
let folderName = prompt("Podaj nazwę nowego folderu");
|
||||||
|
|
||||||
|
if (folderName!==null) {
|
||||||
|
$.ajax({
|
||||||
|
url: "create-folder.php", type: "POST", contentType: 'application/json', data: JSON.stringify({ name: folderName, path: params.get('path') }), success: function () {
|
||||||
|
window.location.reload();
|
||||||
|
},
|
||||||
|
error: function() {
|
||||||
|
window.location.reload();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
setTimeout(() => {
|
||||||
|
lockButtons(false);
|
||||||
|
}, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function upload() {
|
||||||
|
const formData = new FormData();
|
||||||
|
|
||||||
|
formData.append("path", params.get('path'));
|
||||||
|
|
||||||
|
const selection = await window.showOpenFilePicker({multiple: false});
|
||||||
|
if (selection.length > 0) {
|
||||||
|
const file = await selection[0].getFile();
|
||||||
|
formData.append("file", file);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch("upload.php", {
|
||||||
|
method: "POST",
|
||||||
|
body: formData,
|
||||||
|
});
|
||||||
|
window.location.reload();
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function remove(name) {
|
||||||
|
const formData = new FormData();
|
||||||
|
|
||||||
|
formData.append("name", name);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch("remove.php", {
|
||||||
|
method: "POST",
|
||||||
|
body: formData,
|
||||||
|
});
|
||||||
|
window.location.reload();
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function lockButtons(state) {
|
||||||
|
if (state) {
|
||||||
|
$(".pliki").css({
|
||||||
|
opacity: 0.25,
|
||||||
|
"pointer-events": "none",
|
||||||
|
});
|
||||||
|
|
||||||
|
$("a").css("pointer-events", "none");
|
||||||
|
} else {
|
||||||
|
$(".pliki").css({
|
||||||
|
opacity: 1,
|
||||||
|
"pointer-events": "all",
|
||||||
|
});
|
||||||
|
|
||||||
|
$("a").css("pointer-events", "all");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
$("a").on("click", function () {
|
||||||
|
lockButtons(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#uploadButton").on("click", upload);
|
||||||
|
|
||||||
|
$(".delete").on("click", async function () {
|
||||||
|
await remove($(this).data("path"));
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
85
public/style.css
Normal file
85
public/style.css
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
body {
|
||||||
|
font-family: 'Quicksand', sans-serif;
|
||||||
|
background: rgb(242, 242, 242);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pobieranie {
|
||||||
|
padding: 40px;
|
||||||
|
font-family: 'Quicksand', sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
font-family: 'Quicksand', sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pliki {
|
||||||
|
line-height: 25px;
|
||||||
|
width: 500px;
|
||||||
|
max-width: 100vw;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
transition: opacity 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
font-family: 'Quicksand', sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pliki a {
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pliki .plik {
|
||||||
|
display: flex;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.plik .name, .plik .delete {
|
||||||
|
padding: 7px 12px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
transition: all 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pliki .plik .name {
|
||||||
|
background: white;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-start;
|
||||||
|
gap: 5px;
|
||||||
|
flex: 1;
|
||||||
|
border-top-left-radius: 20px;
|
||||||
|
border-bottom-left-radius: 20px;
|
||||||
|
border-right: rgb(208, 208, 208) solid 1px;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pliki .plik .name:hover {
|
||||||
|
background: rgb(72, 91, 255);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pliki .plik .delete {
|
||||||
|
background: white;
|
||||||
|
color: red;
|
||||||
|
border-top-right-radius: 20px;
|
||||||
|
border-bottom-right-radius: 20px;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pliki .plik .delete:hover {
|
||||||
|
background: red;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.path {
|
||||||
|
border-radius: 10px;
|
||||||
|
font-family: 'Fira Code', monospace;
|
||||||
|
padding: 3px 5px;
|
||||||
|
font-size: 17px;
|
||||||
|
border: black 1px solid;
|
||||||
|
}
|
30
public/upload.php
Normal file
30
public/upload.php
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
function join_paths() {
|
||||||
|
$paths = array();
|
||||||
|
|
||||||
|
foreach (func_get_args() as $arg) {
|
||||||
|
if ($arg !== '') { $paths[] = $arg; }
|
||||||
|
}
|
||||||
|
|
||||||
|
return preg_replace('#/+#','/',join('/', $paths));
|
||||||
|
}
|
||||||
|
|
||||||
|
$filesDir = "../../files/"; // Musi kończyć się slashem!
|
||||||
|
$redirectRoute = "/pen"; // Adres względny do któego ma przekierować, jeżeli masz index.php w public/upload to powinno być to /upload
|
||||||
|
|
||||||
|
if (isset($_POST["path"])) { // Jeżeli to faktycznie jest formularz i zawiera ścieżke do kopiowania pliku
|
||||||
|
$targetFile = join_paths($filesDir, $_POST["path"], basename($_FILES["file"]["name"]));
|
||||||
|
|
||||||
|
if (!file_exists($targetFile)) {
|
||||||
|
if (move_uploaded_file($_FILES["file"]["tmp_name"], $targetFile)) { // Skopiuj zuploadowany plik do poprawnego miejsca na serwerze
|
||||||
|
http_response_code(200);
|
||||||
|
} else { // W razie gdyby coś nie wyszło po stronie serwera podczas kopiowania pliku
|
||||||
|
http_response_code(500);
|
||||||
|
echo "Sorry, there was an error uploading your file.";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
http_response_code(409);
|
||||||
|
echo "409 - Resource already exists (file already exists)";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
Loading…
Reference in New Issue
Block a user