Completed
Pull Request — master (#42)
by Vladimir
02:27
created

Filesystem::isSymlink()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 4
ccs 0
cts 2
cp 0
crap 2
rs 10
c 0
b 0
f 0
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 Symfony\Component\Filesystem\Exception\FileNotFoundException;
11
use Symfony\Component\Filesystem\Exception\IOException;
12
use Symfony\Component\Finder\SplFileInfo;
13
14
/**
15
 * Class Filesystem.
16
 *
17
 * This class extends Symfony's Filesystem to provide convenience functions
18
 */
19
class Filesystem extends \Symfony\Component\Filesystem\Filesystem
20
{
21
    /**
22
     * Build an absolute file or directory path separated by the OS specific directory separator.
23
     *
24
     * @param string ...$pathFragments
25
     *
26
     * @return string
27
     */
28 64
    public function absolutePath($pathFragments)
29
    {
30 64
        if ($this->isAbsolutePath($pathFragments))
31 64
        {
32 37
            return $pathFragments;
33
        }
34
35 44
        $args = func_get_args();
36 44
        array_unshift($args, getcwd());
37
38 44
        return implode(DIRECTORY_SEPARATOR, $args);
39
    }
40
41
    /**
42
     * Build a file or directory path separated by the OS specific directory separator.
43
     *
44
     * @param string ...$pathFragments
45
     *
46
     * @return string
47
     */
48 19
    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...
49
    {
50 19
        return implode(DIRECTORY_SEPARATOR, func_get_args());
51
    }
52
53
    /**
54
     * Copy a file or folder recursively.
55
     *
56
     * @param string $originFile          The original filename
57
     * @param string $targetFile          The target filename
58
     * @param bool   $overwriteNewerFiles If true, target files newer than origin files are overwritten
59
     *
60
     * @throws FileNotFoundException When originFile doesn't exist
61
     * @throws IOException           When copy fails
62
     */
63
    public function copy($originFile, $targetFile, $overwriteNewerFiles = false)
64
    {
65
        if ($this->isDir($originFile))
66
        {
67
            if (!$this->isDir($targetFile))
68
            {
69
                mkdir($targetFile, 0755, true);
70
            }
71
72
            $dir = dir($originFile);
73
74
            while (false !== $entry = $dir->read())
75
            {
76
                // Skip pointers
77
                if ($entry == '.' || $entry == '..')
78
                {
79
                    continue;
80
                }
81
82
                $this->copy("$originFile/$entry", "$targetFile/$entry", true);
3 ignored issues
show
Coding Style Best Practice introduced by
As per coding-style, please use concatenation or sprintf for the variable $originFile instead of interpolation.

It is generally a best practice as it is often more readable to use concatenation instead of interpolation for variables inside strings.

// Instead of
$x = "foo $bar $baz";

// Better use either
$x = "foo " . $bar . " " . $baz;
$x = sprintf("foo %s %s", $bar, $baz);
Loading history...
Coding Style Best Practice introduced by
As per coding-style, please use concatenation or sprintf for the variable $entry instead of interpolation.

It is generally a best practice as it is often more readable to use concatenation instead of interpolation for variables inside strings.

// Instead of
$x = "foo $bar $baz";

// Better use either
$x = "foo " . $bar . " " . $baz;
$x = sprintf("foo %s %s", $bar, $baz);
Loading history...
Coding Style Best Practice introduced by
As per coding-style, please use concatenation or sprintf for the variable $targetFile instead of interpolation.

It is generally a best practice as it is often more readable to use concatenation instead of interpolation for variables inside strings.

// Instead of
$x = "foo $bar $baz";

// Better use either
$x = "foo " . $bar . " " . $baz;
$x = sprintf("foo %s %s", $bar, $baz);
Loading history...
83
            }
84
85
            $dir->close();
86
        }
87
        else
88
        {
89
            parent::copy($originFile, $targetFile, $overwriteNewerFiles);
90
        }
91
    }
92
93
    /**
94
     * Create an instance of Symfony's SplFileInfo with relative path information.
95
     *
96
     * @param string $filePath
97
     *
98
     * @return SplFileInfo
99
     */
100
    public function createSplFileInfo($filePath)
101
    {
102
        return new SplFileInfo(
103
            $this->absolutePath($filePath),
104
            $this->getRelativePath($this->getFolderPath($filePath)),
105
            $this->getRelativePath($filePath)
106
        );
107
    }
108
109
    /**
110
     * Strip the current working directory from an absolute path.
111
     *
112
     * @param string $path An absolute path
113
     *
114
     * @return string
115
     */
116 49
    public function getRelativePath($path)
117
    {
118 49
        return str_replace(getcwd() . DIRECTORY_SEPARATOR, '', $path);
119
    }
120
121
    /**
122
     * Get the name of a given file without the extension.
123
     *
124
     * @param string $filePath A file path
125
     *
126
     * @return string
127
     */
128 39
    public function getBaseName($filePath)
129
    {
130 39
        return pathinfo($filePath, PATHINFO_FILENAME);
131
    }
132
133
    /**
134
     * Get the name of a given file.
135
     *
136
     * @param string $filePath A file path
137
     *
138
     * @return string
139
     */
140 13
    public function getFileName($filePath)
141
    {
142 13
        return pathinfo($filePath, PATHINFO_BASENAME);
143
    }
144
145
    /**
146
     * Get the parent directory of a given file.
147
     *
148
     * @param string $filePath A file path
149
     *
150
     * @return string
151
     */
152 17
    public function getFolderPath($filePath)
153
    {
154 17
        return pathinfo($filePath, PATHINFO_DIRNAME);
155
    }
156
157
    /**
158
     * Get the extension of a given file.
159
     *
160
     * @param string $filename A file path
161
     *
162
     * @return string The extension of the file
163
     */
164 113
    public function getExtension($filename)
165
    {
166 113
        return pathinfo($filename, PATHINFO_EXTENSION);
167
    }
168
169
    /**
170
     * Check whether or not if a given path is a directory.
171
     *
172
     * @param string $folderPath
173
     *
174
     * @return bool
175
     */
176 13
    public function isDir($folderPath)
177
    {
178 13
        return is_dir($folderPath);
179
    }
180
181
    /**
182
     * Check whether a given file path is a symlink
183
     *
184
     * @param  string $filePath
185
     *
186
     * @return bool
187
     */
188
    public function isSymlink($filePath)
189
    {
190
        return is_link($filePath);
191
    }
192
193
    /**
194
     * Only read a file's contents if it's within the current working directory
195
     *
196
     * @param  string $filePath
197
     *
198
     * @return bool|string
199
     */
200 14
    public function safeReadFile($filePath)
201
    {
202 14
        $absPath = realpath($this->absolutePath($filePath));
203
204 14
        if (strpos($absPath, getcwd()) !== 0)
205 14
        {
206
            throw new FileNotFoundException(sprintf(
207
                "The '%s' file could not be found or is outside the website working directory",
208
                $filePath
209
            ));
210
        }
211
212 14
        return file_get_contents($absPath);
213
    }
214
215
    /**
216
     * Get the full path to the file without the extension.
217
     *
218
     * @param string $filename A file path
219
     *
220
     * @return string
221
     */
222 4
    public function removeExtension($filename)
223
    {
224 4
        return $this->appendPath(
225 4
            $this->getFolderPath($filename),
226 4
            $this->getBaseName($filename)
227 4
        );
228
    }
229
230
    /**
231
     * Write a file.
232
     *
233
     * @param string $targetDir The directory of where the file will be created; the file name is a separate variable
234
     * @param string $fileName  The name of the file
235
     * @param string $content   The content that belongs in the file
236
     *
237
     * @return SplFileInfo A reference to the newly created file
238
     */
239 View Code Duplication
    public function writeFile($targetDir, $fileName, $content)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
240
    {
241
        $outputFolder = $this->getFolderPath($this->absolutePath($targetDir, $fileName));
242
        $targetFile = $this->getFileName($fileName);
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 3 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
243
244
        if (!file_exists($outputFolder))
245
        {
246
            mkdir($outputFolder, 0755, true);
247
        }
248
249
        file_put_contents($this->appendPath($outputFolder, $targetFile), $content, LOCK_EX);
250
251
        return (new SplFileInfo(
252
            $fileName,
253
            $this->absolutePath($targetDir),
254
            $this->absolutePath($targetDir, $fileName)
255
        ));
256
    }
257
}
258