Completed
Push — dev ( 385789...5662c6 )
by James Ekow Abaka
01:30
created

Directory::createIfNotExists()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

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