Passed
Push — master ( f578af...67718f )
by Alexander
02:21 queued 59s
created

FastRouteCache   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 137
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 56
c 1
b 0
f 0
dl 0
loc 137
ccs 0
cts 103
cp 0
rs 10
wmc 19

12 Methods

Rating   Name   Duplication   Size   Complexity  
A get() 0 30 3
A __construct() 0 3 1
A checkFileExistsAndWritable() 0 7 3
A checkDirectoryWritable() 0 7 2
A getMultiple() 0 3 1
A has() 0 3 1
A deleteMultiple() 0 3 1
A setMultiple() 0 3 1
A checkDirectoryExists() 0 7 2
A set() 0 18 2
A clear() 0 3 1
A delete() 0 3 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Router\FastRoute;
6
7
use Psr\SimpleCache\CacheInterface;
8
9
use function dirname;
10
use function file_exists;
11
use function file_put_contents;
12
use function is_array;
13
use function is_dir;
14
use function is_writable;
15
use function restore_error_handler;
16
use function set_error_handler;
17
use function sprintf;
18
use function var_export;
19
20
class FastRouteCache implements CacheInterface
21
{
22
    /**
23
     * Template used when generating the cache file.
24
     */
25
    public const CACHE_TEMPLATE = <<< 'EOT'
26
<?php
27
return %s;
28
EOT;
29
    /**
30
     * Cache file path relative to the project directory.
31
     *
32
     * @var string
33
     */
34
    private string $cacheFile;
35
36
    public function __construct(string $cacheFilePath)
37
    {
38
        $this->cacheFile = $cacheFilePath;
39
    }
40
41
    public function get($key, $default = null): array
42
    {
43
        set_error_handler(
44
            static function () {
45
            },
46
            E_WARNING
47
        ); // suppress php warnings
48
        $data = include $this->cacheFile;
49
        restore_error_handler();
50
51
        // Cache file does not exist
52
        if (false === $data) {
53
            throw new \RuntimeException(
54
                sprintf(
55
                    'File "%s"; doesn\'t exist',
56
                    $this->cacheFile
57
                )
58
            );
59
        }
60
61
        if (!is_array($data)) {
62
            throw new \RuntimeException(
63
                sprintf(
64
                    'Invalid cache file "%s"; cache file MUST return an array',
65
                    $this->cacheFile
66
                )
67
            );
68
        }
69
70
        return $data;
71
    }
72
73
    public function set($key, $value, $ttl = null): void
74
    {
75
        $cacheDir = dirname($this->cacheFile);
76
77
        $this->checkDirectoryExists($cacheDir);
78
        $this->checkDirectoryWritable($cacheDir);
79
        $this->checkFileExistsAndWritable($this->cacheFile);
80
        $result = file_put_contents(
81
            $this->cacheFile,
82
            sprintf(self::CACHE_TEMPLATE, var_export($value, true)),
83
            LOCK_EX
84
        );
85
86
        if ($result === false) {
87
            throw new \RuntimeException(
88
                sprintf(
89
                    'Can\'t write file "%s"',
90
                    $this->cacheFile
91
                )
92
            );
93
        }
94
    }
95
96
    public function delete($key): bool
97
    {
98
        return unlink($this->cacheFile);
99
    }
100
101
    public function clear(): bool
102
    {
103
        return unlink($this->cacheFile);
104
    }
105
106
    public function has($key): bool
107
    {
108
        return file_exists($this->cacheFile);
109
    }
110
111
    public function setMultiple($values, $ttl = null)
112
    {
113
        throw new \RuntimeException('Method is not implemented');
114
    }
115
116
    public function getMultiple($keys, $default = null)
117
    {
118
        throw new \RuntimeException('Method is not implemented');
119
    }
120
121
    public function deleteMultiple($keys)
122
    {
123
        throw new \RuntimeException('Method is not implemented');
124
    }
125
126
    private function checkDirectoryExists(string $dir): void
127
    {
128
        if (!is_dir($dir)) {
129
            throw new \RuntimeException(
130
                sprintf(
131
                    'The cache directory "%s" does not exist',
132
                    $dir
133
                )
134
            );
135
        }
136
    }
137
138
    private function checkDirectoryWritable(string $dir): void
139
    {
140
        if (!is_writable($dir)) {
141
            throw new \RuntimeException(
142
                sprintf(
143
                    'The cache directory "%s" is not writable',
144
                    $dir
145
                )
146
            );
147
        }
148
    }
149
150
    private function checkFileExistsAndWritable(string $file): void
151
    {
152
        if (file_exists($file) && !is_writable($file)) {
153
            throw new \RuntimeException(
154
                sprintf(
155
                    'The cache file %s is not writable',
156
                    $file
157
                )
158
            );
159
        }
160
    }
161
}
162