Couchbase   C
last analyzed

Complexity

Total Complexity 78

Size/Duplication

Total Lines 686
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 7

Test Coverage

Coverage 91.08%

Importance

Changes 65
Bugs 23 Features 24
Metric Value
wmc 78
c 65
b 23
f 24
lcom 2
cbo 7
dl 0
loc 686
ccs 245
cts 269
cp 0.9108
rs 5.0693

26 Methods

Rating   Name   Duplication   Size   Complexity  
A flush() 0 6 1
A __construct() 0 16 4
A internalSetItem() 0 17 3
A getCouchbaseResource() 0 23 3
A getOptions() 0 8 2
A setOptions() 0 8 2
A expirationTime() 0 9 2
A internalAddItem() 0 15 3
A internalAddItems() 0 16 2
A namespacesKeyValuePairs() 0 11 2
A filterErrors() 0 12 3
A removeNamespacePrefix() 0 9 4
A internalSetItems() 0 10 1
A internalRemoveItem() 0 13 2
A internalRemoveItems() 0 16 2
A namespacesKeys() 0 6 2
A internalGetItem() 0 21 3
A internalReplaceItem() 0 14 2
A internalHasItem() 0 17 3
B internalHasItems() 0 25 5
D internalGetItems() 0 33 9
A internalIncrementItem() 0 21 4
A internalCheckAndSetItem() 0 21 4
A internalTouchItem() 0 17 4
B internalDecrementItem() 0 22 4
B internalGetCapabilities() 0 33 2

How to fix   Complexity   

Complex Class

Complex classes like Couchbase often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Couchbase, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * zf-couchbase2.
4
 *
5
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
6
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
7
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
8
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
9
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
10
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
11
 * SOFTWARE.
12
 *
