Passed
Push — master ( 9ec6c5...85fa92 )
by y
02:17
created

FileCache::setGzEncoding()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Helix\Asana\Api;
4
5
use DateInterval;
6
use DateTime;
7
use Psr\SimpleCache\CacheInterface;
8
9
/**
10
 * A bare bones PSR-16 "compliant" file-based cache for {@see SimpleCache}.
11
 *
12
 * Use this if you don't have a better cache.
13
 *
14
 * This is not safe for concurrency.
15
 */
16
final class FileCache implements CacheInterface {
17
18
    /**
19
     * @var string
20
     */
21
    private $dir;
22
23
    /**
24
     * @var bool
25
     */
26
    private $gzEncoding = false;
27
28
    /**
29
     * @var LoggerInterface
30
     */
31
    private $logger;
32
33
    public function __construct (string $dir) {
34
        $this->dir = $dir;
35
    }
36
37
    private function _path ($key) {
38
        $file = "{$this->dir}/{$key}~";
39
        clearstatcache(true, $file);
40
        return $file;
41
    }
42
43
    public function clear () {
44
        // unused. just delete the dir.
45
    }
46
47
    public function delete ($key) {
48
        $path = $this->_path($key);
49
        if (file_exists($path)) {
50
            $this->log('CACHE DELETE', $key);
51
            unlink($path);
52
        }
53
    }
54
55
    public function deleteMultiple ($keys) {
56
        // unused
57
    }
58
59
    public function get ($key, $default = null) {
60
        $path = $this->_path($key);
61
        if (file_exists($path)) {
62
            if (filemtime($path) > time()) {
63
                $this->log('CACHE HIT', $key);
64
                return unserialize($this->gzEncoding ? gzdecode(file_get_contents($path)) : file_get_contents($path));
65
            }
66
            $this->log('CACHE EXPIRE', $key);
67
            unlink($path);
68
        }
69
        else {
70
            $this->log('CACHE MISS', $key);
71
        }
72
        return $default;
73
    }
74
75
    /**
76
     * @return LoggerInterface
77
     */
78
    public function getLogger () {
79
        return $this->logger;
80
    }
81
82
    public function getMultiple ($keys, $default = null) {
83
        // unused
84
    }
85
86
    public function has ($key) {
87
        // unused
88
    }
89
90
    /**
91
     * @return bool
92
     */
93
    public function isGzEncoding (): bool {
94
        return $this->gzEncoding;
95
    }
96
97
    private function log (string $msg, string $key): void {
98
        if ($this->logger) {
99
            $this->logger->log($msg, $key);
100
        }
101
    }
102
103
    public function set ($key, $value, $ttl = null) {
104
        assert($ttl instanceof DateInterval);
105
        $this->log('CACHE SET', $key);
106
        $path = $this->_path($key);
107
        if (!is_dir(dirname($path))) {
108
            mkdir(dirname($path), 0770, true);
109
        }
110
        // if a gid ref is being stashed, make a symlink for quality of life.
111
        if (is_scalar($value)) {
112
            $link = substr($path, 0, -1) . '.ref';
113
            $real = $this->_path("asana/{$value}");
114
            if (!is_link($link)) {
115
                symlink($real, $link);
116
            }
117
        }
118
        file_put_contents($path, $this->gzEncoding ? gzencode(serialize($value)) : serialize($value));
119
        chmod($path, 0660);
120
        touch($path, (new DateTime())->add($ttl)->getTimeStamp());
121
    }
122
123
    /**
124
     * @param bool $gzEncoding
125
     * @return $this
126
     */
127
    public function setGzEncoding (bool $gzEncoding) {
128
        $this->gzEncoding = $gzEncoding;
129
        return $this;
130
    }
131
132
    /**
133
     * @param null|LoggerInterface $logger
134
     * @return $this
135
     */
136
    public function setLogger (?LoggerInterface $logger) {
137
        $this->logger = $logger;
138
        return $this;
139
    }
140
141
    public function setMultiple ($values, $ttl = null) {
142
        // unused
143
    }
144
}