Completed
Push — master ( ea3a48...b57255 )
by Lars
02:48
created

Cache::removeAll()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2.0625

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 8
ccs 3
cts 4
cp 0.75
rs 9.4285
cc 2
eloc 5
nc 2
nop 0
crap 2.0625
1
<?php
2
3
namespace voku\cache;
4
5
/**
6
 * Cache: global-cache class
7
 *
8
 * can use different cache-adapter:
9
 * - Redis
10
 * - Memcache / Memcached
11
 * - APC / APCu
12
 * - Xcache
13
 * - Array
14
 *
15
 * @package   voku\cache
16
 */
17
class Cache implements iCache
18
{
19
20
  /**
21
   * @var iAdapter
22
   */
23
  private $adapter;
24
25
  /**
26
   * @var iSerializer
27
   */
28
  private $serializer;
29
30
  /**
31
   * @var string
32
   */
33
  private $prefix = '';
34
35
  /**
36
   * @var bool
37
   */
38
  private $isReady = false;
39
40
  /**
41
   * @var bool
42
   */
43
  private $isActive = true;
44
45
  /**
46
   * @var mixed no cache, if admin-session is set
47
   */
48
  private $isAdminSession = false;
49
50
  /**
51
   * __construct
52
   *
53
   * @param null|iAdapter    $adapter
54
   * @param null|iSerializer $serializer
55
   * @param boolean          $checkForUser   check for dev-ip or if cms-user is logged-in
56
   * @param boolean          $cacheEnabled   false will disable the cache (use it e.g. for global settings)
57
   * @param string|boolean   $isAdminSession set a user-id, if the user is a admin (so we can disable cache for this
58
   *                                         user)
59
   */
60 37
  public function __construct($adapter = null, $serializer = null, $checkForUser = true, $cacheEnabled = true, $isAdminSession = false)
61
  {
62 37
    $this->isAdminSession = $isAdminSession;
63
64
    // check for active-cache
65 37
    $this->setActive($cacheEnabled);
66 37
    if ($this->isActive === true && $checkForUser === true) {
67
      $this->setActive($this->isCacheActiveForTheCurrentUser());
68
    }
69
70 37
    if ($this->isActive === true) {
71
72 37
      $this->setPrefix($this->getTheDefaultPrefix());
73
74
      if (
75
          $adapter === null
76 37
          ||
77 37
          !is_object($adapter)
78 37
          ||
79
          !$adapter instanceof iAdapter
80 37
      ) {
81
        $adapter = $this->autoConnectToAvailableCacheSystem();
82
      }
83
84
      // Memcache(d) has his own "serializer", so don't use it twice
85 37
      if (!is_object($serializer) && $serializer === null) {
86
        if (
87
            $adapter instanceof AdapterMemcached
88
            ||
89
            $adapter instanceof AdapterMemcache
90
        ) {
91 1
          $serializer = new SerializerNo();
92
        } else {
93
          // set serializer as default
94
          $serializer = new SerializerIgbinary();
95
        }
96
      }
97 37
    }
98
99
    // check if we will use the cache
100
    if (
101
        $serializer instanceof iSerializer
102 37
        &&
103
        $adapter instanceof iAdapter
104 37
    ) {
105 37
      $this->setCacheIsReady(true);
106
107 37
      $this->adapter = $adapter;
108 37
      $this->serializer = $serializer;
109 37
    }
110 37
  }
111
112
  /**
113
   * enable / disable the cache
114
   *
115
   * @param boolean $isActive
116
   */
117 37
  public function setActive($isActive)
118
  {
119 37
    $this->isActive = (boolean)$isActive;
120 37
  }
121
122
  /**
123
   * check if the current use is a admin || dev || server == client
124
   *
125
   * @return bool
126
   */
127
  public function isCacheActiveForTheCurrentUser()
0 ignored issues
show
Coding Style introduced by
isCacheActiveForTheCurrentUser uses the super-global variable $_GET which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
Coding Style introduced by
isCacheActiveForTheCurrentUser uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
128
  {
129
    $active = true;
130
131
    // test the cache, with this GET-parameter
132
    $testCache = isset($_GET['testCache']) ? (int)$_GET['testCache'] : 0;
133
134
    if ($testCache != 1) {
135
      if (
136
        // server == client
137
          (
138
              isset($_SERVER['SERVER_ADDR'])
139
              &&
140
              $_SERVER['SERVER_ADDR'] == $this->getClientIp()
141
          )
142
          ||
143
          // admin is logged-in
144
          $this->isAdminSession
145
          ||
146
          // user is a dev
147
          $this->checkForDev() === true
148
      ) {
149
        $active = false;
150
      }
151
    }
152
153
    return $active;
154
  }
155
156
  /**
157
   * returns the IP address of the client
158
   *
159
   * @param   bool $trust_proxy_headers   Whether or not to trust the
160
   *                                      proxy headers HTTP_CLIENT_IP
161
   *                                      and HTTP_X_FORWARDED_FOR. ONLY
162
   *                                      use if your $_SERVER is behind a
163
   *                                      proxy that sets these values
164
   *
165
   * @return  string
166
   */
167
  private function getClientIp($trust_proxy_headers = false)
0 ignored issues
show
Coding Style introduced by
getClientIp uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
168
  {
169
    $remoteAddr = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : 'NO_REMOTE_ADDR';
170
171
    if ($trust_proxy_headers) {
172
      return $remoteAddr;
173
    }
174
175
    if (isset($_SERVER['HTTP_CLIENT_IP']) && $_SERVER['HTTP_CLIENT_IP']) {
176
      $ip = $_SERVER['HTTP_CLIENT_IP'];
177
    } elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR']) && $_SERVER['HTTP_X_FORWARDED_FOR']) {
178
      $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
179
    } else {
180
      $ip = $remoteAddr;
181
    }
182
183
    return $ip;
184
  }
