Completed
Pull Request — master (#9)
by James Ekow Abaka
01:16
created

Directory::moveTo()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 5
cts 5
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 1
1
<?php
2
3
namespace ntentan\utils\filesystem;
4
5
use ntentan\utils\exceptions\FileAlreadyExistsException;
6
use ntentan\utils\exceptions\FileNotFoundException;
7
use ntentan\utils\exceptions\FileNotReadableException;
8
use ntentan\utils\exceptions\FileNotWriteableException;
9
use ntentan\utils\Filesystem;
10
use ntentan\utils\exceptions\FilesystemException;
11
12
/**
13
 * A directory on the filesystem.
14
 *
15
 * @package ntentan\utils\filesystem
16
 */
17
class Directory implements FileInterface
18
{
19
20
    /**
21
     * Full path to the directory.
22
     *
23
     * @var string
24
     */
25
    private $path;
26
27
    /**
28
     * Create a new instance with a path.
29
     *
30
     * @param string $path Optional path pointed to by new instance. Path does not have to exist.
31
     */
32 6
    public function __construct(string $path = null)
33
    {
34 6
        $this->path = $path;
35 6
    }
36
37
    /**
38
     * Used to perform copies and moves.
39
     *
40
     * @param string $operation
41
     * @param string $destination
42
     * @throws FileNotFoundException
43
     * @throws FilesystemException
44
     * @throws FileAlreadyExistsException
45
     * @throws FileNotReadableException
46
     * @throws FileNotWriteableException
47
     */
48 2
    private function directoryOperation(string $operation, string $destination):void
49
    {
50 2
        foreach ($this->getFiles(true) as $file) {
51 2
            $fileTarget = $destination . DIRECTORY_SEPARATOR . substr($file, strlen($this->path));
52 2
            if(is_dir($file)) {
53 2
                continue;
54
            }
55
            try{
56 2
                Filesystem::checkExists(dirname($fileTarget));
57 2
            } catch (FileNotFoundException $exception) {
58 2
                Filesystem::directory(dirname($fileTarget))->create(true);
59
            }
60
61 2
            $file->$operation($fileTarget);
62
        }
63 2
    }
64
65
    /**
66
     * Recursively copies directory and its contents to destination.
67
     *
68
     * @param string $destination
69
     * @throws FileNotFoundException
70
     * @throws FilesystemException
71
     * @throws FileAlreadyExistsException
72
     * @throws FileNotReadableException
73
     * @throws FileNotWriteableException
74
     */
75 1
    public function copyTo(string $destination): void
76
    {
77 1
        $this->directoryOperation('copyTo', $destination);
78 1
    }
79
80
    /**
81
     * Recursively get the size of all contents in the directory.
82
     *
83
     * @return integer
84
     * @throws FileNotFoundException
85
     * @throws FilesystemException
86
     * @throws FileNotReadableException
87
     */
88 1
    public function getSize() : int
89
    {
90 1
        return $this->getFiles()->getSize();
91
    }
92
93
    /**
94
     * Recursively move a directory and its contents to another location.
95
     *
96
     * @param string $destination
97
     * @throws FileNotFoundException
98
     * @throws FilesystemException
99
     * @throws FileAlreadyExistsException
100
     * @throws FileNotReadableException
101
     * @throws FileNotWriteableException
102
     */
103 1
    public function moveTo(string $destination) : void
104
    {
105 1
        $this->directoryOperation('moveTo', $destination);
106 1
        $this->delete();
107 1
        $this->path = $destination;
108 1
    }
109
110
    /**
111
     * Create the directory pointed to by path.
112
     *
113
     * @param int $permissions
114
     * @throws FileAlreadyExistsException
115
     * @throws FileNotWriteableException
116
     */
117 2
    public function create($recursive=false, $permissions = 0755)
118
    {
119 2
        Filesystem::checkNotExists($this->path);
120 2
        $parent = $this->path;
121 2
        if($recursive) {
122 2
            $segments = explode(DIRECTORY_SEPARATOR, $this->path);
123 2
            $parent = "";
124 2
            foreach($segments as $segment) {
125 2
                $parent .= $segment . DIRECTORY_SEPARATOR;
126 2
                if(!is_dir($parent)) {
127 2
                    break;
128
                }
129
            }
130
        }
131 2
        $parent = dirname($parent);
132 2
        Filesystem::checkWritable($parent == "" ? '.' : $parent);
133 2
        mkdir($this->path, $permissions, true);
134 2
    }
135
136
    /**
137
     * Recursively delete the directory and all its contents.
138
     *
139
     * @throws FileNotFoundException
140
     * @throws FilesystemException
141
     * @throws FileNotReadableException
142
     */
143 2
    public function delete() : void
144
    {
145 2
        $this->getFiles()->delete();
146 2
        rmdir($this->path);
147 2
    }
148
149
    /**
150
     * Get the path of the directory.
151
     *
152
     * @return string
153
     */
154 1
    public function getPath() : string
155
    {
156 1
        return $this->path;
157
    }
158
159
    /**
160
     * Get the files in the directory.
161
     *
162
     * @throws FilesystemException
163
     * @throws FileNotFoundException
164
     * @throws FileNotReadableException
165
     * @return FileCollection | array<string>
166
     */
167 5
    public function getFiles($recursive=false, $returnStrings=false)
168
    {
169 5
        Filesystem::checkExists($this->path);
170 5
        Filesystem::checkReadable($this->path);
171 5
        $contents = [];
172
173 5
        $files = scandir($this->path);
174 5
        foreach ($files as $file) {
175 5
            if($file == '.' || $file == '..') continue;
176 5
            $path = "$this->path/$file";
177 5
            if(is_dir($path) && $recursive) {
178 2
                $contents = array_merge($contents, Filesystem::directory($path)->getFiles(true, true));
179
            }
180 5
            $contents[] = $path;
181
        }
182 5
        return $returnStrings ? $contents : new FileCollection($contents);
183
    }
184
185 3
    public function __toString()
186
    {
187 3
        return $this->path;
188
    }
189
}
190