Memcached::verifyReturnCode()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 5
c 1
b 0
f 0
dl 0
loc 10
ccs 0
cts 6
cp 0
rs 10
cc 2
nc 2
nop 1
crap 6
1
<?php
2
3
namespace WebStream\Cache\Driver;
4
5
use WebStream\Container\Container;
0 ignored issues
show
Bug introduced by
The type WebStream\Container\Container was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
6
use WebStream\DI\Injector;
0 ignored issues
show
Bug introduced by
The type WebStream\DI\Injector was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
7
8
/**
9
 * Memcached
10
 * @author Ryuichi Tanaka
11
 * @since 2015/07/08
12
 * @version 0.7
13
 */
14
class Memcached implements ICache
15
{
16
    use Injector;
17
18
    /**
19
     * @var Container キャッシュ依存コンテナ
20
     */
21
    private Container $cacheContainer;
22
23
    /**
24
     * @var string キャッシュ接頭辞
25
     */
26
    private string $cachePrefix;
27
28
    /**
29
     * {@inheritdoc}
30
     */
31
    public function __construct(Container $cacheContainer)
32
    {
33
        $this->cacheContainer = $cacheContainer;
34
        $this->cachePrefix = $this->cacheContainer->cachePrefix . '.' . $this->cacheContainer->classPrefix . '.';
35
    }
36
37
    /**
38
     * {@inheritdoc}
39
     */
40
    public function add($key, $value, $ttl = 0, $overwrite = false): bool
41
    {
42
        if (!$this->isAvailableCacheLibrary()) {
43
            return false;
44
        }
45
        $key = $this->cachePrefix . $key;
46
        $result = null;
47
48
        if ($ttl > 0) {
49
            if ($overwrite) {
50
                $result = $this->cacheContainer->driver->replace($key, $value, $ttl);
51
                if ($result === false) {
52
                    $result = $this->cacheContainer->driver->set($key, $value, $ttl);
53
                }
54
            } else {
55
                $result = $this->cacheContainer->driver->set($key, $value, $ttl);
56
            }
57
        } else {
58
            if ($overwrite) {
59
                $result = $this->cacheContainer->driver->replace($key, $value);
60
                if ($result === false) {
61
                    $result = $this->cacheContainer->driver->set($key, $value);
62
                }
63
            } else {
64
                $result = $this->cacheContainer->driver->set($key, $value);
65
            }
66
        }
67
68
        $this->logger->info("Execute cache save: " . $key);
69
        $this->verifyReturnCode($this->cacheContainer->codes['success']);
70
71
        return $result;
72
    }
73
74
    /**
75
     * {@inheritdoc}
76
     */
77
    public function get($key)
78
    {
79
        if (!$this->isAvailableCacheLibrary()) {
80
            return false;
81
        }
82
        $key = $this->cachePrefix . $key;
83
        $result = $this->cacheContainer->driver->get($key);
84
85
        if ($result !== false) {
86
            $this->logger->info("Execute cache read: " . $key);
87
        } else {
88
            $this->logger->warn("Failed to read cache: " . $key);
89
        }
90
91
        return $this->verifyReturnCode($this->cacheContainer->codes['success']) ? $result : null;
92
    }
93
94
    /**
95
     * {@inheritdoc}
96
     */
97
    public function delete($key): bool
98
    {
99
        if (!$this->isAvailableCacheLibrary()) {
100
            return false;
101
        }
102
        $key = $this->cachePrefix . $key;
103
        $this->cacheContainer->driver->delete($key);
104
105
        if ($this->verifyReturnCode($this->cacheContainer->codes['notfound'])) {
106
            $this->logger->info("Execute cache cleared: " . $key);
107
            return true;
108
        } else {
109
            $this->logger->warn("Failed to clear cache: " . $key);
110
            return false;
111
        }
112
    }
113
114
    /**
115
     * {@inheritdoc}
116
     */
117
    public function clear(): bool
118
    {
119
        if (!$this->isAvailableCacheLibrary()) {
120
            return false;
121
        }
122
        $allKeys = $this->cacheContainer->driver->getAllKeys();
123
        if ($allKeys === false) {
124
            $this->logger->warn("Can't get cache keys: " . $this->cachePrefix . "*");
125
            $this->cacheContainer->driver->flush();
126
127
            return true;
128
        }
129
130
        $prefixLength = strlen($this->cachePrefix);
131
        $targetKeys = [];
132
        foreach ($allKeys as $key) {
133
            if (substr($key, 0, $prefixLength)) {
134
                $targetKeys[] = $key;
135
            }
136
        }
137
138
        $this->cacheContainer->driver->deleteMulti($targetKeys);
139
140
        if ($this->verifyReturnCode($this->cacheContainer->codes['notfound'])) {
141
            $this->logger->info("Execute all cache cleared: " . $this->cachePrefix . "*");
142
            return true;
143
        } else {
144
            $this->logger->warn("Failed to clear all cache: " . $this->cachePrefix . "*");
145
            return false;
146
        }
147
    }
148
149
    /**
150
     * リターンコードを検証する
151
     * @param int $code 想定コード
152
     * @return bool 検証結果
153
     */
154
    private function verifyReturnCode(int $code): bool
155
    {
156
        if ($code !== $this->cacheContainer->driver->getResultCode()) {
157
            $message = $this->cacheContainer->driver->getResultMessage();
158
            $this->logger->warn("Error $code interacting with memcached: $message");
159
160
            return false;
161
        }
162
163
        return true;
164
    }
165
166
    /**
167
     * キャッシュライブラリが使用可能か検査する
168
     * @return bool 使用可能でtrue
169
     */
170
    private function isAvailableCacheLibrary(): bool
171
    {
172
        if ($this->cacheContainer->available) {
173
            return true;
174
        }
175
176
        $this->logger->warn("Memcached cache library is unavailable.");
177
178
        return false;
179
    }
180
}
181