Memcached::__construct()   A
last analyzed

Complexity

Conditions 4
Paths 3

Size

Total Lines 18
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 4.0961

Importance

Changes 0
Metric Value
eloc 10
dl 0
loc 18
ccs 9
cts 11
cp 0.8182
rs 9.9332
c 0
b 0
f 0
cc 4
nc 3
nop 1
crap 4.0961
1
<?php namespace Comodojo\Cache\Drivers;
2
3
use \Comodojo\Cache\Traits\InstanceTrait;
4
use \Comodojo\Foundation\Utils\UniqueId;
5
use \Memcached as MemcachedInstance;
6
use \Exception;
7
8
/**
9
 * @package     Comodojo Spare Parts
10
 * @author      Marco Giovinazzi <[email protected]>
11
 * @license     MIT
12
 *
13
 * LICENSE:
14
 *
15
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
 * THE SOFTWARE.
22
 */
23
24
class Memcached extends AbstractDriver {
25
26
    use InstanceTrait;
27
28
    const DRIVER_NAME = "memcached";
29
30
    /**
31
     * {@inheritdoc}
32
     */
33 47
    public function __construct(array $configuration = []) {
34
35 47
        if ( class_exists('Memcached') === false ) throw new Exception("ext-memcached not available");
36
37 47
        $instance = new MemcachedInstance($configuration['persistent_id']);
38
39 47
        $instance->addServer(
40 47
            $configuration['server'],
41 47
            $configuration['port'],
42 47
            $configuration['weight']
43
        );
44
45 47
        if ( !empty($configuration['username']) && !empty($configuration['password']) ) {
46
            $instance->setOption(MemcachedInstance::OPT_BINARY_PROTOCOL, true);
47
            $instance->setSaslAuthData($configuration['username'], $configuration['password']);
0 ignored issues
show
Bug introduced by
The method setSaslAuthData() does not exist on Memcached. ( Ignorable by Annotation )

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

47
            $instance->/** @scrutinizer ignore-call */ 
48
                       setSaslAuthData($configuration['username'], $configuration['password']);

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...
48
        }
49
50 47
        $this->setInstance($instance);
51
52 47
    }
53
54
    /**
55
     * {@inheritdoc}
56
     */
57 47
    public function test() {
58
59 47
        return sizeof($this->getInstance()->getServerList()) > 0 && $this->ping();
60
61
    }
62
63 47
    public function ping() {
64
65
        // try to read a fake value from cache and check it's return code
66 47
        $instance = $this->getInstance();
67 47
        $instance->get('cache-internals');
68 47
        $code = $instance->getResultCode();
69
70
        // check if code represents a failure
71
        // $code != [MEMCACHED_SUCCESS, MEMCACHED_NOTFOUND]
72 47
        return in_array($code, [0, 16]);
73
74
    }
75
76
    /**
77
     * {@inheritdoc}
78
     */
79 35
    public function get($key, $namespace) {
80
81 35
        $scope = $this->getNamespaceKey($namespace);
82
83 35
        if ( $scope === false ) return null;
0 ignored issues
show
introduced by
The condition $scope === false is always false.
Loading history...
84
85 27
        $shadowName = "$scope-$key";
86
87 27
        $instance = $this->getInstance();
88
89 27
        $item = $instance->get($shadowName);
90
91 27
        return $instance->getResultCode() == MemcachedInstance::RES_NOTFOUND ? null : $item;
92
93
    }
94
95
    /**
96
     * {@inheritdoc}
97
     */
98 27
    public function set($key, $namespace, $value, $ttl = null) {
99
100 27
        if ( $ttl == null ) $ttl = 0;
101
102 27
        $scope = $this->getNamespaceKey($namespace);
103
104 27
        if ( $scope === false ) $scope = $this->setNamespaceKey($namespace);
0 ignored issues
show
introduced by
The condition $scope === false is always false.
Loading history...
105
106 27
        if ( $scope === false ) return false;
0 ignored issues
show
introduced by
The condition $scope === false is always false.
Loading history...
107
108 27
        $shadowName = "$scope-$key";
109
110 27
        return $this->getInstance()->set($shadowName, $value, $ttl);
111
112
    }
113
114
    /**
115
     * {@inheritdoc}
116
     */
117 3
    public function delete($key, $namespace) {
118
119 3
        $scope = $this->getNamespaceKey($namespace);
120
121 3
        if ( $scope === false ) return false;
0 ignored issues
show
introduced by
The condition $scope === false is always false.
Loading history...
122
123 3
        $shadowName = "$scope-$key";
124
125 3
        return $this->getInstance()->delete($shadowName);
126
127
    }
128
129
    /**
130
     * {@inheritdoc}
131
     */
132 11
    public function clear($namespace = null) {
133
134 11
        if ( $namespace == null ) {
135
136 9
            return $this->getInstance()->flush();
137
138
        } else {
139
140 2
            $scope = $this->getNamespaceKey($namespace);
141
142 2
            if ( $scope === false ) return false;
0 ignored issues
show
introduced by
The condition $scope === false is always false.
Loading history...
143
144 2
            return $this->getInstance()->delete($namespace);
145
146
        }
147
148
    }
149
150
    /**
151
     * {@inheritdoc}
152
     */
153 2
    public function getMultiple(array $keys, $namespace) {
154
155 2
        if ( empty($keys) ) return [];
156
157 2
        $keypad = array_combine($keys, array_fill(0, count($keys), null));
158
159 2
        $scope = $this->getNamespaceKey($namespace);
160
161 2
        if ( $scope === false ) return $keypad;
0 ignored issues
show
introduced by
The condition $scope === false is always false.
Loading history...
162
163 2
        $keyscope = array_map(function($key) use($scope) {
164 2
            return "$scope-$key";
165 2
        }, $keys);
166
167 2
        if ( version_compare(phpversion(), '7.0.0', '<') ) {
168
            $data = $this->getInstance()->getMulti($keyscope, $null = null, MemcachedInstance::GET_PRESERVE_ORDER);
169
        } else {
170 2
            $data = $this->getInstance()->getMulti($keyscope, MemcachedInstance::GET_PRESERVE_ORDER);
171
        }
172
173 2
        $return = [];
174
175 2
        foreach ( $data as $scoped_key => $value ) {
176 2
            $key = substr($scoped_key, strlen("$scope-"));
177 2
            $return[$key] = $value;
178
        }
179
180 2
        return array_replace($keypad, $return);
181
182
    }
183
184
    /**
185
     * {@inheritdoc}
186
     */
187 1
    public function setMultiple(array $key_values, $namespace, $ttl = null) {
188
189 1
        if ( $ttl == null ) $ttl = 0;
190
191 1
        $scope = $this->getNamespaceKey($namespace);
192
193 1
        if ( $scope === false ) $scope = $this->setNamespaceKey($namespace);
0 ignored issues
show
introduced by
The condition $scope === false is always false.
Loading history...
194
195 1
        if ( $scope === false ) return false;
0 ignored issues
show
introduced by
The condition $scope === false is always false.
Loading history...
196
197 1
        $shadowNames = [];
198
199 1
        foreach ( $key_values as $key => $value ) {
200 1
            $shadowNames["$scope-$key"] = $value;
201
        }
202
203 1
        return $this->getInstance()->setMulti($shadowNames, $ttl);
204
205
    }
206
207
    /**
208
     * {@inheritdoc}
209
     */
210 3
    public function deleteMultiple(array $keys, $namespace) {
211
212 3
        $scope = $this->getNamespaceKey($namespace);
213
214 3
        if ( $scope === false ) return false;
0 ignored issues
show
introduced by
The condition $scope === false is always false.
Loading history...
215
216 3
        $shadowNames = array_map(function($key) use($scope) {
217 3
            return "$scope-$key";
218 3
        }, $keys);
219
220 3
        $delete = $this->getInstance()->deleteMulti($shadowNames);
221
222 3
        return count(array_diff(array_unique($delete), [true])) === 0;
223
224
    }
225
226
    /**
227
     * {@inheritdoc}
228
     */
229 5
    public function has($key, $namespace) {
230
231 5
        return $this->get($key, $namespace) === null ? false : true;
232
233
    }
234
235
    /**
236
     * {@inheritdoc}
237
     */
238 2
    public function stats() {
239
240 2
        return $this->getInstance()->getStats();
241
242
    }
243
244
    /**
245
     * Set namespace key
246
     *
247
     * @return  mixed
248
     */
249 5
    private function setNamespaceKey($namespace) {
250
251 5
        $uId = UniqueId::generate(64);
252
253 5
        return $this->getInstance()->set($namespace, $uId, 0) === false ? false : $uId;
254
255
    }
256
257
    /**
258
     * Get namespace key
259
     *
260
     * @return  string
261
     */
262 37
    private function getNamespaceKey($namespace) {
263
264 37
        return $this->getInstance()->get($namespace);
265
266
    }
267
268
}
269