Completed
Pull Request — master (#59)
by Jitendra
02:21
created

FileStore::set()   A

Complexity

Conditions 5
Paths 4

Size

Total Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 5

Importance

Changes 0
Metric Value
cc 5
nc 4
nop 2
dl 0
loc 18
ccs 10
cts 10
cp 1
crap 5
rs 9.3554
c 0
b 0
f 0
1
<?php
2
3
namespace TusPhp\Cache;
4
5
use Carbon\Carbon;
6
7
class FileStore extends AbstractCache
8
{
9
    /** @const string */
10
    const DEFAULT_CACHE_FILE = 'tus_php.cache';
11
12
    /** @var string */
13
    protected $cacheDir;
14
15
    /** @var string */
16
    protected $cacheFile;
17
18
    /**
19
     * FileStore constructor.
20
     *
21
     * @param string|null $cacheDir
22
     * @param string      $cacheFile
23
     */
24 2
    public function __construct(string $cacheDir = null, string $cacheFile = self::DEFAULT_CACHE_FILE)
25
    {
26 2
        $cacheDir = $cacheDir ?? dirname(__DIR__, 2) . DIRECTORY_SEPARATOR . '.cache' . DIRECTORY_SEPARATOR;
27
28 2
        $this->setCacheDir($cacheDir);
29 2
        $this->setCacheFile($cacheFile);
30 2
    }
31
32
    /**
33
     * Set cache dir.
34
     *
35
     * @param string $path
36
     *
37
     * @return self
38
     */
39 1
    public function setCacheDir(string $path) : self
40
    {
41 1
        $this->cacheDir = $path;
42
43 1
        return $this;
44
    }
45
46
    /**
47
     * Get cache dir.
48
     *
49
     * @return string
50
     */
51 1
    public function getCacheDir() : string
52
    {
53 1
        return $this->cacheDir;
54
    }
55
56
    /**
57
     * Set cache file.
58
     *
59
     * @param string $file
60
     *
61
     * @return self
62
     */
63 1
    public function setCacheFile(string $file) : self
64
    {
65 1
        $this->cacheFile = $file;
66
67 1
        return $this;
68
    }
69
70
    /**
71
     * Get cache file.
72
     *
73
     * @return string
74
     */
75 5
    public function getCacheFile() : string
76
    {
77 5
        return $this->cacheDir . $this->cacheFile;
78
    }
79
80
    /**
81
     * Create cache dir if not exists.
82
     *
83
     * @return void
84
     */
85 2
    protected function createCacheDir()
86
    {
87 2
        if ( ! file_exists($this->cacheDir)) {
88 2
            mkdir($this->cacheDir);
89
        }
90 2
    }
91
92
    /**
93
     * Create cache file and add required meta.
94
     *
95
     * @return void
96
     */
97 2
    protected function createCacheFile()
98
    {
99 2
        $this->createCacheDir();
100
101 2
        $cacheFilePath = $this->getCacheFile();
102
103 2
        if ( ! file_exists($cacheFilePath)) {
104 2
            touch($cacheFilePath);
105
        }
106 2
    }
107
108
    /**
109
     * {@inheritDoc}
110
     */
111 8
    public function get(string $key, bool $withExpired = false)
112
    {
113 8
        $key      = $this->getActualCacheKey($key);
114 8
        $contents = $this->getCacheContents();
115
116 8
        if (empty($contents[$key])) {
117 3
            return null;
118
        }
119
120 5
        if ($withExpired) {
121 1
            return $contents[$key];
122
        }
123
124 5
        return $this->isValid($key) ? $contents[$key] : null;
125
    }
126
127
    /**
128
     * {@inheritDoc}
129
     */
130 8
    public function set(string $key, $value)
131
    {
132 8
        $key       = $this->getActualCacheKey($key);
133 8
        $cacheFile = $this->getCacheFile();
134
135 8
        if ( ! file_exists($cacheFile) || ! $this->isValid($key)) {
136 8
            $this->createCacheFile();
137
        }
138
139 8
        $contents = json_decode(file_get_contents($cacheFile), true) ?? [];
140
141 8
        if ( ! empty($contents[$key]) && is_array($value)) {
142 3
            $contents[$key] = $value + $contents[$key];
143
        } else {
144 8
            $contents[$key] = $value;
145
        }
146
147 8
        return file_put_contents($cacheFile, json_encode($contents));
148
    }
149
150
    /**
151
     * {@inheritDoc}
152
     */
153 1
    public function delete(string $key) : bool
154
    {
155 1
        $key      = $this->getActualCacheKey($key);
156 1
        $contents = $this->getCacheContents();
157
158 1
        if (isset($contents[$key])) {
159 1
            unset($contents[$key]);
160
161 1
            return false !== file_put_contents($this->getCacheFile(), json_encode($contents));
162
        }
163
164 1
        return false;
165
    }
166
167
    /**
168
     * {@inheritDoc}
169
     */
170 2
    public function keys() : array
171
    {
172 2
        $contents = $this->getCacheContents();
173
174 2
        if (is_array($contents)) {
175 1
            return array_keys($this->getCacheContents());
176
        }
177
178 1
        return [];
179
    }
180
181
    /**
182
     * Check if cache is still valid.
183
     *
184
     * @param string $key
185
     *
186
     * @return bool
187
     */
188 3
    public function isValid(string $key) : bool
189
    {
190 3
        $key  = $this->getActualCacheKey($key);
191 3
        $meta = $this->getCacheContents()[$key] ?? [];
192
193 3
        if (empty($meta['expires_at'])) {
194 1
            return false;
195
        }
196
197 2
        return Carbon::now() < Carbon::createFromFormat(self::RFC_7231, $meta['expires_at']);
198
    }
199
200
    /**
201
     * Get cache contents.
202
     *
203
     * @return array|bool
204
     */
205 3
    public function getCacheContents()
206
    {
207 3
        $cacheFile = $this->getCacheFile();
208
209 3
        if ( ! file_exists($cacheFile)) {
210 1
            return false;
211
        }
212
213 2
        return json_decode(file_get_contents($cacheFile), true) ?? [];
214
    }
215
216
    /**
217
     * Get actual cache key with prefix.
218
     *
219
     * @param string $key
220
     *
221
     * @return string
222
     */
223 1
    public function getActualCacheKey(string $key) : string
224
    {
225 1
        $prefix = $this->getPrefix();
226
227 1
        if (false === strpos($key, $prefix)) {
228 1
            $key = $prefix . $key;
229
        }
230
231 1
        return $key;
232
    }
233
}
234