FilesystemTestCase   A
last analyzed

Complexity

Total Complexity 31

Size/Duplication

Total Lines 145
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 1

Importance

Changes 0
Metric Value
wmc 31
lcom 2
cbo 1
dl 0
loc 145
rs 9.92
c 0
b 0
f 0

10 Methods

Rating   Name   Duplication   Size   Complexity  
B setUpBeforeClass() 0 28 8
A setUp() 0 8 1
A tearDown() 0 12 3
A assertFilePermissions() 0 9 1
A getFileOwner() 0 8 2
A getFileGroup() 0 11 2
A markAsSkippedIfLinkIsMissing() 0 10 4
A markAsSkippedIfSymlinkIsMissing() 0 11 6
A markAsSkippedIfChmodIsMissing() 0 6 2
A markAsSkippedIfPosixIsMissing() 0 6 2
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Sonata Project package.
7
 *
8
 * (c) Thomas Rabaix <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Sonata\MediaBundle\Tests\Fixtures;
15
16
use PHPUnit\Framework\TestCase;
17
use Symfony\Component\Filesystem\Filesystem;
18
19
class FilesystemTestCase extends TestCase
20
{
21
    protected $longPathNamesWindows = [];
22
23
    /**
24
     * @var Filesystem
25
     */
26
    protected $filesystem;
27
28
    /**
29
     * @var string
30
     */
31
    protected $workspace;
32
33
    private $umask;
34
35
    /**
36
     * @var bool|null Flag for hard links on Windows
37
     */
38
    private static $linkOnWindows;
39
40
    /**
41
     * @var bool|null Flag for symbolic links on Windows
42
     */
43
    private static $symlinkOnWindows;
44
45
    public static function setUpBeforeClass(): void
46
    {
47
        if ('\\' === \DIRECTORY_SEPARATOR) {
48
            self::$linkOnWindows = true;
49
            $originFile = tempnam(sys_get_temp_dir(), 'li');
50
            $targetFile = tempnam(sys_get_temp_dir(), 'li');
51
            if (true !== @link($originFile, $targetFile)) {
52
                $report = error_get_last();
53
                if (\is_array($report) && false !== strpos($report['message'], 'error code(1314)')) {
54
                    self::$linkOnWindows = false;
55
                }
56
            } else {
57
                @unlink($targetFile);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
58
            }
59
60
            self::$symlinkOnWindows = true;
61
            $originDir = tempnam(sys_get_temp_dir(), 'sl');
62
            $targetDir = tempnam(sys_get_temp_dir(), 'sl');
63
            if (true !== @symlink($originDir, $targetDir)) {
64
                $report = error_get_last();
65
                if (\is_array($report) && false !== strpos($report['message'], 'error code(1314)')) {
66
                    self::$symlinkOnWindows = false;
67
                }
68
            } else {
69
                @unlink($targetDir);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
70
            }
71
        }
72
    }
73
74
    protected function setUp(): void
75
    {
76
        $this->umask = umask(0);
77
        $this->filesystem = new Filesystem();
78
        $this->workspace = sys_get_temp_dir().'/'.microtime(true).'.'.mt_rand();
79
        mkdir($this->workspace, 0777, true);
80
        $this->workspace = realpath($this->workspace);
81
    }
82
83
    protected function tearDown(): void
84
    {
85
        if (!empty($this->longPathNamesWindows)) {
86
            foreach ($this->longPathNamesWindows as $path) {
87
                exec('DEL '.$path);
88
            }
89
            $this->longPathNamesWindows = [];
90
        }
91
92
        $this->filesystem->remove($this->workspace);
93
        umask($this->umask);
94
    }
95
96
    protected function assertFilePermissions(int $expectedFilePerms, string $filePath): void
97
    {
98
        $actualFilePerms = (int) substr(sprintf('%o', fileperms($filePath)), -3);
99
        $this->assertSame(
100
            $expectedFilePerms,
101
            $actualFilePerms,
102
            sprintf('File permissions for %s must be %s. Actual %s', $filePath, $expectedFilePerms, $actualFilePerms)
103
        );
104
    }
105
106
    protected function getFileOwner(string $filepath)
107
    {
108
        $this->markAsSkippedIfPosixIsMissing();
109
110
        $infos = stat($filepath);
111
112
        return ($datas = posix_getpwuid($infos['uid'])) ? $datas['name'] : null;
113
    }
114
115
    protected function getFileGroup(string $filepath)
116
    {
117
        $this->markAsSkippedIfPosixIsMissing();
118
119
        $infos = stat($filepath);
120
        if ($datas = posix_getgrgid($infos['gid'])) {
121
            return $datas['name'];
122
        }
123
124
        $this->markTestSkipped('Unable to retrieve file group name');
125
    }
126
127
    protected function markAsSkippedIfLinkIsMissing(): void
128
    {
129
        if (!\function_exists('link')) {
130
            $this->markTestSkipped('link is not supported');
131
        }
132
133
        if ('\\' === \DIRECTORY_SEPARATOR && false === self::$linkOnWindows) {
134
            $this->markTestSkipped('link requires "Create hard links" privilege on windows');
135
        }
136
    }
137
138
    protected function markAsSkippedIfSymlinkIsMissing(bool $relative = false): void
139
    {
140
        if ('\\' === \DIRECTORY_SEPARATOR && false === self::$symlinkOnWindows) {
141
            $this->markTestSkipped('symlink requires "Create symbolic links" privilege on Windows');
142
        }
143
144
        // https://bugs.php.net/69473
145
        if ($relative && '\\' === \DIRECTORY_SEPARATOR && 1 === PHP_ZTS) {
146
            $this->markTestSkipped('symlink does not support relative paths on thread safe Windows PHP versions');
147
        }
148
    }
149
150
    protected function markAsSkippedIfChmodIsMissing(): void
151
    {
152
        if ('\\' === \DIRECTORY_SEPARATOR) {
153
            $this->markTestSkipped('chmod is not supported on Windows');
154
        }
155
    }
156
157
    protected function markAsSkippedIfPosixIsMissing(): void
158
    {
159
        if (!\function_exists('posix_isatty')) {
160
            $this->markTestSkipped('Function posix_isatty is required.');
161
        }
162
    }
163
}
164