185
186
  /**
187
   * check for developer
188
   *
189
   * @return bool
190
   */
191
  private function checkForDev()
0 ignored issues
show
Coding Style introduced by
checkForDev uses the super-global variable $_GET which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
Coding Style introduced by
checkForDev uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
192
  {
193
    $return = false;
194
195
    if (function_exists('checkForDev')) {
196
      $return = checkForDev();
197
    } else {
198
199
      // for testing with dev-address
200
      $noDev = isset($_GET['noDev']) ? (int)$_GET['noDev'] : 0;
201
      $remoteAddr = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : 'NO_REMOTE_ADDR';
202
203
      if (
204
          $noDev != 1
205
          &&
206
          (
207
              $remoteAddr === '127.0.0.1'
208
              ||
209
              $remoteAddr === '::1'
210
              ||
211
              PHP_SAPI === 'cli'
212
          )
213
      ) {
214
        $return = true;
215
      }
216
    }
217
218
    return $return;
219
  }
220
221
  /**
222
   * set the default-prefix via "SERVER"-var + "SESSION"-language
223
   */
224 37
  protected function getTheDefaultPrefix()
0 ignored issues
show
Coding Style introduced by
getTheDefaultPrefix uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
Coding Style introduced by
getTheDefaultPrefix uses the super-global variable $_SESSION which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
225
  {
226 37
    return (isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : '') . '_' .
227 37
           (isset($_SERVER['THEME']) ? $_SERVER['THEME'] : '') . '_' .
228 37
           (isset($_SERVER['STAGE']) ? $_SERVER['STAGE'] : '') . '_' .
229 37
           (isset($_SESSION['language']) ? $_SESSION['language'] : '') . '_' .
230 37
           (isset($_SESSION['language_extra']) ? $_SESSION['language_extra'] : '');
231
  }
232
233
  /**
234
   * auto-connect to the available cache-system on the server
235
   *
236
   * @return iAdapter
237
   */
238
  protected function autoConnectToAvailableCacheSystem()
