Skip to content
This repository was archived by the owner on Jul 26, 2024. It is now read-only.

Commit fa20d77

Browse files
committed
Addressed further symlink issues
Specifically updating recursive deletion/copy handling to ignore symlink directories. This is so symlinks remain so that content is stored in the actual desired symlinked locations upon restore, rather than new non-sym-link equivilents (Which could loose data in scenarios like within docker containers where data is symlinked to volume locations). Tested on a dev linuxserver docker environment, which specific checking of file handling before/after restore of backup.
1 parent 0562ac3 commit fa20d77

File tree

1 file changed

+27
-7
lines changed

1 file changed

+27
-7
lines changed

src/Services/Directories.php

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
use FilesystemIterator;
55
use RecursiveDirectoryIterator;
66
use RecursiveIteratorIterator;
7+
use SplFileInfo;
78

89
class Directories
910
{
@@ -16,22 +17,26 @@ public static function move(string $src, string $target): void
1617

1718
public static function copy(string $src, string $target): void
1819
{
19-
mkdir($target);
20+
if (!file_exists($target)) {
21+
mkdir($target);
22+
}
2023

2124
/** @var RecursiveDirectoryIterator $files */
2225
$files = new RecursiveIteratorIterator(
2326
new RecursiveDirectoryIterator($src, FilesystemIterator::SKIP_DOTS | FilesystemIterator::FOLLOW_SYMLINKS),
2427
RecursiveIteratorIterator::SELF_FIRST
2528
);
2629

27-
/** @var \SplFileInfo $fileinfo */
30+
/** @var SplFileInfo $fileinfo */
2831
foreach ($files as $fileinfo) {
2932
$srcPath = $fileinfo->getRealPath();
3033
$subPath = $files->getSubPathName();
3134
$destPath = Paths::join($target, $subPath);
32-
if ($fileinfo->isDir()) {
35+
$result = true;
36+
if ($fileinfo->isDir() && !file_exists($destPath)) {
37+
echo $destPath . "\n";
3338
$result = mkdir($destPath);
34-
} else {
39+
} else if ($fileinfo->isFile()) {
3540
$result = copy($srcPath, $destPath);
3641
}
3742

@@ -41,18 +46,31 @@ public static function copy(string $src, string $target): void
4146
}
4247
}
4348

49+
/**
50+
* Delete the contents of the given directory.
51+
* Will not delete symlinked folders to ensure that symlinks remain consistent,
52+
* but will aim to delete contents of symlinked folders.
53+
*/
4454
public static function delete(string $dir): void
4555
{
4656
$files = new RecursiveIteratorIterator(
4757
new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS | FilesystemIterator::FOLLOW_SYMLINKS),
4858
RecursiveIteratorIterator::CHILD_FIRST
4959
);
5060

61+
$links = '::';
62+
63+
/** @var SplFileInfo $fileinfo */
5164
foreach ($files as $fileinfo) {
5265
$path = $fileinfo->getRealPath();
66+
$result = true;
5367
if ($fileinfo->isDir()) {
54-
$result = rmdir($path);
55-
} else {
68+
if ($fileinfo->isLink()) {
69+
$links .= $fileinfo->getPath() . '::';
70+
} else if (!str_contains($links, '::' . $path)) {
71+
$result = rmdir($path);
72+
}
73+
} else if ($fileinfo->isFile()) {
5674
$result = unlink($path);
5775
}
5876

@@ -61,6 +79,8 @@ public static function delete(string $dir): void
6179
}
6280
}
6381

64-
rmdir($dir);
82+
if ($links === '::') {
83+
rmdir($dir);
84+
}
6585
}
6686
}

0 commit comments

Comments
 (0)