]> BookStack Code Mirror - system-cli/blob - src/Services/Directories.php
Improved symlink support for backup/restore
[system-cli] / src / Services / Directories.php
1 <?php declare(strict_types=1);
2
3 namespace Cli\Services;
4 use FilesystemIterator;
5 use RecursiveDirectoryIterator;
6 use RecursiveIteratorIterator;
7
8 class Directories
9 {
10
11     public static function move(string $src, string $target): void
12     {
13         static::copy($src, $target);
14         static::delete($src);
15     }
16
17     public static function copy(string $src, string $target): void
18     {
19         mkdir($target);
20
21         /** @var RecursiveDirectoryIterator $files */
22         $files = new RecursiveIteratorIterator(
23             new RecursiveDirectoryIterator($src, FilesystemIterator::SKIP_DOTS | FilesystemIterator::FOLLOW_SYMLINKS),
24             RecursiveIteratorIterator::SELF_FIRST
25         );
26
27         /** @var \SplFileInfo $fileinfo */
28         foreach ($files as $fileinfo) {
29             $srcPath = $fileinfo->getRealPath();
30             $subPath = $files->getSubPathName();
31             $destPath = Paths::join($target, $subPath);
32             if ($fileinfo->isDir()) {
33                 $result = mkdir($destPath);
34             } else {
35                 $result = copy($srcPath, $destPath);
36             }
37
38             if ($result === false) {
39                 throw new \Exception("Failed to copy file or directory from {$srcPath} to {$destPath}");
40             }
41         }
42     }
43
44     public static function delete(string $dir): void
45     {
46         $files = new RecursiveIteratorIterator(
47             new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS | FilesystemIterator::FOLLOW_SYMLINKS),
48             RecursiveIteratorIterator::CHILD_FIRST
49         );
50
51         foreach ($files as $fileinfo) {
52             $path = $fileinfo->getRealPath();
53             if ($fileinfo->isDir()) {
54                 $result = rmdir($path);
55             } else {
56                 $result = unlink($path);
57             }
58
59             if ($result === false) {
60                 throw new \Exception("Failed to delete file or directory at {$path}");
61             }
62         }
63
64         rmdir($dir);
65     }
66 }