Completed
Push — develop ( 32d851...a318ff )
by Michele
87:15 queued 85:13
created

ZanzaraCache::appendCacheUserData()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 3
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Zanzara;
4
5
use React\Cache\CacheInterface;
6
use React\Promise\PromiseInterface;
7
8
/**
9
 * @method get($key, $default = null)
10
 * @method set($key, $value, $ttl = null)
11
 * @method delete($key)
12
 * @method setMultiple(array $values, $ttl = null)
13
 * @method deleteMultiple(array $keys)
14
 * @method clear()
15
 * @method has($key)
16
 */
17
class ZanzaraCache
18
{
19
    /**
20
     * @var CacheInterface|null
21
     */
22
    private $cache;
23
24
    /**
25
     * @var ZanzaraLogger
26
     */
27
    private $logger;
28
29
    private const CONVERSATION = "CONVERSATION";
30
31
    private const CHATDATA = " CHATDATA";
32
33
    private const USERDATA = "USERDATA";
34
35
    private const GLOBALDATA = "GLOBALDATA";
36
37
    /**
38
     * ZanzaraLogger constructor.
39
     * @param CacheInterface|null $cache
40
     * @param ZanzaraLogger $logger
41
     */
42
    public function __construct(?CacheInterface $cache, ZanzaraLogger $logger)
43
    {
44
        $this->logger = $logger;
45
        $this->cache = $cache;
46
    }
47
48
    public function getGlobalCacheData()
49
    {
50
        $cacheKey = self::GLOBALDATA;
51
        return $this->doGet($cacheKey);
52
    }
53
54
    public function setGlobalCacheData(string $key, $data)
55
    {
56
        $cacheKey = self::GLOBALDATA;
57
        return $this->doSet($cacheKey, $key, $data);
58
    }
59
60
    public function appendGlobalCacheData(string $key, $data)
61
    {
62
        $cacheKey = self::GLOBALDATA;
63
        return $this->appendCacheData($cacheKey, $key, $data);
64
    }
65
66
    public function getCacheGlobalDataItem(string $key)
67
    {
68
        $cacheKey = self::GLOBALDATA;
69
        return $this->getCacheItem($cacheKey, $key);
70
    }
71
72
    public function deleteCacheGlobalData()
73
    {
74
        $cacheKey = self::GLOBALDATA;
75
        return $this->deleteCache([$cacheKey]);
76
    }
77
78
    public function deleteCacheItemGlobalData(string $key)
79
    {
80
        $cacheKey = self::GLOBALDATA;
81
        return $this->deleteCacheItem($cacheKey, $key);
82
    }
83
84
    /**
85
     * Get the correct key value for chatId data stored in cache
86
     * @param $chatId
87
     * @return string
88
     */
89
    private function getChatIdKey(int $chatId)
90
    {
91
        return ZanzaraCache::CHATDATA . strval($chatId);
92
    }
93
94
    public function getCacheChatData(int $chatId)
95
    {
96
        $cacheKey = $this->getChatIdKey($chatId);
97
        return $this->doGet($cacheKey);
98
    }
99
100
    public function getCacheChatDataItem(int $chatId, string $key)
101
    {
102
        $cacheKey = $this->getChatIdKey($chatId);
103
        return $this->getCacheItem($cacheKey, $key);
104
    }
105
106
    public function setCacheChatData(int $chatId, string $key, $data)
107
    {
108
        $cacheKey = $this->getChatIdKey($chatId);
109
        return $this->doSet($cacheKey, $key, $data);
110
    }
111
112
    public function appendCacheChatData(int $chatId, string $key, $data)
113
    {
114
        $cacheKey = $this->getChatIdKey($chatId);
115
        return $this->appendCacheData($cacheKey, $key, $data);
116
    }
117
118
    public function deleteAllCacheChatData(int $chatId)
119
    {
120
        $cacheKey = $this->getChatIdKey($chatId);
121
        return $this->deleteCache([$cacheKey]);
122
    }
123
124
    public function deleteCacheChatDataItem(int $chatId, string $key)
125
    {
126
        $cacheKey = $this->getChatIdKey($chatId);
127
        return $this->deleteCacheItem($cacheKey, $key);
128
    }
129
130
    /**
131
     * Get the correct key value for userId data stored in cache
132
     * @param $userId
133
     * @return string
134
     */
135
    private function getUserIdKey(int $userId)
136
    {
137
        return ZanzaraCache::USERDATA . strval($userId);
138
    }
139
140
    public function getCacheUserData(int $userId)
141
    {
142
        $cacheKey = $this->getUserIdKey($userId);
143
        return $this->doGet($cacheKey);
144
    }
145
146
    public function getCacheUserDataItem(int $userId, string $key)
147
    {
148
        $cacheKey = $this->getUserIdKey($userId);
149
        return $this->getCacheItem($cacheKey, $key);
150
    }
151
152
    public function setCacheUserData(int $userId, string $key, $data)
153
    {
154
        $cacheKey = $this->getUserIdKey($userId);
155
        return $this->doSet($cacheKey, $key, $data);
156
    }
157
158
    public function appendCacheUserData(int $userId, string $key, $data)
159
    {
160
        $cacheKey = $this->getUserIdKey($userId);
161
        return $this->appendCacheData($cacheKey, $key, $data);
162
    }
163
164
    public function deleteAllCacheUserData(int $userId)
165
    {
166
        $cacheKey = $this->getUserIdKey($userId);
167
        return $this->deleteCache([$cacheKey]);
168
    }
169
170
    public function deleteCacheItemUserData(int $userId, string $key)
171
    {
172
        $cacheKey = $this->getUserIdKey($userId);
173
        return $this->deleteCacheItem($cacheKey, $key);
174
    }
175
176
    /**
177
     * Get key of the conversation by chatId
178
     * @param $chatId
179
     * @return string
180
     */
181
    private function getConversationKey(int $chatId)
182
    {
183
        return ZanzaraCache::CONVERSATION . strval($chatId);
184
    }
185
186
    public function setConversationHandler(int $chatId, $data)
187
    {
188
        $key = "state";
189
        $cacheKey = $this->getConversationKey($chatId);
190
        return $this->doSet($cacheKey, $key, $data);
191
    }
192
193
    /**
194
     * delete a cache iteam and return the promise
195
     * @param $chatId
196
     * @return PromiseInterface
197
     */
198
    public function deleteConversationCache(int $chatId)
199
    {
200
        return $this->deleteCache([$this->getConversationKey($chatId)]);
201
    }
202
203
    /**
204
     * Use only to call native method of CacheInterface
205
     * @param $name
206
     * @param $arguments
207
     * @return PromiseInterface
208
     */
209
    public function __call($name, $arguments): ?PromiseInterface
210
    {
211
        return call_user_func_array([$this->cache, $name], $arguments);
212
    }
213
214
    /**
215
     * Delete a key inside array stored in cacheKey
216
     * @param $cacheKey
217
     * @param $key
218
     * @return PromiseInterface
219
     */
220
    public function deleteCacheItem(string $cacheKey, $key)
221
    {
222
        return $this->cache->get($cacheKey)->then(function ($arrayData) use ($cacheKey, $key) {
0 ignored issues
show
Bug introduced by
The method get() does not exist on null. ( Ignorable by Annotation )

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

222
        return $this->cache->/** @scrutinizer ignore-call */ get($cacheKey)->then(function ($arrayData) use ($cacheKey, $key) {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
223
            if (!$arrayData) {
224
                return true; //there isn't anything so it's deleted
225
            } else {
226
                unset($arrayData[$key]);
227
            }
228
229
            return $this->cache->set($cacheKey, $arrayData)->then(function ($result) {
230
                if ($result !== true) {
231
                    $this->logger->errorWriteCache($result);
232
                }
233
                return $result;
234
            });
235
        });
236
    }
237
238
    /**
239
     * delete a cache iteam and return the promise
240
     * @param array $keys
241
     * @return PromiseInterface
242
     */
243
    public function deleteCache(array $keys)
244
    {
245
        return $this->cache->deleteMultiple($keys)->then(function ($result) {
246
            if ($result !== true) {
247
                $this->logger->errorClearCache($result);
248
            }
249
            return $result;
250
        });
251
    }
252
253
    /**
254
     * Get cache item inside array stored in cacheKey
255
     * @param $cacheKey
256
     * @param $key
257
     * @return PromiseInterface
258
     */
259
    public function getCacheItem(string $cacheKey, $key)
260
    {
261
        return $this->cache->get($cacheKey)->then(function ($arrayData) use ($key) {
262
            if ($arrayData && array_key_exists($key, $arrayData)) {
263
                return $arrayData[$key];
264
            } else {
265
                return null;
266
            }
267
        });
268
    }
269
270
    public function doGet(string $cacheKey)
271
    {
272
        return $this->cache->get($cacheKey);
273
    }
274
275
    /**
276
     * Wipe entire cache.
277
     * @return PromiseInterface
278
     */
279
    public function wipeCache()
280
    {
281
        return $this->cache->clear();
282
    }
283
284
    /**
285
     * set a cache value and return the promise
286
     * @param $cacheKey
287
     * @param $key
288
     * @param $data
289
     * @return PromiseInterface
290
     */
291
    public function doSet(string $cacheKey, string $key, $data)
292
    {
293
        return $this->cache->get($cacheKey)->then(function ($arrayData) use ($key, $data, $cacheKey) {
294
            if (!$arrayData) {
295
                $arrayData = array();
296
                $arrayData[$key] = $data;
297
            } else {
298
                $arrayData[$key] = $data;
299
            }
300
301
            return $this->cache->set($cacheKey, $arrayData)->then(function ($result) {
302
                if ($result !== true) {
303
                    $this->logger->errorWriteCache($result);
304
                }
305
                return $result;
306
            });
307
        });
308
    }
309
310
    /**
311
     * Append data to an existing cache item. The item value is always an array.
312
     *
313
     * @param string $cacheKey
314
     * @param string $key
315
     * @param $data
316
     * @return PromiseInterface
317
     */
318
    public function appendCacheData(string $cacheKey, string $key, $data)
319
    {
320
        return $this->cache->get($cacheKey)->then(function ($arrayData) use ($key, $data, $cacheKey) {
321
            $arrayData[$key][] = $data;
322
323
            return $this->cache->set($cacheKey, $arrayData)->then(function ($result) {
324
                if ($result !== true) {
325
                    $this->logger->errorWriteCache($result);
326
                }
327
                return $result;
328
            });
329
        });
330
    }
331
332
    /**
333
     * Used by ListenerResolver to call the correct handler stored inside cache
334
     * @param $chatId
335
     * @param $update
336
     * @param $container
337
     * @return PromiseInterface
338
     */
339
    public function callHandlerByChatId(int $chatId, $update, $container)
340
    {
341
        return $this->cache->get($this->getConversationKey($chatId))->then(function (array $conversation) use ($update, $chatId, $container) {
0 ignored issues
show
Unused Code introduced by
The import $chatId is not used and could be removed.

This check looks for imports that have been defined, but are not used in the scope.

Loading history...
342
            if (!empty($conversation)) {
343
                $handler = $conversation["state"];
344
                $handler(new Context($update, $container));
345
            }
346
        }, function ($err) use ($container, $update) {
0 ignored issues
show
Unused Code introduced by
The import $container is not used and could be removed.

This check looks for imports that have been defined, but are not used in the scope.

Loading history...
347
            $this->logger->errorUpdate($update, $err);
348
        })->otherwise(function ($err, $update, $chatId) {
0 ignored issues
show
Bug introduced by
The method otherwise() does not exist on React\Promise\PromiseInterface. It seems like you code against a sub-type of said class. However, the method does not exist in Zanzara\Test\PromiseWrapper\ZanzaraPromise or React\Promise\CancellablePromiseInterface. Are you sure you never get one of those? ( Ignorable by Annotation )

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

348
        })->/** @scrutinizer ignore-call */ otherwise(function ($err, $update, $chatId) {
Loading history...
349
            $this->logger->errorUpdate($err, $update);
350
            $this->deleteConversationCache($chatId);
351
        });
352
    }
353
354
}