Cache::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 6
nc 1
nop 2
dl 0
loc 8
rs 10
c 0
b 0
f 0
1
<?php /** @noinspection MoreThanThreeArgumentsInspection */
2
3
namespace mrcnpdlk\Lib\PfcAdapter;
4
5
6
use InvalidArgumentException;
7
use Phpfastcache\CacheManager;
8
use Phpfastcache\Core\Pool\ExtendedCacheItemPoolInterface;
9
use Psr\Log\LoggerInterface;
10
use Psr\Log\NullLogger;
11
12
/**
13
 * Class Cache
14
 *
15
 * @package mrcnpdlk\Lib\PfcAdapter
16
 */
17
class Cache
18
{
19
    /**
20
     * @var \Phpfastcache\Core\Pool\ExtendedCacheItemPoolInterface
21
     */
22
    private $oCache;
23
    /**
24
     * @var mixed
25
     */
26
    private $userData;
27
    /**
28
     * @var string
29
     */
30
    private $projectHash;
31
    /**
32
     * @var integer
33
     */
34
    private $defaultTtl;
35
    /**
36
     * Generate hash with project hash
37
     *
38
     * @var boolean
39
     */
40
    private $uniqueHash;
41
    /**
42
     * @var LoggerInterface
43
     */
44
    private $logger;
45
    /**
46
     * @var boolean
47
     */
48
    private $isEnabled;
49
50
    /**
51
     * Cache constructor.
52
     *
53
     * @param \Phpfastcache\Core\Pool\ExtendedCacheItemPoolInterface|null $oCache
54
     * @param bool                                                        $uniqueHash
55
     */
56
    public function __construct(ExtendedCacheItemPoolInterface $oCache = null, bool $uniqueHash = true)
57
    {
58
        $this->oCache      = $oCache ?? CacheManager::Redis();
59
        $this->projectHash = md5(__DIR__);
60
        $this->defaultTtl  = $this->oCache->getConfig()->getDefaultTtl();
61
        $this->uniqueHash  = $uniqueHash;
62
        $this->logger      = new NullLogger();
63
        $this->isEnabled   = true;
64
    }
65
66
    /**
67
     * @return $this
68
     * @throws \InvalidArgumentException
69
     */
70
    public function clearAllCache(): self
71
    {
72
        $this->oCache->deleteItemsByTag($this->projectHash);
73
74
        return $this;
75
    }
76
77
    /**
78
     * @param string|string[] $tTags
79
     *
80
     * @return $this
81
     * @throws \InvalidArgumentException
82
     */
83
    public function clearCache($tTags): self
84
    {
85
        $tTags = (array)$tTags;
86
        $this->oCache->deleteItemsByTags($tTags);
87
88
        return $this;
89
    }
90
91
    /**
92
     * @param array $tHashKeys
93
     *
94
     * @return string
95
     */
96
    public function genHash(array $tHashKeys): string
97
    {
98
        if ($this->uniqueHash) {
99
            return md5(json_encode(array_merge($tHashKeys, [$this->projectHash])));
100
        }
101
102
        return md5(json_encode($tHashKeys));
103
    }
104
105
    /**
106
     * @return mixed
107
     */
108
    public function get()
109
    {
110
        return $this->userData;
111
    }
112
113
    /**
114
     * @return ExtendedCacheItemPoolInterface
115
     */
116
    public function getHandler(): ExtendedCacheItemPoolInterface
117
    {
118
        return $this->oCache;
119
    }
120
121
    /**
122
     * @param callable        $inputDataFunction Callback function using when invalid cache
123
     * @param string|string[] $tHashKeys
124
     * @param string|string[] $tRedisTags
125
     * @param int|null        $iCache            Cache validity in seconds
126
     *
127
     * @return $this
128
     */
129
    public function set(
130
        callable $inputDataFunction,
131
        $tHashKeys,
132
        $tRedisTags,
133
        int $iCache = null
134
    ): self {
135
        try {
136
            if ($tHashKeys === [] || $tHashKeys === null || (\is_string($tHashKeys) && trim($tHashKeys) === '')) {
137
                throw new InvalidArgumentException('HashKey is required!', 1);
138
            }
139
140
            $tRedisTags = (array)$tRedisTags;
141
            $tHashKeys  = (array)$tHashKeys;
142
            $iCache     = $iCache ?? $this->defaultTtl;
143
144
            $hashKey = $this->genHash($tHashKeys);
145
146
            if ($this->isEnabled === false) {
147
                $this->logger->debug(sprintf('CACHE [%s]: cache omitted [not enabled]', $hashKey));
148
                $this->userData = $inputDataFunction();
149
            } elseif ($iCache > 0) {
150
                $oCachedItem = $this->oCache->getItem($hashKey);
151
                //do każdego zapytania dajemy TAG związany z projektem
152
                $tRedisTags = array_unique(array_merge([$this->projectHash], $tRedisTags));
153
154
                if (!$oCachedItem->isHit() || $oCachedItem->get() === null) {
155
                    $this->logger->debug(sprintf('CACHE [%s]: old or NULL, reset [ttl=%s]', $hashKey, $iCache));
156
                    $this->userData = $inputDataFunction();
157
                    $oCachedItem
158
                        ->set($this->userData)
159
                        ->setTags($tRedisTags)
160
                        ->expiresAfter($iCache)
161
                    ;
162
                    $this->oCache->save($oCachedItem);
163
                } else {
164
                    $this->logger->debug(sprintf('CACHE [%s]: getting from cache', $hashKey));
165
                    $this->userData = $oCachedItem->get();
166
                }
167
            } else {
168
                $this->logger->debug(sprintf('CACHE [%s]: cache omitted [ttl=0]', $hashKey));
169
                $this->userData = $inputDataFunction();
170
            }
171
172
            return $this;
173
        } catch (\Exception $e) {
174
            $this->logger->warning(sprintf('CACHE Error: %s. Using fallback function.', $e->getMessage()));
175
            $this->userData = $inputDataFunction();
176
177
            return $this;
178
        }
179
    }
180
181
    /**
182
     * @param bool $isEnabled
183
     *
184
     * @return $this
185
     */
186
    public function setEnabled(bool $isEnabled = true): self
187
    {
188
        $this->isEnabled = $isEnabled;
189
190
        return $this;
191
    }
192
193
    /**
194
     * @param \Psr\Log\LoggerInterface $oLogger
195
     *
196
     * @return $this
197
     */
198
    public function setLogger(LoggerInterface $oLogger): self
199
    {
200
        $this->logger = $oLogger;
201
202
        return $this;
203
    }
204
}
205