Completed
Push — dev ( 397072...03b82e )
by James Ekow Abaka
01:33
created

Directory   A

Complexity

Total Complexity 18

Size/Duplication

Total Lines 170
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 30.19%

Importance

Changes 0
Metric Value
wmc 18
lcom 1
cbo 2
dl 0
loc 170
ccs 16
cts 53
cp 0.3019
rs 10
c 0
b 0
f 0

10 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A directoryOperation() 0 13 3
A copyTo() 0 4 1
A getSize() 0 4 1
A moveTo() 0 6 1
A create() 0 21 4
A delete() 0 5 1
A getPath() 0 4 1
A getFiles() 0 14 4
A __toString() 0 4 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 3
    public function __construct(string $path = null)
30
    {
31 3
        $this->path = $path;
32 3
    }
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
    private function directoryOperation(string $operation, string $destination):void
46
    {
47
        try {
48
            Filesystem::checkExists($destination);
49
            $destination = $destination . DIRECTORY_SEPARATOR . basename($this);
50
        } catch (FileNotFoundException $e) {
51
            Filesystem::directory($destination)->create(true);
52
        }
53
54
        foreach ($this->getFiles() as $file) {
55
            $file->$operation($destination . DIRECTORY_SEPARATOR . basename($file));
56
        }
57
    }
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
    public function copyTo(string $destination): void
70
    {
71
        $this->directoryOperation('copyTo', $destination);
72
    }
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
    public function getSize() : int
83
    {
84
        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
    public function moveTo(string $destination) : void
98
    {
99
        $this->directoryOperation('moveTo', $destination);
100
        $this->delete();
101
        $this->path = $destination;
102
    }
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
    public function create($recursive=false, $permissions = 0755)
112
    {
113
        Filesystem::checkNotExists($this->path);
114
        if($recursive) {
115
            $segments = explode(DIRECTORY_SEPARATOR, $this->path);
116
            $accumulator = "";
117
            $parent = "";
118
            foreach($segments as $segment) {
119
                $accumulator .= $segment . DIRECTORY_SEPARATOR;
120
                if(is_dir($accumulator)) {
121
                    $parent = $accumulator;
122
                } else {
123
                    break;
124
                }
125
            }
126
        } else {
127
            $parent = dirname($this->path);
128
        }
129
        Filesystem::checkWritable($parent);
130
        mkdir($this->path, $permissions, true);
131
    }
132
133
    /**
134
     * Recursively delete the directory and all its contents.
135
     *
136
     * @throws FileNotFoundException
137
     * @throws FilesystemException
138
     * @throws \ntentan\utils\exceptions\FileNotReadableException
139
     */
140 1
    public function delete() : void
141
    {
142 1
        $this->getFiles()->delete();
143 1
        rmdir($this->path);
144 1
    }
145
146
    /**
147
     * Get the path of the directory.
148
     *
149
     * @return string
150
     */
151
    public function getPath() : string
152
    {
153
        return $this->path;
154
    }
155
156
    /**
157
     * Get the files in the directory.
158
     *
159
     * @throws FilesystemException
160
     * @throws \ntentan\utils\exceptions\FileNotFoundException
161
     * @throws \ntentan\utils\exceptions\FileNotReadableException
162
     * @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...
163
     */
164 2
    public function getFiles() : FileCollection
165
    {
166 2
        Filesystem::checkExists($this->path);
167 2
        Filesystem::checkReadable($this->path);
168 2
        $contents = [];
169
170 2
        $files = scandir($this->path);
171 2
        foreach ($files as $file) {
172 2
            if($file != '.' && $file != '..') {
173 2
                $contents[] = "$this->path/$file";
174
            }
175
        }
176 2
        return new FileCollection($contents);
177
    }
178
179
    public function __toString()
180
    {
181
        return $this->path;
182
    }
183
}
184