13
 * @copyright 2015 MehrAlsNix (http://www.mehralsnix.de)
14
 * @license   http://www.opensource.org/licenses/mit-license.php MIT
15
 *
16
 * @link      http://github.com/MehrAlsNix/zf-couchbase2
17
 */
18
namespace MehrAlsNix\ZF\Cache\Storage\Adapter;
19
20
use Zend\Cache\Exception;
21
use Zend\Cache\Storage\Adapter\AbstractAdapter;
22
use Zend\Cache\Storage\Capabilities;
23
use Zend\Cache\Storage\FlushableInterface;
24
25
/**
26
 * Class Couchbase.
27
 */
28
class Couchbase extends AbstractAdapter implements FlushableInterface
0 ignored issues
show
Complexity introduced by
The class Couchbase has a coupling between objects value of 14. Consider to reduce the number of dependencies under 13.
Loading history...
Complexity introduced by
This class has a complexity of 78 which exceeds the configured maximum of 50.

The class complexity is the sum of the complexity of all methods. A very high value is usually an indication that your class does not follow the single reponsibility principle and does more than one job.

Some resources for further reading:

You can also find more detailed suggestions for refactoring in the “Code” section of your repository.

Loading history...
29
{
30
    /**
31
     * Major version of ext/couchbase.
32
     *
33
     * @var null|int
34
     */
35
    protected static $extCouchbaseMajorVersion;
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $extCouchbaseMajorVersion exceeds the maximum configured length of 20.

Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.

Loading history...
36
37
    /**
38
     * @var CouchbaseResourceManager
39
     */
40
    protected $resourceManager;
41
42
    /**
43
     * @var string
44
     */
45
    protected $resourceId;
46
47
    /**
48
     * The namespace prefix.
49
     *
50
     * @var string
51
     */
52
    protected $namespacePrefix = '';
53
54
    /**
55
     * Has this instance be initialized.
56
     *
57
     * @var bool
58
     */
59
    protected $initialized = false;
60
61
    /**
62
     * Constructor.
63
     *
64
     * @param null|array|\Traversable|CouchbaseOptions $options
65
     *
66
     * @throws Exception\ExceptionInterface
67
     */
68 61
    public function __construct($options = null)
69
    {
70 61
        if (static::$extCouchbaseMajorVersion === null) {
71 1
            $v = (string) phpversion('couchbase');
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $v. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
72 1
            static::$extCouchbaseMajorVersion = ($v !== '') ? (int) $v[0] : 0;
73 1
        }
74 61
        if (static::$extCouchbaseMajorVersion < 2) {
75
            throw new Exception\ExtensionNotLoadedException('Need ext/couchbase version >= 2.0.0');
76
        }
77 61
        parent::__construct($options);
78
        // reset initialized flag on update option(s)
79 61
        $initialized = &$this->initialized;
80 61
        $this->getEventManager()->attach('option', function () use (&$initialized) {
81 61
            $initialized = false;
82 61
        });
83 61
    }
84
85
    /**
86
     * Flush the whole storage.
87
     *
88
     * @return bool
89
     */
90 61
    public function flush()
91
    {
92 61
        $this->getCouchbaseResource()->manager()->flush();
93
94 61
        return true;
95
    }
96
97
    /**
98
     * Internal method to store an item.
99
     *
100
     * @param string $normalizedKey
101
     * @param mixed  $value
102
     *
103
     * @return bool
104
     *
105
     * @throws Exception\ExceptionInterface
106
     */
107 32
    protected function internalSetItem(&$normalizedKey, &$value)
108
    {
109 32
        $memc = $this->getCouchbaseResource();
110 32
        $internalKey = $this->namespacePrefix.$normalizedKey;
111
112
        try {
113 32
            $memc->upsert($internalKey, $value, ['expiry' => $this->expirationTime()]);
114 32
        } catch (\CouchbaseException $e) {
115
            if ($e->getCode() === \COUCHBASE_KEY_ENOENT) {
116
                return false;
117
            }
118
119
            throw new Exception\RuntimeException($e->getMessage());
120
        }
121
122 32
        return true;
123
    }
124
125
    /**
126
     * Initialize the internal memcached resource.
127
     *
128
     * @return \CouchbaseBucket
129
     */
130 61
    protected function getCouchbaseResource()
131
    {
132 61
        if (!$this->initialized) {
133 61
            $options = $this->getOptions();
134
135
            // get resource manager and resource id
136 61
            $this->resourceManager = $options->getResourceManager();
137 61
            $this->resourceId = $options->getResourceId();
138
139
            // init namespace prefix
140 61
            $namespace = $options->getNamespace();
141 61
            $this->namespacePrefix = '';
142
143 61
            if ($namespace !== '') {
144 61
                $this->namespacePrefix = $namespace.$options->getNamespaceSeparator();
145 61
            }
146
147
            // update initialized flag
148 61
            $this->initialized = true;
149 61
        }
150
151 61
        return $this->resourceManager->getResource($this->resourceId);
152
    }
153
154
    /**
155
     * Get options.
156
     *
157
     * @return CouchbaseOptions
158
     *
159
     * @see setOptions()
160
     */
161 61
    public function getOptions()
162
    {
163 61
        if (!$this->options) {
164
            $this->setOptions(new CouchbaseOptions());
165
        }
166
167 61
        return $this->options;
168
    }
169
170
    /**
171
     * Set options.
172
     *
173
     * @param array|\Traversable|CouchbaseOptions $options
174
     *
175
     * @return \CouchbaseCluster
176
     *
177
     * @see    getOptions()
178
     */
179 61
    public function setOptions($options)
180
    {
181 61
        if (!$options instanceof CouchbaseOptions) {
182
            $options = new CouchbaseOptions($options);
183
        }
184
185 61
        return parent::setOptions($options);
186
    }
187
188
    /**
189
     * Get expiration time by ttl.
190
     *
191
     * Some storage commands involve sending an expiration value (relative to
192
     * an item or to an operation requested by the client) to the server. In
193
     * all such cases, the actual value sent may either be Unix time (number of
194
     * seconds since January 1, 1970, as an integer), or a number of seconds
195
     * starting from current time. In the latter case, this number of seconds
196
     * may not exceed 60*60*24*30 (number of seconds in 30 days); if the
197
     * expiration value is larger than that, the server will consider it to be
198
     * real Unix time value rather than an offset from current time.
199
     *
200
     * @return int
201
     */
202 43
    protected function expirationTime()
203
    {
204 43
        $ttl = $this->getOptions()->getTtl();
205 43
        if ($ttl > 2592000) {
206
            return time() + $ttl;
207
        }
208
209 43
        return $ttl;
210
    }
211
212
    /**
213
     * Add an item.
214
     *
215
     * @param string $normalizedKey
216
     * @param mixed  $value
217
     *
218
     * @return bool
219
     *
220
     * @throws Exception\ExceptionInterface
221
     */
222 3
    protected function internalAddItem(&$normalizedKey, &$value)
223
    {
224 3
        $memc = $this->getCouchbaseResource();
225 3
        $internalKey = $this->namespacePrefix.$normalizedKey;
226
        try {
227 3
            $memc->insert($internalKey, $value, ['expiry' => $this->expirationTime()]);
228 3
        } catch (\CouchbaseException $e) {
229 1
            if ($e->getCode() === \COUCHBASE_KEY_EEXISTS) {
230 1
                return false;
231
            }
232
            throw new Exception\RuntimeException($e);
233
        }
234
235 2
        return true;
236
    }
237
238
    /**
239
     * @param array $normalizedKeyValuePairs
240
     *
241
     * @return array|mixed
242
     *
243
     * @throws Exception\RuntimeException
244
     */
245 1
    protected function internalAddItems(array &$normalizedKeyValuePairs)
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $normalizedKeyValuePairs exceeds the maximum configured length of 20.

Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.

Loading history...
246
    {
247 1
        $memc = $this->getCouchbaseResource();
248
249 1
        $namespacedKeyValuePairs = $this->namespacesKeyValuePairs($normalizedKeyValuePairs);
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $namespacedKeyValuePairs exceeds the maximum configured length of 20.

Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.

Loading history...
250
251
        try {
252 1
            $result = $memc->insert($namespacedKeyValuePairs, null, ['expiry' => $this->expirationTime()]);
253 1
        } catch (\CouchbaseException $e) {
254
            throw new Exception\RuntimeException($e);
255
        }
256
257 1
        $this->filterErrors($result);
258
259 1
        return $result;
260
    }
261
262
    /**
263
     * @param array $normalizedKeyValuePairs
264
     *
265
     * @return array
266
     */
267 7
    protected function namespacesKeyValuePairs(array &$normalizedKeyValuePairs)
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $normalizedKeyValuePairs exceeds the maximum configured length of 20.

Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.

Loading history...
268
    {
269 7
        $namespacedKeyValuePairs = [];
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $namespacedKeyValuePairs exceeds the maximum configured length of 20.

Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.

Loading history...
270
271 7
        foreach ($normalizedKeyValuePairs as $normalizedKey => &$value) {
272 7
            $namespacedKeyValuePairs[$this->namespacePrefix.$normalizedKey] = ['value' => &$value];
273 7
        }
274 7
        unset($value);
275
276 7
        return $namespacedKeyValuePairs;
277
    }
278
279
    /**
280
     * @param $result
281
     */
282 4
    protected function filterErrors(&$result)
283
    {
284 4
        foreach ($result as $key => $document) {
285 4
            if (!$document->error instanceof \CouchbaseException) {
0 ignored issues
show
Bug introduced by
The class CouchbaseException does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
286 4
                unset($result[$key]);
287 4
            }
288 4
        }
289
290 4
        $result = array_keys($result);
291
292 4
        $this->removeNamespacePrefix($result);
293 4
    }
294
295
    /**
296
     * @param array $result
297
     */
298 5
    protected function removeNamespacePrefix(&$result)
299
    {
300 5
        if ($result && $this->namespacePrefix !== '') {
0 ignored issues
show
Bug Best Practice introduced by
The expression $result of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
301 4
            $nsPrefixLength = strlen($this->namespacePrefix);
302 4
            foreach ($result as &$internalKey) {
303 4
                $internalKey = substr($internalKey, $nsPrefixLength);
304 4
            }
305 4
        }
306 5
    }
307
308
    /**
309
     * Internal method to store multiple items.
310
     *
311
     * @param array $normalizedKeyValuePairs
312
     *
313
     * @return array Array of not stored keys
314
     *
315
     * @throws Exception\ExceptionInterface
316
     */
317 6
    protected function internalSetItems(array &$normalizedKeyValuePairs)
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $normalizedKeyValuePairs exceeds the maximum configured length of 20.

Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.

Loading history...
318
    {
319 6
        $memc = $this->getCouchbaseResource();
320
321 6
        $namespacedKeyValuePairs = $this->namespacesKeyValuePairs($normalizedKeyValuePairs);
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $namespacedKeyValuePairs exceeds the maximum configured length of 20.

Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.

Loading history...
322
323 6
        $memc->upsert($namespacedKeyValuePairs, null, ['expiry' => $this->expirationTime()]);
324
325 6
        return [];
326
    }
327
328
    /**
329
     * Internal method to remove an item.
330
     *
331
     * @param string $normalizedKey
332
     *
333
     * @return bool
334
     *
335
     * @throws Exception\ExceptionInterface
336
     */
337 3
    protected function internalRemoveItem(&$normalizedKey)
338
    {
339 3
        $memc = $this->getCouchbaseResource();
340 3
        $result = true;
341
342
        try {
343 3
            $memc->remove($this->namespacePrefix.$normalizedKey);
344 3
        } catch (\CouchbaseException $e) {
345 1
            $result = false;
346
        }
347
348 3
        return $result;
349
    }
350
351
    /**
352
     * Internal method to remove multiple items.
353
     *
354
     * @param array $normalizedKeys
355
     *
356
     * @return array Array of not removed keys
357
     *
358
     * @throws Exception\ExceptionInterface
359
     */
360 3
    protected function internalRemoveItems(array &$normalizedKeys)
361
    {
362 3
        $memc = $this->getCouchbaseResource();
363
364 3
        $this->namespacesKeys($normalizedKeys);
365
366
        try {
367 3
            $result = $memc->remove($normalizedKeys);
368 3
        } catch (\CouchbaseException $e) {
369
            throw new Exception\RuntimeException($e);
370
        }
371
372 3
        $this->filterErrors($result);
373
374 3
        return $result;
375
    }
376
377 6
    protected function namespacesKeys(array &$normalizedKeys)
378
    {
379 6
        foreach ($normalizedKeys as &$normalizedKey) {
380 6
            $normalizedKey = $this->namespacePrefix.$normalizedKey;
381 6
        }
382 6
    }
383
384
    /**
385
     * Internal method to set an item only if token matches.
386
     *
387
     * @param mixed  $token
388
     * @param string $normalizedKey
389
     * @param mixed  $value
390
     *
391
     * @return bool
392
     *
393
     * @throws Exception\ExceptionInterface
394
     *
395
     * @see    getItem()
396
     * @see    setItem()
397
     */
398 1
    protected function internalCheckAndSetItem(&$token, &$normalizedKey, &$value)
399
    {
400 1
        $memc = $this->getCouchbaseResource();
401 1
        $key = $this->namespacePrefix.$normalizedKey;
402 1
        $success = null;
403 1
        $this->internalGetItem($key, $success, $token);
404
405
        try {
406 1
            $memc->replace($key, $value, ['cas' => $token, 'expiry' => $this->expirationTime()]);
407 1
            $result = true;
408 1
        } catch (\CouchbaseException $e) {
409 1
            if ($e->getCode() === \COUCHBASE_KEY_EEXISTS
410 1
                || $e->getCode() === \COUCHBASE_KEY_ENOENT
411 1
            ) {
412 1
                return false;
413
            }
414
            throw new Exception\RuntimeException($e);
415
        }
416
417 1
        return $result;
418
    }
419
420
    /**
421
     * Internal method to get an item.
422
     *
423
     * @param string $normalizedKey
424
     * @param bool   $success
425
     * @param mixed  $casToken
426
     *
427
     * @return mixed Data on success, null on failure
428
     *
429
     * @throws Exception\ExceptionInterface
430
     */
431 20
    protected function internalGetItem(&$normalizedKey, &$success = null, &$casToken = null)
432
    {
433 20
        $internalKey = $this->namespacePrefix.$normalizedKey;
434 20
        $memc = $this->getCouchbaseResource();
435
436
        try {
437 20
            $document = $memc->get($internalKey);
438 17
            $result = $document->value;
439 17
            $casToken = $document->cas;
440 17
            $success = true;
441 20
        } catch (\CouchbaseException $e) {
442 6
            if ($e->getCode() === \COUCHBASE_KEY_ENOENT) {
443 6
                $result = null;
444 6
                $success = false;
445 6
            } else {
446
                throw new Exception\RuntimeException($e->getMessage());
447
            }
448
        }
449
450 20
        return $result;
451
    }
452
453
    /**
454
     * Internal method to set an item only if token matches.
455
     *
456
     * @param string $normalizedKey
457
     * @param mixed  $value
458
     *
459
     * @return bool
460
     *
461
     * @throws Exception\ExceptionInterface
462
     */
463 3
    protected function internalReplaceItem(&$normalizedKey, &$value)
464
    {
465 3
        $result = true;
466
467 3
        $memc = $this->getCouchbaseResource();
468 3
        $expiration = $this->expirationTime();
469
        try {
470 3
            $memc->replace($this->namespacePrefix.$normalizedKey, $value, ['expiry' => $expiration]);
471 3
        } catch (\CouchbaseException $e) {
472 2
            $result = false;
473
        }
474
475 3
        return $result;
476
    }
477
478
    /**
479
     * Internal method to touch an item.
480
     *
481
     * @param string &$normalizedKey Key which will be touched
482
     *
483
     * @return bool
484
     *
485
     * @throws Exception\RuntimeException
486
     */
487 2
    protected function internalTouchItem(&$normalizedKey)
488
    {
489 2
        $redis = $this->getCouchbaseResource();
490
        try {
491 2
            $ttl = $this->getOptions()->getTtl();
492 2
            $redis->touch($this->namespacePrefix.$normalizedKey, $ttl);
493 2
        } catch (\CouchbaseException $e) {
494 1
            if ($e->getCode() === \COUCHBASE_KEY_EEXISTS
495 1
                || $e->getCode() === \COUCHBASE_KEY_ENOENT
496 1
            ) {
497 1
                return false;
498
            }
499
            throw new Exception\RuntimeException($e);
500
        }
501
502 1
        return true;
503
    }
504
505
    /**
506
     * Internal method to test if an item exists.
507
     *
508
     * @param string $normalizedKey
509
     *
510
     * @return bool
511
     *
512
     * @throws Exception\ExceptionInterface
513
     */
514 17
    protected function internalHasItem(&$normalizedKey)
515
    {
516 17
        $memc = $this->getCouchbaseResource();
517 17
        $internalKey = $this->namespacePrefix.$normalizedKey;
518
519
        try {
520 17
            $result = $memc->get($internalKey)->value;
521 17
        } catch (\CouchbaseException $e) {
522 11
            if ($e->getCode() === \COUCHBASE_KEY_ENOENT) {
523 11
                $result = false;
524 11
            } else {
525
                throw new Exception\RuntimeException($e);
526
            }
527
        }
528
529 17
        return (bool) $result;
530
    }
531
532
    /**
533
     * Internal method to test multiple items.
534
     *
535
     * @param array $normalizedKeys
536
     *
537
     * @return array Array of found keys
538
     *
539
     * @throws Exception\ExceptionInterface
540
     */
541 3
    protected function internalHasItems(array &$normalizedKeys)
542
    {
543 3
        $memc = $this->getCouchbaseResource();
544
545 3
        $this->namespacesKeys($normalizedKeys);
546
547
        try {
548 3
            $result = $memc->get($normalizedKeys);
549 3
            foreach ($result as $key => $element) {
550 3
                if ($element->error instanceof \CouchbaseException
0 ignored issues
show
Bug introduced by
The class CouchbaseException does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
551 3
                    && $element->error->getCode() === \COUCHBASE_KEY_ENOENT
552 3
                ) {
553 2
                    unset($result[$key]);
554 2
                }
555 3
            }
556 3
        } catch (\CouchbaseException $e) {
557
            return [];
558
        }
559
560 3
        $result = array_keys($result);
561
562 3
        $this->removeNamespacePrefix($result);
563
564 3
        return $result;
565
    }
566
567
    /**
568
     * Internal method to get multiple items.
569
     *
570
     * @param array $normalizedKeys
571
     *
572
     * @return array Associative array of keys and values
573
     *
574
     * @throws Exception\ExceptionInterface
575
     */
576 4
    protected function internalGetItems(array &$normalizedKeys)
577
    {
578 4
        $memc = $this->getCouchbaseResource();
579
580 4
        $this->namespacesKeys($normalizedKeys);
581
582
        try {
583 4
            $result = $memc->get($normalizedKeys);
584 4
            foreach ($result as $key => $element) {
585 4
                if ($element->error instanceof \CouchbaseException
0 ignored issues
show
Bug introduced by
The class CouchbaseException does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
586 4
                    && $element->error->getCode() === \COUCHBASE_KEY_ENOENT
587 4
                ) {
588 2
                    unset($result[$key]);
589 2
                } else {
590 4
                    $result[$key] = $element->value;
591
                }
592 4
            }
593 4
        } catch (\CouchbaseException $e) {
594
            return [];
595
        }
596
597
        // remove namespace prefix from result
598 4
        if ($result && $this->namespacePrefix !== '') {
599 3
            $tmp = [];
600 3
            $nsPrefixLength = strlen($this->namespacePrefix);
601 3
            foreach ($result as $internalKey => $value) {
602 3
                $tmp[substr($internalKey, $nsPrefixLength)] = $value instanceof \CouchbaseMetaDoc ? $value->value : $value;
0 ignored issues
show
Bug introduced by
The class CouchbaseMetaDoc does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
603 3
            }
604 3
            $result = $tmp;
605 3
        }
606
607 4
        return $result;
608
    }
609
610
    /**
611
     * Internal method to increment an item.
612
     *
613
     * @param string $normalizedKey
614
     * @param int    $value
615
     *
616
     * @return int|bool The new value on success, false on failure
617
     *
618
     * @throws Exception\ExceptionInterface
619
     */
620 3
    protected function internalIncrementItem(&$normalizedKey, &$value)
621
    {
622 3
        $couchbaseBucket = $this->getCouchbaseResource();
623 3
        $internalKey = $this->namespacePrefix.$normalizedKey;
624 3
        $value = (int) $value;
625 3
        $newValue = false;
626
627
        try {
628 3
            $newValue = $couchbaseBucket->counter($internalKey, $value, ['initial' => $value, 'expiry' => $this->expirationTime()])->value;
629 3
        } catch (\CouchbaseException $e) {
630
            try {
631
                if ($e->getCode() === \COUCHBASE_KEY_ENOENT) {
632
                    $newValue = $couchbaseBucket->insert($internalKey, $value, ['expiry' => $this->expirationTime()])->value;
633
                }
634
            } catch (\CouchbaseException $e) {
635
                throw new Exception\RuntimeException($e);
636
            }
637
        }
638
639 3
        return $newValue;
640
    }
641
642
    /**
643
     * Internal method to decrement an item.
644
     *
645
     * @param string $normalizedKey
646
     * @param int    $value
647
     *
648
     * @return int|bool The new value on success, false on failure
649
     *
650
     * @throws Exception\ExceptionInterface
651
     */
652 2
    protected function internalDecrementItem(&$normalizedKey, &$value)
653
    {
654 2
        $couchbaseBucket = $this->getCouchbaseResource();
655 2
        $internalKey = $this->namespacePrefix.$normalizedKey;
656 2
        $value = - (int) $value;
657 2
        $newValue = false;
658
659
        try {
660 2
            $newValue = $couchbaseBucket->counter($internalKey, $value, ['expiry' => $this->expirationTime()])->value;
661 2
        } catch (\CouchbaseException $e) {
662
            try {
663 1
                if ($e->getCode() === \COUCHBASE_KEY_ENOENT) {
664 1
                    $newValue = $value;
665 1
                    $couchbaseBucket->insert($internalKey, $value, ['expiry' => $this->expirationTime()]);
666 1
                }
667 1
            } catch (\CouchbaseException $e) {
668
                throw new Exception\RuntimeException($e);
669
            }
670
        }
671
672 2
        return $newValue;
673
    }
674
675
    /**
676
     * Internal method to get capabilities of this adapter.
677
     *
678
     * @return Capabilities
679
     */
680 15
    protected function internalGetCapabilities()
681
    {
682 15
        if ($this->capabilities === null) {
683 15
            $this->capabilityMarker = new \stdClass();
684 15
            $this->capabilities = new Capabilities(
685 15
                $this,
686 15
                $this->capabilityMarker,
687
                [
688
                    'supportedDatatypes' => [
689 15
                        'NULL' => true,
690 15
                        'boolean' => true,
691 15
                        'integer' => true,
692 15
                        'double' => true,
693 15
                        'string' => true,
694 15
                        'array' => false,
695 15
                        'object' => 'object',
696 15
                        'resource' => false,
697 15
                    ],
698 15
                    'supportedMetadata' => [],
699 15
                    'minTtl' => 1,
700 15
                    'maxTtl' => 0,
701 15
                    'staticTtl' => true,
702 15
                    'ttlPrecision' => 1,
703 15
                    'useRequestTime' => false,
704 15
                    'expiredRead' => false,
705 15
                    'maxKeyLength' => 255,
706 15
                    'namespaceIsPrefix' => true,
707
                ]
708 15
            );
709 15
        }
710
711 15
        return $this->capabilities;
712
    }
713
}
714