239
  {
240
    static $adapterCache;
241
242
    if (is_object($adapterCache) && $adapterCache instanceof iAdapter) {
243
      return $adapterCache;
244
    } else {
245
246
      $memcached = null;
247
      $isMemcachedAvailable = false;
248
      if (extension_loaded('memcached')) {
249
        $memcached = new \Memcached();
250
        $isMemcachedAvailable = $memcached->addServer('127.0.0.1', '11211');
251
      }
252
253
      if ($isMemcachedAvailable === false) {
254
        $memcached = null;
255
      }
256
257
      $adapterMemcached = new AdapterMemcached($memcached);
0 ignored issues
show
Bug introduced by
It seems like $memcached can be null; however, __construct() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
258
      if ($adapterMemcached->installed() === true) {
259
260
        // fallback to Memcached
261
        $adapter = $adapterMemcached;
262
263
      } else {
264
265
        $memcache = null;
266
        $isMemcacheAvailable = false;
267
        if (class_exists('\Memcache')) {
268
          $memcache = new \Memcache;
269
          /** @noinspection PhpUsageOfSilenceOperatorInspection */
270
          $isMemcacheAvailable = @$memcache->connect('127.0.0.1', 11211);
271
        }
272
273
        if ($isMemcacheAvailable === false) {
274
          $memcache = null;
275
        }
276
277
        $adapterMemcache = new AdapterMemcache($memcache);
0 ignored issues
show
Bug introduced by
It seems like $memcache can be null; however, __construct() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
278
        if ($adapterMemcache->installed() === true) {
279
280
          // fallback to Memcache
281
          $adapter = $adapterMemcache;
282
283
        } else {
284
285
          $redis = null;
286
          $isRedisAvailable = false;
287
          if (extension_loaded('redis')) {
288
            if (class_exists('\Predis\Client')) {
289
              /** @noinspection PhpUndefinedNamespaceInspection */
290
              $redis = new \Predis\Client(
291
                  array(
292
                      'scheme'  => 'tcp',
293
                      'host'    => '127.0.0.1',
294
                      'port'    => 6379,
295
                      'timeout' => '2.0',
296
                  )
297
              );
298
              try {
299
                $redis->connect();
300
                $isRedisAvailable = $redis->getConnection()->isConnected();
301
              } catch (\Exception $e) {
302
                // nothing
303
              }
304
            }
305
          }
306
307
          if ($isRedisAvailable === false) {
308
            $redis = null;
309
          }
310
311
          $adapterRedis = new AdapterPredis($redis);
0 ignored issues
show
Bug introduced by
It seems like $redis can be null; however, __construct() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
312
          if ($adapterRedis->installed() === true) {
313
314
            // fallback to Redis
315
            $adapter = $adapterRedis;
316
317
          } else {
318
319
            $adapterXcache = new AdapterXcache();
320
            if ($adapterXcache->installed() === true) {
321
322
              // fallback to Xcache
323
              $adapter = $adapterXcache;
324
325
            } else {
326
327
              $adapterApc = new AdapterApc();
328
              if ($adapterApc->installed() === true) {
329
330
                // fallback to APC || APCu
331
                $adapter = $adapterApc;
332
333
              } else {
334
335
                $adapterFile = new AdapterFile();
336
                if ($adapterFile->installed() === true) {
337
338
                  // fallback to File-Cache
339
                  $adapter = $adapterFile;
340
341
                } else {
342
                  // no cache-adapter available -> use a array
343
                  $adapter = new AdapterArray();
344
                }
345
              }
346
            }
347
          }
348
        }
349
      }
350
351
      // save to static cache
352
      $adapterCache = $adapter;
353
    }
354
355
    return $adapter;
356
  }
357
358
  /**
359
   * set cacheIsReady state
360
   *
361
   * @param boolean $isReady
362
   */
363 37
  private function setCacheIsReady($isReady)
364
  {
365 37
    $this->isReady = (boolean)$isReady;
366 37
  }
367
368
  /**
369
   * get the cacheIsReady state
370
   *
371
   * @return boolean
372
   */
373 4
  public function getCacheIsReady()
374
  {
375 4
    return $this->isReady;
376
  }
377
378
  /**
379
   * get cached-item by key
380
   *
381
   * @param string $key
382
   *
383
   * @return mixed
384
   */
385 17
  public function getItem($key)
386
  {
387 17
    if ($this->adapter instanceof iAdapter) {
388 17
      $storeKey = $this->calculateStoreKey($key);
389 17
      $serialized = $this->adapter->get($storeKey);
390 17
      $value = $serialized ? $this->serializer->unserialize($serialized) : null;
391 17
    } else {
392
      return null;
393
    }
394
395 17
    return $value;
396
  }
397
398
  /**
399
   * calculate store-key (prefix + $rawKey)
400
   *
401
   * @param String $rawKey
402
   *
403
   * @return string
404
   */
405 32
  private function calculateStoreKey($rawKey)
406
  {
407 32
    $str = $this->getPrefix() . $rawKey;
408
409 32
    if ($this->adapter instanceof AdapterFile) {
410 6
      $str = $this->cleanStoreKey($str);
411 6
    }
412
413 32
    return $str;
414
  }
415
416
  /**
417
   * @param string $str
418
   *
419
   * @return string
420
   */
