FileCache::getFilePath()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the ekino Drupal Debug project.
7
 *
8
 * (c) ekino
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 Ekino\Drupal\Debug\Cache;
15
16
use Carbon\Carbon;
17
use Ekino\Drupal\Debug\Resource\Model\ResourcesCollection;
18
use Ekino\Drupal\Debug\Resource\ResourcesFreshnessChecker;
19
use Symfony\Component\Filesystem\Exception\IOException;
20
use Symfony\Component\Filesystem\Filesystem;
21
22
class FileCache
23
{
24
    /**
25
     * @var string
26
     */
27
    private $filePath;
28
29
    /**
30
     * @var ResourcesFreshnessChecker
31
     */
32
    private $resourcesFreshnessChecker;
33
34
    /**
35
     * @param string              $filePath
36
     * @param ResourcesCollection $resourcesCollection
37
     */
38 52
    public function __construct(string $filePath, ResourcesCollection $resourcesCollection)
39
    {
40 52
        $this->filePath = $filePath;
41
42 52
        $this->resourcesFreshnessChecker = new ResourcesFreshnessChecker(\sprintf('%s.meta', $filePath), $resourcesCollection);
43 52
    }
44
45
    /**
46
     * @return bool
47
     */
48 37
    public function isFresh(): bool
49
    {
50 37
        return $this->resourcesFreshnessChecker->isFresh();
51
    }
52
53
    /**
54
     * @return array|false
55
     */
56 47
    public function get()
57
    {
58 47
        if (!\is_file($this->filePath)) {
59 22
            return false;
60
        }
61
62
        try {
63 26
            $data = require $this->filePath;
64 1
        } catch (\Error $e) {
65 1
            return false;
66
        }
67
68 25
        if (!\is_array($data)) {
69 1
            throw new \LogicException('The file cache data content should be an array.');
70
        }
71
72 24
        if (!\array_key_exists('data', $data)) {
73 1
            throw new \LogicException('The file cache data content should have a "data" key.');
74
        }
75
76 23
        return $data;
77
    }
78
79
    /**
80
     * @return array
81
     */
82 18
    public function getData(): array
83
    {
84 18
        $data = $this->get();
85 18
        if (!\is_array($data)) {
86 1
            return array();
87
        }
88
89 17
        return $data['data'];
90
    }
91
92
    /**
93
     * @param array $data
94
     */
95 24
    public function write(array $data): void
96
    {
97 24
        $currentData = $this->get();
98 24
        if (\is_array($currentData)) {
99 4
            $data = \array_merge($currentData['data'], $data);
100
        }
101
102 24
        $umask = \umask();
103 24
        $filesystem = new Filesystem();
104
105 24
        $filesystem->dumpFile($this->filePath, '<?php return '.\var_export(array(
106 24
            'date' => Carbon::now()->format(DATE_ATOM),
107 24
            'data' => $data,
108 24
        ), true).';');
109
110
        try {
111 24
            $filesystem->chmod($this->filePath, 0666, $umask);
112
        } catch (IOException $e) {
113
            // discard chmod failure (some filesystem may not support it)
114
        }
115
116 24
        if (\function_exists('opcache_invalidate') && \filter_var(\ini_get('opcache.enable'), FILTER_VALIDATE_BOOLEAN)) {
117 24
            @\opcache_invalidate($this->filePath, true);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for opcache_invalidate(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

117
            /** @scrutinizer ignore-unhandled */ @\opcache_invalidate($this->filePath, true);

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...
118
        }
119
120 24
        $this->resourcesFreshnessChecker->commit();
121 24
    }
122
123 20
    public function invalidate(): void
124
    {
125 20
        if (\is_file($this->filePath)) {
126 18
            \unlink($this->filePath);
127
        }
128 20
    }
129
130 1
    public function getFilePath(): string
131
    {
132 1
        return $this->filePath;
133
    }
134
135
    public function getCurrentResourcesCollection(): ResourcesCollection
136
    {
137
        return $this->resourcesFreshnessChecker->getCurrentResourcesCollection();
138
    }
139
}
140