Passed
Push — master ( 2b999c...5d5c93 )
by Daniel
02:14
created

Filesystem::createDirectory()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 3
nc 2
nop 2
dl 0
loc 7
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Dandelion\Filesystem;
6
7
use Dandelion\Exception\IOException;
8
9
use function chdir;
10
use function file_get_contents;
11
use function getcwd;
12
use function in_array;
13
use function is_file;
14
use function rmdir;
15
use function rtrim;
16
use function scandir;
17
use function sprintf;
18
use function unlink;
19
20
class Filesystem implements FilesystemInterface
21
{
22
    protected const IGNORED_DIRECTORY_ENTRIES = ['.', '..'];
23
24
    /**
25
     * @param string $pathToFile
26
     *
27
     * @return string
28
     *
29
     * @throws \Dandelion\Exception\IOException
30
     */
31
    public function readFile(string $pathToFile): string
32
    {
33
        $fileContent = @file_get_contents($pathToFile);
34
35
        if ($fileContent === false) {
36
            throw new IOException(sprintf('Failed to read file "%s".', $pathToFile), 0, null);
37
        }
38
39
        return $fileContent;
40
    }
41
42
    /**
43
     * @return string
44
     *
45
     * @throws \Dandelion\Exception\IOException
46
     */
47
    public function getCurrentWorkingDirectory(): string
48
    {
49
        $currentWorkingDirectory = getcwd();
50
51
        if (!$currentWorkingDirectory) {
52
            // @codeCoverageIgnoreStart
53
            throw new IOException(sprintf('Could not get current working directory.'));
54
            // @codeCoverageIgnoreEnd
55
        }
56
57
        return rtrim($currentWorkingDirectory, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
58
    }
59
60
    /**
61
     * @param string $path
62
     * @param int $mode
63
     *
64
     * @return \Dandelion\Filesystem\FilesystemInterface
65
     *
66
     * @throws \Dandelion\Exception\IOException
67
     */
68
    public function createDirectory(string $path, int $mode = 0755): FilesystemInterface
69
    {
70
        if (!mkdir($path, $mode, true) && !is_dir($path)) {
71
            throw new IOException(sprintf('Could not create directory.'));
72
        }
73
74
        return $this;
75
    }
76
77
    /**
78
     * @param string $directory
79
     *
80
     * @return \Dandelion\Filesystem\FilesystemInterface
81
     *
82
     * @throws \Dandelion\Exception\IOException
83
     */
84
    public function changeDirectory(string $directory): FilesystemInterface
85
    {
86
        if (!@chdir($directory)) {
87
            throw new IOException(sprintf('Could not change directory.'));
88
        }
89
90
        return $this;
91
    }
92
93
    /**
94
     * @param string $directory
95
     *
96
     * @return \Dandelion\Filesystem\FilesystemInterface
97
     *
98
     * @throws \Exception
99
     */
100
    public function removeDirectory(string $directory): FilesystemInterface
101
    {
102
        if (!is_dir($directory)) {
103
            throw new IOException(sprintf('%s is not a directory.', $directory));
104
        }
105
106
        $this->removeDirectoryContent($directory);
107
108
        if (!rmdir($directory)) {
109
            throw new IOException(sprintf('Could not delete directory "%s".', $directory));
110
        }
111
112
        return $this;
113
    }
114
115
    /**
116
     * @param string $directory
117
     *
118
     * @return \Dandelion\Filesystem\FilesystemInterface
119
     *
120
     * @throws \Exception
121
     */
122
    protected function removeDirectoryContent(string $directory): FilesystemInterface
123
    {
124
        $directoryEntries = @scandir($directory);
125
126
        if ($directoryEntries === false) {
127
            throw new IOException(sprintf('Could not scan directory "%s".', $directory));
128
        }
129
130
        foreach ($directoryEntries as $directoryEntry) {
131
            if (in_array($directoryEntry, static::IGNORED_DIRECTORY_ENTRIES, true)) {
132
                continue;
133
            }
134
135
            $pathToDirectoryEntry = rtrim($directory, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . $directoryEntry;
136
137
            if (is_file($pathToDirectoryEntry)) {
138
                $this->removeFile($pathToDirectoryEntry);
139
                continue;
140
            }
141
142
            if (is_dir($pathToDirectoryEntry)) {
143
                $this->removeDirectory($pathToDirectoryEntry);
144
                continue;
145
            }
146
        }
147
148
        return $this;
149
    }
150
151
    /**
152
     * @param string $file
153
     *
154
     * @return \Dandelion\Filesystem\FilesystemInterface
155
     *
156
     * @throws \Exception
157
     */
158
    public function removeFile(string $file): FilesystemInterface
159
    {
160
        if (!is_file($file)) {
161
            throw new IOException(sprintf('%s is not a file.', $file));
162
        }
163
164
        if (!unlink($file)) {
165
            throw new IOException(sprintf('Could not delete file "%s".', $file));
166
        }
167
168
        return $this;
169
    }
170
}
171