421 6
  private function cleanStoreKey($str)
422
  {
423 6
    $str = preg_replace("/[\r\n\t ]+/", ' ', $str);
424 6
    $str = str_replace(
425 6
        array('"', '*', ':', '<', '>', '?', "'", '|'),
426
        array(
427 6
            '-+-',
428 6
            '-+-+-',
429 6
            '-+-+-+-',
430 6
            '-+-+-+-+-',
431 6
            '-+-+-+-+-+-',
432 6
            '-+-+-+-+-+-+-',
433 6
            '-+-+-+-+-+-+-+-',
434 6
            '-+-+-+-+-+-+-+-+-',
435 6
        ),
436
        $str
437 6
    );
438 6
    $str = html_entity_decode($str, ENT_QUOTES, 'UTF-8');
439 6
    $str = htmlentities($str, ENT_QUOTES, 'UTF-8');
440 6
    $str = preg_replace('/(&)([a-z])([a-z]+;)/i', '$2', $str);
441 6
    $str = str_replace(' ', '-', $str);
442 6
    $str = rawurlencode($str);
443 6
    $str = str_replace('%', '-', $str);
444
445 6
    return $str;
446
  }
447
448
  /**
449
   * @return string
450
   */
451 32
  public function getPrefix()
452
  {
453 32
    return $this->prefix;
454
  }
455
456
  /**
457
   * set prefix [WARNING: do not use if you don't know what you do]
458
   *
459
   * @param string $prefix
460
   */
461 37
  public function setPrefix($prefix)
462
  {
463 37
    $this->prefix = (string)$prefix;
464 37
  }
465
466
  /**
467
   * set cache-item by key => value + date
468
   *
469
   * @param string    $key
470
   * @param mixed     $value
471
   * @param \DateTime $date
472
   *
473
   * @return boolean
474
   * @throws \Exception
475
   */
476 6
  public function setItemToDate($key, $value, \DateTime $date)
477
  {
478 6
    $ttl = $date->getTimestamp() - time();
479
480 6
    if ($ttl <= 0) {
481 1
      throw new \Exception('Date in the past.');
482
    }
483
484 5
    $storeKey = $this->calculateStoreKey($key);
485
486 5
    return $this->setItem($storeKey, $value, $ttl);
487
  }
488
489
  /**
490
   * set cache-item by key => value + ttl
491
   *
492
   * @param string $key
493
   * @param mixed  $value
494
   * @param int    $ttl
495
   *
496
   * @return bool
497
   */
498 17
  public function setItem($key, $value, $ttl = 0)
499
  {
500
    if (
501 17
        $this->adapter instanceof iAdapter
502 17
        &&
503 17
        $this->serializer instanceof iSerializer
504 17
    ) {
505 17
      $storeKey = $this->calculateStoreKey($key);
506 17
      $serialized = $this->serializer->serialize($value);
507
508 17
      if ($ttl) {
509 7
        return $this->adapter->setExpired($storeKey, $serialized, $ttl);
510
      } else {
511 10
        return $this->adapter->set($storeKey, $serialized);
512
      }
513
    } else {
514
      return false;
515
    }
516
  }
517
518
  /**
519
   * remove cached-item
520
   *
521
   * @param string $key
522
   *
523
   * @return bool
524
   */
525 2 View Code Duplication
  public function removeItem($key)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

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

Loading history...
526
  {
527 2
    if ($this->adapter instanceof iAdapter) {
528 2
      $storeKey = $this->calculateStoreKey($key);
529
530 2
      return $this->adapter->remove($storeKey);
531
    } else {
532
      return false;
533
    }
534
  }
535
536
  /**
537
   * remove cache
538
   *
539
   * @return bool
540
   */
541 1
  public function removeAll()
542
  {
543 1
    if ($this->adapter instanceof iAdapter) {
544 1
      return $this->adapter->removeAll();
545
    } else {
546
      return false;
547
    }
548
  }
549
550
  /**
551
   * check if cached-item exists
552
   *
553
   * @param string $key
554
   *
555
   * @return boolean
556
   */
557 6 View Code Duplication
  public function existsItem($key)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

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

Loading history...
558
  {
559 6
    if ($this->adapter instanceof iAdapter) {
560 6
      $storeKey = $this->calculateStoreKey($key);
561
562 6
      return $this->adapter->exists($storeKey);
563
    } else {
564
      return false;
565
    }
566
  }
567
568
}
569