first commit
This commit is contained in:
219
_backup.php
Normal file
219
_backup.php
Normal file
@@ -0,0 +1,219 @@
|
||||
<?php
|
||||
|
||||
define('TMP_FILE', __DIR__ . '/backup_tmp.json');
|
||||
define('FILES_PER_STEP', 50);
|
||||
|
||||
// Sprawdzenie czy możemy użyć shell_exec + zip/tar
|
||||
function canUseShell() {
|
||||
return function_exists('shell_exec') && !in_array('shell_exec', explode(',', ini_get('disable_functions')));
|
||||
}
|
||||
|
||||
function commandAvailable($cmd) {
|
||||
$check = shell_exec("command -v $cmd 2>/dev/null");
|
||||
return !empty($check);
|
||||
}
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
header('Content-Type: application/json');
|
||||
|
||||
$action = $_POST['action'] ?? '';
|
||||
|
||||
if ($action === 'init') {
|
||||
$filename = 'backup_' . date("Ymd_His");
|
||||
$response = ['success' => false];
|
||||
|
||||
if (canUseShell()) {
|
||||
if (commandAvailable('tar')) {
|
||||
$tarName = "$filename.tar";
|
||||
shell_exec("tar -cf $tarName .");
|
||||
if (file_exists($tarName)) {
|
||||
$response = [
|
||||
'success' => true,
|
||||
'method' => 'shell_tar',
|
||||
'file' => $tarName
|
||||
];
|
||||
echo json_encode($response);
|
||||
exit;
|
||||
}
|
||||
} elseif (commandAvailable('zip')) {
|
||||
$zipName = "$filename.zip";
|
||||
shell_exec("zip -r $zipName . -x '*backup_*.zip' '*.git*' 'node_modules/*' 'vendor/*'");
|
||||
if (file_exists($zipName)) {
|
||||
$response = [
|
||||
'success' => true,
|
||||
'method' => 'shell_zip',
|
||||
'file' => $zipName
|
||||
];
|
||||
echo json_encode($response);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Jeśli nie ma shell_exec lub zip/tar — fallback na ZipArchive krok po kroku
|
||||
$zipName = "$filename.zip";
|
||||
$zipPath = __DIR__ . '/' . $zipName;
|
||||
|
||||
$iterator = new RecursiveIteratorIterator(
|
||||
new RecursiveDirectoryIterator(__DIR__, RecursiveDirectoryIterator::SKIP_DOTS)
|
||||
);
|
||||
|
||||
$files = [];
|
||||
foreach ($iterator as $file) {
|
||||
$path = $file->getPathname();
|
||||
if (strpos($path, $zipName) !== false) continue;
|
||||
$files[] = $path;
|
||||
}
|
||||
|
||||
$zip = new ZipArchive();
|
||||
if ($zip->open($zipPath, ZipArchive::CREATE | ZipArchive::OVERWRITE) !== true) {
|
||||
echo json_encode(['success' => false, 'message' => 'Nie można utworzyć ZIP']);
|
||||
exit;
|
||||
}
|
||||
$zip->addEmptyDir('__INIT__');
|
||||
$zip->close();
|
||||
|
||||
file_put_contents(TMP_FILE, json_encode([
|
||||
'method' => 'php_zip',
|
||||
'files' => $files,
|
||||
'index' => 0,
|
||||
'zipfile' => $zipPath,
|
||||
'zipname' => $zipName
|
||||
]));
|
||||
|
||||
echo json_encode([
|
||||
'success' => true,
|
||||
'method' => 'php_zip'
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($action === 'step') {
|
||||
if (!file_exists(TMP_FILE)) {
|
||||
echo json_encode(['success' => false, 'message' => 'Brak danych tymczasowych']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$data = json_decode(file_get_contents(TMP_FILE), true);
|
||||
$files = $data['files'];
|
||||
$index = $data['index'];
|
||||
$zipfile = $data['zipfile'];
|
||||
$zipname = $data['zipname'];
|
||||
|
||||
$zip = new ZipArchive();
|
||||
if ($zip->open($zipfile) !== true) {
|
||||
echo json_encode(['success' => false, 'message' => 'Nie można otworzyć ZIP']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$end = min($index + FILES_PER_STEP, count($files));
|
||||
for ($i = $index; $i < $end; $i++) {
|
||||
$filePath = $files[$i];
|
||||
if (is_file($filePath)) {
|
||||
$localname = substr($filePath, strlen(__DIR__) + 1);
|
||||
$zip->addFile($filePath, $localname);
|
||||
}
|
||||
}
|
||||
|
||||
$zip->close();
|
||||
|
||||
$data['index'] = $end;
|
||||
file_put_contents(TMP_FILE, json_encode($data));
|
||||
|
||||
$progress = $end / count($files);
|
||||
|
||||
echo json_encode([
|
||||
'success' => true,
|
||||
'method' => 'php_zip',
|
||||
'progress' => round($progress * 100, 2),
|
||||
'done' => $end >= count($files),
|
||||
'zipfile' => $zipname
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="pl">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Backup dynamiczny</title>
|
||||
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
||||
<style>
|
||||
#progress-bar {
|
||||
width: 100%;
|
||||
background-color: #eee;
|
||||
border: 1px solid #ccc;
|
||||
margin-top: 10px;
|
||||
}
|
||||
#progress-bar-inner {
|
||||
height: 20px;
|
||||
width: 0;
|
||||
background-color: #4caf50;
|
||||
text-align: center;
|
||||
color: white;
|
||||
line-height: 20px;
|
||||
transition: width 0.3s ease;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h2>Automatyczny backup plików</h2>
|
||||
<button id="start-backup">Rozpocznij</button>
|
||||
|
||||
<div id="progress-bar" style="display:none;">
|
||||
<div id="progress-bar-inner">0.00%</div>
|
||||
</div>
|
||||
|
||||
<div id="status"></div>
|
||||
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
let method = '';
|
||||
let zipFile = '';
|
||||
|
||||
$("#start-backup").click(function(){
|
||||
$("#status").text("Inicjalizowanie...");
|
||||
$("#progress-bar").show();
|
||||
$("#progress-bar-inner").css("width", "0%").text("0.00%");
|
||||
|
||||
$.post("", { action: "init" }, function(res){
|
||||
if (!res.success) {
|
||||
$("#status").text("Błąd: " + res.message);
|
||||
return;
|
||||
}
|
||||
|
||||
method = res.method;
|
||||
|
||||
if (method === 'shell_tar' || method === 'shell_zip') {
|
||||
$("#progress-bar-inner").css("width", "100%").text("100%");
|
||||
$("#status").html("✅ Gotowe! <a href='" + res.file + "' download>Pobierz</a>");
|
||||
} else if (method === 'php_zip') {
|
||||
doStep();
|
||||
}
|
||||
}, "json");
|
||||
});
|
||||
|
||||
function doStep() {
|
||||
$.post("", { action: "step" }, function(res){
|
||||
if (res.success && res.method === 'php_zip') {
|
||||
let percent = parseFloat(res.progress).toFixed(2);
|
||||
$("#progress-bar-inner").css("width", percent + "%").text(percent + "%");
|
||||
|
||||
if (res.done) {
|
||||
$("#status").html("✅ Backup gotowy! <a href='" + res.zipfile + "' download>Pobierz ZIP</a>");
|
||||
} else {
|
||||
setTimeout(doStep, 300);
|
||||
}
|
||||
} else {
|
||||
$("#status").text("Błąd: " + res.message);
|
||||
}
|
||||
}, "json");
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user