Completed
Push — master ( 151f35...e36260 )
by James Ekow Abaka
23s queued 10s
created

Directory::getFiles()   B

Complexity

Conditions 7
Paths 8

Size

Total Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 7

Importance

Changes 0
Metric Value
dl 0
loc 17
ccs 12
cts 12
cp 1
rs 8.8333
c 0
b 0
f 0
cc 7
nc 8
nop 2
crap 7
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
        if($recursive) {
121 2
            $parsedPath = parse_url($this->path);
122 2
            $segments = explode(DIRECTORY_SEPARATOR, $parsedPath['path']);
123 2
            $scheme = $parsedPath['scheme'] ?? '';
124 2
            $host = $parsedPath['host'] ?? '';
125 2
            array_unshift($segments, $scheme . ':' . DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR . $host);
126 2
            $accumulator = "";
127 2
            $parent = "";
128 2
            foreach($segments as $segment) {
129 2
                $accumulator .= $segment . DIRECTORY_SEPARATOR;
130 2
                if(is_dir($accumulator)) {
131 2
                    $parent = $accumulator;
132
                } else {
133 2
                    break;
134
                }
135
            }
136
        } else {
137
            $parent = dirname($this->path);
138
        }
139 2
        Filesystem::checkWritable($parent == "" ? "." : $parent);
140 2
        mkdir($this->path, $permissions, true);
141 2
    }
142
143
    /**
144
     * Recursively delete the directory and all its contents.
145
     *
146
     * @throws FileNotFoundException
147
     * @throws FilesystemException
148
     * @throws FileNotReadableException
149
     */
150 2
    public function delete() : void
151
    {
152 2
        $this->getFiles()->delete();
153 2
        rmdir($this->path);
154 2
    }
155
156
    /**
157
     * Get the path of the directory.
158
     *
159
     * @return string
160
     */
161 1
    public function getPath() : string
162
    {
163 1
        return $this->path;
164
    }
165
166
    /**
167
     * Get the files in the directory.
168
     *
169
     * @throws FilesystemException
170
     * @throws FileNotFoundException
171
     * @throws FileNotReadableException
172
     * @return FileCollection | array<string>
173
     */
174 5
    public function getFiles($recursive=false, $returnStrings=false)
175
    {
176 5
        Filesystem::checkExists($this->path);
177 5
        Filesystem::checkReadable($this->path);
178 5
        $contents = [];
179
180 5
        $files = scandir($this->path);
181 5
        foreach ($files as $file) {
182 5
            if($file == '.' || $file == '..') continue;
183 5
            $path = "$this->path/$file";
184 5
            if(is_dir($path) && $recursive) {
185 2
                $contents = array_merge($contents, Filesystem::directory($path)->getFiles(true, true));
186
            }
187 5
            $contents[] = $path;
188
        }
189 5
        return $returnStrings ? $contents : new FileCollection($contents);
190
    }
191
192 3
    public function __toString()
193
    {
194 3
        return $this->path;
195
    }
196
}
197