Filesystem::getPath()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 7
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 10
ccs 7
cts 7
cp 1
crap 1
rs 10
1
<?php
2
3
/**
4
 * Copyright MediaCT. All rights reserved.
5
 * https://www.mediact.nl
6
 */
7
8
declare(strict_types=1);
9
10
namespace Mediact\CodingStandard\PhpStorm;
11
12
use RecursiveDirectoryIterator;
13
use RecursiveIteratorIterator;
14
use RuntimeException;
15
use SplFileInfo;
16
17
class Filesystem implements FilesystemInterface
18
{
19
    /**
20
     * @var string
21
     */
22
    private $root = '';
23
24
    /**
25
     * Constructor.
26
     *
27
     * @param string $root
28
     */
29 1
    public function __construct($root)
30
    {
31 1
        if (! empty($root)) {
32 1
            $this->root = rtrim($root, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
33
        }
34 1
    }
35
36
    /**
37
     * Check whether a file exists.
38
     *
39
     * @param string $path
40
     *
41
     * @return bool
42
     */
43 1
    public function has(string $path): bool
44
    {
45 1
        return file_exists($this->getPath($path));
46
    }
47
48
    /**
49
     * Read a path.
50
     *
51
     * @param string $path
52
     *
53
     * @return string
54
     * @throws RuntimeException When the path is not readable.
55
     */
56 3
    public function read(string $path): string
57
    {
58 3
        $path = $this->getPath($path);
59 3
        if (!is_readable($path) || !is_file($path)) {
60 2
            throw new RuntimeException($path . ' is not readable file');
61
        }
62
63 1
        return file_get_contents($path);
64
    }
65
66
    /**
67
     * Write contents to a path.
68
     *
69
     * @param string $path
70
     * @param string $contents
71
     *
72
     * @return bool
73
     * @throws RuntimeException When the path is not writable.
74
     */
75 3
    public function put(string $path, string $contents): bool
76
    {
77 3
        $directory = dirname($path);
78 3
        $this->createDir($directory);
79 3
        $path = $this->getPath($path);
80 3
        if (!file_exists($path) && !is_writable(dirname($path))) {
81 1
            throw new RuntimeException(dirname($path) . ' is not writable');
82
        }
83
84 2
        if (file_exists($path) && !is_writable($path)) {
85 1
            throw new RuntimeException($path . ' is not writable');
86
        }
87
88 1
        return (bool) file_put_contents($path, $contents);
89
    }
90
91
    /**
92
     * Create a directory if it does not exist.
93
     *
94
     * @param string $path
95
     *
96
     * @return bool
97
     * @throws RuntimeException When the directory can not be created.
98
     */
99 3
    public function createDir(string $path): bool
100
    {
101 3
        $directory = $this->getPath($path);
102 3
        if (!is_dir($directory)) {
103 3
            if (file_exists($directory)) {
104 1
                throw new RuntimeException(
105 1
                    $directory . ' is not a directory.'
106
                );
107
            }
108
109 2
            if (!mkdir($directory, 0777, true)) {
110 1
                throw new RuntimeException(
111 1
                    $directory . ' can not be created.'
112
                );
113
            }
114
        }
115
116 1
        return true;
117
    }
118
119
    /**
120
     * List contents of a directory.
121
     *
122
     * @param string $path
123
     *
124
     * @return array
125
     * @throws RuntimeException When the path is not a directory.
126
     */
127 2
    public function listFiles(string $path = ''): array
128
    {
129 2
        $directory = $this->getPath($path);
130 2
        if (!is_dir($directory)) {
131 1
            throw new RuntimeException(
132 1
                $directory . ' is not a directory.'
133
            );
134
        }
135
136 1
        $iterator = new RecursiveIteratorIterator(
137 1
            new RecursiveDirectoryIterator(
138 1
                $this->getPath($path),
139 1
                RecursiveDirectoryIterator::SKIP_DOTS
140
            ),
141 1
            RecursiveIteratorIterator::SELF_FIRST
142
        );
143
144 1
        $files = [];
145
146
        /** @var SplFileInfo $fileInfo */
147 1
        foreach ($iterator as $fileInfo) {
148 1
            if ($fileInfo->isDir()) {
149 1
                continue;
150
            }
151
152 1
            $files[] = preg_replace(
153 1
                sprintf('/^%s/', preg_quote($this->root, '/')),
154 1
                '',
155 1
                $fileInfo->getPathname()
156
            );
157
        }
158
159 1
        return $files;
160
    }
161
162
    /**
163
     * Get the full path.
164
     *
165
     * @param string $path
166
     *
167
     * @return string
168
     */
169 1
    private function getPath(string $path): string
170
    {
171 1
        return $this->root .
172 1
            ltrim(
173 1
                preg_replace(
174 1
                    sprintf('|%s{2,}|', preg_quote(DIRECTORY_SEPARATOR)),
175 1
                    DIRECTORY_SEPARATOR,
176
                    $path
177
                ),
178 1
                DIRECTORY_SEPARATOR
179
            );
180
    }
181
182
    /**
183
     * Get root
184
     *
185
     * @return string
186
     */
187
    public function getRoot(): string
188
    {
189
        return $this->root;
190
    }
191
}
192