mirror of https://github.com/itflow-org/itflow
Try to fix uploads
This commit is contained in:
parent
986f688468
commit
c77e1be1c3
114
setup/index.php
114
setup/index.php
|
|
@ -310,7 +310,7 @@ if (isset($_POST['restore'])) {
|
|||
|
||||
$uploadDir = $appRoot . "/uploads";
|
||||
|
||||
// Extract inner uploads.zip to staging (with validation & scan report)
|
||||
// 6.a Extract inner uploads.zip to staging (with validation & scan report)
|
||||
$staging = $appRoot . "/uploads_restoring_" . bin2hex(random_bytes(4));
|
||||
if (!mkdir($staging, 0700, true)) {
|
||||
deleteDir($tempDir);
|
||||
|
|
@ -348,90 +348,65 @@ if (isset($_POST['restore'])) {
|
|||
exit;
|
||||
}
|
||||
|
||||
// If inner zip has a single "uploads/" folder, promote its contents
|
||||
$roots = [];
|
||||
// 6.b Determine the actual content root inside staging
|
||||
// If the inner archive’s top-level is exactly "uploads/", use that; otherwise use staging itself.
|
||||
$contentRoot = $staging;
|
||||
$topEntries = [];
|
||||
if ($dh = opendir($staging)) {
|
||||
while (($e = readdir($dh)) !== false) {
|
||||
if ($e === '.' || $e === '..') continue;
|
||||
$roots[] = $e;
|
||||
$topEntries[] = $e;
|
||||
}
|
||||
closedir($dh);
|
||||
}
|
||||
sort($roots);
|
||||
if (count($roots) === 1) {
|
||||
$candidate = $staging . DIRECTORY_SEPARATOR . $roots[0];
|
||||
if (is_dir($candidate)) {
|
||||
$promoted = $staging . "_promoted";
|
||||
if (!@rename($candidate, $promoted)) {
|
||||
// fallback to copy
|
||||
$rit = new RecursiveIteratorIterator(
|
||||
new RecursiveDirectoryIterator($candidate, FilesystemIterator::SKIP_DOTS),
|
||||
RecursiveIteratorIterator::SELF_FIRST
|
||||
);
|
||||
if (!mkdir($promoted, 0700, true)) {
|
||||
deleteDir($staging);
|
||||
deleteDir($tempDir);
|
||||
die("Failed to create promoted staging directory.");
|
||||
}
|
||||
foreach ($rit as $it) {
|
||||
$rel = substr($it->getPathname(), strlen($candidate) + 1);
|
||||
$dst = $promoted . DIRECTORY_SEPARATOR . $rel;
|
||||
if ($it->isDir()) {
|
||||
if (!is_dir($dst) && !mkdir($dst, 0700, true)) {
|
||||
deleteDir($staging);
|
||||
deleteDir($tempDir);
|
||||
die("Failed to create $dst");
|
||||
}
|
||||
} else {
|
||||
$pdir = dirname($dst);
|
||||
if (!is_dir($pdir) && !mkdir($pdir, 0700, true)) {
|
||||
deleteDir($staging);
|
||||
deleteDir($tempDir);
|
||||
die("Failed to create $pdir");
|
||||
}
|
||||
if (!copy($it->getPathname(), $dst)) {
|
||||
deleteDir($staging);
|
||||
deleteDir($tempDir);
|
||||
die("Failed to copy $rel into promoted staging");
|
||||
}
|
||||
@chmod($dst, 0640);
|
||||
}
|
||||
}
|
||||
}
|
||||
deleteDir($staging);
|
||||
$staging = isset($promoted) ? $promoted : $staging;
|
||||
sort($topEntries);
|
||||
|
||||
if (count($topEntries) === 1) {
|
||||
$candidate = $staging . DIRECTORY_SEPARATOR . $topEntries[0];
|
||||
if (is_dir($candidate) && strtolower($topEntries[0]) === 'uploads') {
|
||||
// Use the "uploads" directory directly without moving/deleting staging yet
|
||||
$contentRoot = $candidate;
|
||||
}
|
||||
}
|
||||
|
||||
// Sanity: staging must contain files
|
||||
// 6.c Sanity check: content root must have files
|
||||
$hasFiles = false;
|
||||
$it = new RecursiveIteratorIterator(
|
||||
new RecursiveDirectoryIterator($staging, FilesystemIterator::SKIP_DOTS)
|
||||
$ritCheck = new RecursiveIteratorIterator(
|
||||
new RecursiveDirectoryIterator($contentRoot, FilesystemIterator::SKIP_DOTS)
|
||||
);
|
||||
foreach ($it as $f) { if ($f->isFile()) { $hasFiles = true; break; } }
|
||||
foreach ($ritCheck as $f) {
|
||||
if ($f->isFile()) { $hasFiles = true; break; }
|
||||
}
|
||||
if (!$hasFiles) {
|
||||
deleteDir($staging);
|
||||
deleteDir($tempDir);
|
||||
die("Uploads restore failed: staging is empty (inner uploads.zip may be malformed or fully blocked).");
|
||||
die("Uploads restore failed: extracted content is empty (inner uploads.zip may be malformed or fully blocked).");
|
||||
}
|
||||
|
||||
// --- DELETE existing /uploads first, then REPLACE with staging ---
|
||||
// 6.d Remove current /uploads and replace with restored content
|
||||
if (is_dir($uploadDir)) {
|
||||
deleteDir($uploadDir, $appRoot); // guarded delete (under app root)
|
||||
deleteDir($uploadDir, $appRoot); // guarded delete under app root
|
||||
}
|
||||
if (!@rename($staging, $uploadDir)) {
|
||||
// fallback: copy
|
||||
|
||||
// If contentRoot IS the staging root, try a simple rename
|
||||
$renameSource = ($contentRoot === $staging) ? $staging : $contentRoot;
|
||||
$renameOk = @rename($renameSource, $uploadDir);
|
||||
|
||||
// If we used the child "uploads" dir as contentRoot, staging still exists with an empty top; clean it later
|
||||
if (!$renameOk) {
|
||||
// Fallback: copy tree
|
||||
if (!mkdir($uploadDir, 0750, true)) {
|
||||
deleteDir($staging);
|
||||
deleteDir($tempDir);
|
||||
die("Failed to create uploads directory for placement.");
|
||||
}
|
||||
|
||||
$rit = new RecursiveIteratorIterator(
|
||||
new RecursiveDirectoryIterator($staging, FilesystemIterator::SKIP_DOTS),
|
||||
new RecursiveDirectoryIterator($contentRoot, FilesystemIterator::SKIP_DOTS),
|
||||
RecursiveIteratorIterator::SELF_FIRST
|
||||
);
|
||||
foreach ($rit as $it) {
|
||||
$rel = substr($it->getPathname(), strlen($staging) + 1);
|
||||
$rel = substr($it->getPathname(), strlen($contentRoot) + 1);
|
||||
$dst = $uploadDir . DIRECTORY_SEPARATOR . $rel;
|
||||
if ($it->isDir()) {
|
||||
if (!is_dir($dst) && !mkdir($dst, 0750, true)) {
|
||||
|
|
@ -457,17 +432,26 @@ if (isset($_POST['restore'])) {
|
|||
@chmod($dst, 0640);
|
||||
}
|
||||
}
|
||||
// If we copied only the inner "uploads" folder, we still need to clean the top-level staging
|
||||
deleteDir($staging);
|
||||
} else {
|
||||
// rename succeeded; if we renamed the child "uploads", the original staging still exists – clean it
|
||||
if ($contentRoot !== $staging) {
|
||||
deleteDir($staging);
|
||||
}
|
||||
}
|
||||
|
||||
// Verify uploads has files
|
||||
$okFiles = false;
|
||||
$it2 = new RecursiveIteratorIterator(
|
||||
new RecursiveDirectoryIterator($uploadDir, FilesystemIterator::SKIP_DOTS)
|
||||
// 6.e Verify uploads now has files and report counts
|
||||
$fileCount = 0; $dirCount = 0;
|
||||
$ritVerify = new RecursiveIteratorIterator(
|
||||
new RecursiveDirectoryIterator($uploadDir, FilesystemIterator::SKIP_DOTS),
|
||||
RecursiveIteratorIterator::SELF_FIRST
|
||||
);
|
||||
foreach ($it2 as $f) { if ($f->isFile()) { $okFiles = true; break; } }
|
||||
if (!$okFiles) {
|
||||
deleteDir($uploadDir);
|
||||
foreach ($ritVerify as $it) {
|
||||
if ($it->isDir()) $dirCount++;
|
||||
else $fileCount++;
|
||||
}
|
||||
if ($fileCount === 0) {
|
||||
deleteDir($tempDir);
|
||||
die("Uploads replace failed: resulting directory is empty.");
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue