Completed
Push — dev ( 03b82e...64e4df )
by James Ekow Abaka
03:28
created

Directory::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 3
cts 3
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\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
            Filesystem::checkExists($destination);
49
            $destination = $destination . DIRECTORY_SEPARATOR . basename($this);
50 2
        } catch (FileNotFoundException $e) {
51 2
            Filesystem::directory($destination)->create(true);
52
        }
53
54 2
        foreach ($this->getFiles() as $file) {
55 2
            $file->$operation($destination . DIRECTORY_SEPARATOR . basename($file));
56
        }
57 2
    }
58
59
    /**
60
     * Recursively copies directory and its contents to destination.
61
     *
62
     * @param string $destination
63
     * @throws FileNotFoundException
64
     * @throws FilesystemException
65
     * @throws \ntentan\utils\exceptions\FileAlreadyExistsException
66
     * @throws \ntentan\utils\exceptions\FileNotReadableException
67
     * @throws \ntentan\utils\exceptions\FileNotWriteableException
68
     */
69 1
    public function copyTo(string $destination): void
70
    {
71 1
        $this->directoryOperation('copyTo', $destination);
72 1
    }
73
74
    /**
75
     * Recursively get the size of all contents in the directory.
76
     *
77
     * @return integer
78
     * @throws FileNotFoundException
79
     * @throws FilesystemException
80
     * @throws \ntentan\utils\exceptions\FileNotReadableException
81
     */
82 1
    public function getSize() : int
83
    {
84 1
        return $this->getFiles()->getSize();
85
    }
86
87
    /**
88
     * Recursively move a directory and its contents to another location.
89
     *
90
     * @param string $destination
91
     * @throws FileNotFoundException
92
     * @throws FilesystemException
93
     * @throws \ntentan\utils\exceptions\FileAlreadyExistsException
94
     * @throws \ntentan\utils\exceptions\FileNotReadableException
95
     * @throws \ntentan\utils\exceptions\FileNotWriteableException
96
     */
97 1
    public function moveTo(string $destination) : void
98
    {
99 1
        $this->directoryOperation('moveTo', $destination);
100 1
        $this->delete();
101 1
        $this->path = $destination;
102 1
    }
103
104
    /**
105
     * Create the directory pointed to by path.
106
     *
107
     * @param int $permissions
108
     * @throws \ntentan\utils\exceptions\FileAlreadyExistsException
109
     * @throws \ntentan\utils\exceptions\FileNotWriteableException
110
     */
111 2
    public function create($recursive=false, $permissions = 0755)
112
    {
113 2
        Filesystem::checkNotExists($this->path);
114 2
        if($recursive) {
115 2
            $parsedPath = parse_url($this->path);
116 2
            $segments = explode(DIRECTORY_SEPARATOR, $parsedPath['path']);
117 2
            array_unshift($segments, $parsedPath['scheme'] . ':' . DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR . $parsedPath['host']);
118 2
            $accumulator = "";
119 2
            $parent = "";
120 2
            foreach($segments as $segment) {
121 2
                $accumulator .= $segment . DIRECTORY_SEPARATOR;
122 2
                if(is_dir($accumulator)) {
123 2
                    $parent = $accumulator;
124
                } else {
125 2
                    break;
126
                }
127
            }
128
        } else {
129
            $parent = dirname($this->path);
130
        }
131 2
        Filesystem::checkWritable($parent);
132 2
        mkdir($this->path, $permissions, true);
133 2
    }
134
135
    /**
136
     * Recursively delete the directory and all its contents.
137
     *
138
     * @throws FileNotFoundException
139
     * @throws FilesystemException
140
     * @throws \ntentan\utils\exceptions\FileNotReadableException
141
     */
142 2
    public function delete() : void
143
    {
144 2
        $this->getFiles()->delete();
145 2
        rmdir($this->path);
146 2
    }
147
148
    /**
149
     * Get the path of the directory.
150
     *
151
     * @return string
152
     */
153 1
    public function getPath() : string
154
    {
155 1
        return $this->path;
156
    }
157
158
    /**
159
     * Get the files in the directory.
160
     *
161
     * @throws FilesystemException
162
     * @throws \ntentan\utils\exceptions\FileNotFoundException
163
     * @throws \ntentan\utils\exceptions\FileNotReadableException
164
     * @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...
165
     */
166 5
    public function getFiles() : FileCollection
167
    {
168 5
        Filesystem::checkExists($this->path);
169 5
        Filesystem::checkReadable($this->path);
170 5
        $contents = [];
171
172 5
        $files = scandir($this->path);
173 5
        foreach ($files as $file) {
174 5
            if($file != '.' && $file != '..') {
175 5
                $contents[] = "$this->path/$file";
176
            }
177
        }
178 5
        return new FileCollection($contents);
179
    }
180
181 3
    public function __toString()
182
    {
183 3
        return $this->path;
184
    }
185
}
186