Completed
Push — master ( 6da8c0...fe2605 )
by Vladimir
02:38
created

Filesystem   A

Complexity

Total Complexity 24

Size/Duplication

Total Lines 237
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 6

Test Coverage

Coverage 42.11%

Importance

Changes 0
Metric Value
wmc 24
lcom 2
cbo 6
dl 0
loc 237
ccs 24
cts 57
cp 0.4211
rs 10
c 0
b 0
f 0

15 Methods

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