Completed
Push — master ( 3c4d84...92e7ec )
by Vladimir
02:30
created

Filesystem   A

Complexity

Total Complexity 23

Size/Duplication

Total Lines 232
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 6

Test Coverage

Coverage 52.73%

Importance

Changes 0
Metric Value
wmc 23
lcom 2
cbo 6
dl 0
loc 232
ccs 29
cts 55
cp 0.5273
rs 10
c 0
b 0
f 0

15 Methods

Rating   Name   Duplication   Size   Complexity  
A absolutePath() 0 12 2
A appendPath() 0 4 1
B copy() 0 29 6
A createFileObject() 0 4 1
A getRelativePath() 0 4 1
A getBaseName() 0 4 1
A getFileName() 0 4 1
A getFolderPath() 0 4 1
A getExtension() 0 4 1
A isDir() 0 4 1
A isFile() 0 4 1
A isSymlink() 0 4 1
A safeReadFile() 0 22 3
A removeExtension() 0 7 1
A path() 0 4 1
1
<?php
2
3
/**
4
 * @copyright 2017 Vladimir Jimenez
5
 * @license   https://github.com/allejo/stakx/blob/master/LICENSE.md MIT
6
 */
7
8
namespace allejo\stakx\System;
9
10
use allejo\stakx\Exception\FileAccessDeniedException;
11
use allejo\stakx\Filesystem\File;
12
use allejo\stakx\Filesystem\FilesystemPath;
13
use allejo\stakx\Service;
14
use Symfony\Component\Filesystem\Exception\FileNotFoundException;
15
use Symfony\Component\Filesystem\Exception\IOException;
16
17
/**
18
 * Class Filesystem.
19
 *
20
 * This class extends Symfony's Filesystem to provide convenience functions
21
 */
