Completed
Push — dev ( fdde29...9392d7 )
by James Ekow Abaka
01:43
created

Directory::getPath()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

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

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
168
     */
169 5
    public function getFiles() : FileCollection
170
    {
171 5
        Filesystem::checkExists($this->path);
172 5
        Filesystem::checkReadable($this->path);
173 5
        $contents = [];
174
175 5
        $files = scandir($this->path);
176 5
        foreach ($files as $file) {
177 5
            if($file != '.' && $file != '..') {
178 5
                $contents[] = "$this->path/$file";
179
            }
180
        }
181 5
        return new FileCollection($contents);
182
    }
183
184 3
    public function __toString()
185
    {
186 3
        return $this->path;
187
    }
188
}
189