22
class Filesystem extends \Symfony\Component\Filesystem\Filesystem
23
{
24
    /**
25
     * Build an absolute file or directory path separated by the OS specific directory separator.
26
     *
27
     * @param string ...$pathFragments
28
     *
29
     * @return string
30
     */
31 77
    public function absolutePath($pathFragments)
32
    {
33 77
        if ($this->isAbsolutePath($pathFragments))
34
        {
35 50
            return $pathFragments;
36
        }
37
38 31
        $args = func_get_args();
39 31
        array_unshift($args, Service::getWorkingDirectory());
40
41 31
        return implode(DIRECTORY_SEPARATOR, $args);
42
    }
43
44
    /**
45
     * Build a file or directory path separated by the OS specific directory separator.
46
     *
47
     * @param string ...$pathFragments
48
     *
49
     * @return string
50
     */
51 13
    public function appendPath($pathFragments)
0 ignored issues
show
Unused Code introduced by
The parameter $pathFragments is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
52
    {
53 13
        return implode(DIRECTORY_SEPARATOR, func_get_args());
54
    }
55
56
    /**
57
     * Copy a file or folder recursively.
58
     *
59
     * @param string $originFile          The original filename
60
     * @param string $targetFile          The target filename
61
     * @param bool   $overwriteNewerFiles If true, target files newer than origin files are overwritten
62
     *
63
     * @throws FileNotFoundException When originFile doesn't exist
64
     * @throws IOException           When copy fails
65
     */
66
    public function copy($originFile, $targetFile, $overwriteNewerFiles = false)
67
    {
68
        if ($this->isDir($originFile))
69
        {
70
            if (!$this->isDir($targetFile))
71
            {
72
                mkdir($targetFile, 0755, true);
73
            }
74
75
            $dir = dir($originFile);
76
77
            while (false !== $entry = $dir->read())
78
            {
79
                // Skip pointers
80
                if ($entry == '.' || $entry == '..')
81
                {
82
                    continue;
83
                }
84
85
                $this->copy("$originFile/$entry", "$targetFile/$entry", true);
86
            }
87
88
            $dir->close();
89
        }
90
        else
91
        {
92
            parent::copy($originFile, $targetFile, $overwriteNewerFiles);
93
        }
94
    }
95
96
    /**
97
     * Create an instance of stakx's File object with relative path information.
98
     *
99
     * @param string $filePath
100
     *
101
     * @return File
102
     */
103
    public function createFileObject($filePath)
104
    {
105
        return new File($this->absolutePath($filePath));
106
    }
107
108
    /**
109
     * Strip the current working directory from an absolute path.
110
     *
111
     * @param string $path An absolute path
112
     *
113
     * @return string
114
     */
115 64
    public function getRelativePath($path)
116
    {
117 64
        return str_replace(Service::getWorkingDirectory() . DIRECTORY_SEPARATOR, '', $path);
118
    }
119
120
    /**
121
     * Get the name of a given file without the extension.
122
     *
123
     * @param string $filePath A file path
124
     *
125
     * @return string
126
     */
127 4
    public function getBaseName($filePath)
128
    {
129 4
        return pathinfo($filePath, PATHINFO_FILENAME);
130
    }
131
132
    /**
133
     * Get the name of a given file.
134
     *
135
     * @param string $filePath A file path
136
     *
137
     * @return string
138
     */
139
    public function getFileName($filePath)
140
    {
141
        return pathinfo($filePath, PATHINFO_BASENAME);
142
    }
143
144
    /**
145
     * Get the parent directory of a given file.
146
     *
147
     * @param string $filePath A file path
148
     *
149
     * @return string
150
     */
151 4
    public function getFolderPath($filePath)
152
    {
153 4
        return pathinfo($filePath, PATHINFO_DIRNAME);
154
    }
155
156
    /**
157
     * Get the extension of a given file.
158
     *
159
     * @param string $filename A file path
160
     *
161
     * @return string The extension of the file
162
     */
163 25
    public function getExtension($filename)
164
    {
165 25
        return pathinfo($filename, PATHINFO_EXTENSION);
166
    }
167
168
    /**
169
     * Check whether or not if a given path is a directory.
170
     *
171
     * @param string $folderPath
172
     *
173
     * @return bool
174
     */
175
    public function isDir($folderPath)
176
    {
177
        return is_dir($folderPath);
178
    }
179
180
    /**
181
     * Check whether or not a given path is a file.
182
     *
183
     * @param string $filePath
184
     *
185
     * @return bool
186
     */
187
    public function isFile($filePath)
188
    {
189
        return is_file($filePath);
190
    }
191
192
    /**
193
     * Check whether a given file path is a symlink
194
     *
195
     * @param  string $filePath
196
     *
197
     * @return bool
198
     */
199
    public function isSymlink($filePath)
200
    {
201
        return is_link($filePath);
202
    }
203
204
    /**
205
     * Only read a file's contents if it's within the current working directory
206
     *
207
     * @param  string $filePath
208
     *
209
     * @return bool|string
210
     */
211 36
    public function safeReadFile($filePath)
212
    {
213 36
        $absPath = realpath($this->absolutePath($filePath));
214
215 36
        if (!$this->exists($absPath))
216
        {
217
            throw new FileNotFoundException(sprintf(
218
                "The '%s' file could not be found or is outside the website working directory",
219
                $filePath
220
            ));
221
        }
222
223 36
        if (strpos($absPath, Service::getWorkingDirectory()) !== 0)
224
        {
225 36
            throw new FileAccessDeniedException(sprintf(
226 36
                "The '%s' file is outside the website working directory",
227 36
                $filePath
228
            ));
229
        }
230
231
        return file_get_contents($absPath);
232
    }
233
234
    /**
235
     * Get the full path to the file without the extension.
236
     *
237
     * @param string $filename A file path
238
     *
239
     * @return string
240
     */
241 4
    public function removeExtension($filename)
242
    {
243 4
        return $this->appendPath(
244 4
            $this->getFolderPath($filename),
245 4
            $this->getBaseName($filename)
246
        );
247
    }
248
249 6
    public function path($path)
250
    {
251 6
        return (new FilesystemPath($path));
252
    }
253
}
254