Completed
Push — master ( 7cf8a8...6bcaa7 )
by Lars
02:27
created

Cache::existsItem()   B

Complexity

Conditions 5
Paths 6

Size

Total Lines 22
Code Lines 11

Duplication

Lines 22
Ratio 100 %

Code Coverage

Tests 5
CRAP Score 9.9614

Importance

Changes 1
Bugs 1 Features 0
Metric Value
c 1
b 1
f 0
dl 22
loc 22
ccs 5
cts 12
cp 0.4167
rs 8.6737
cc 5
eloc 11
nc 6
nop 1
crap 9.9614
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
 * - File
15
 *
16
 * @package   voku\cache
17
 */
18
class Cache implements iCache
19
{
20
21
  /**
22
   * @var iAdapter
23
   */
24
  private $adapter;
25
26
  /**
27
   * @var iSerializer
28
   */
29
  private $serializer;
30
31
  /**
32
   * @var string
33
   */
34
  private $prefix = '';
35
36
  /**
37
   * @var bool
38
   */
39
  private $isReady = false;
40
41
  /**
42
   * @var bool
43
   */
44
  private $isActive = true;
45
46
  /**
47
   * @var mixed no cache, if admin-session is set
48
   */
49
  private $isAdminSession = false;
50
51
  /**
52
   * @var array
53
   */
54
  private static $STATIC_CACHE = array();
55
56
  /**
57
   * @var array
58
   */
59
  private static $STATIC_CACHE_COUNTER = array();
60
61
  /**
62
   * __construct
63
   *
64
   * @param null|iAdapter    $adapter
65
   * @param null|iSerializer $serializer
66
   * @param boolean          $checkForUser   check for dev-ip or if cms-user is logged-in
67
   * @param boolean          $cacheEnabled   false will disable the cache (use it e.g. for global settings)
68
   * @param string|boolean   $isAdminSession set a user-id, if the user is a admin (so we can disable cache for this
69
   *                                         user)
70
   */
71 42
  public function __construct($adapter = null, $serializer = null, $checkForUser = true, $cacheEnabled = true, $isAdminSession = false)
72
  {
73 42
    $this->isAdminSession = $isAdminSession;
74
75
    // First check if the cache is active at all.
76 42
    $this->setActive($cacheEnabled);
77
    if (
78 42
        $this->isActive === true
79 42
        &&
80
        $checkForUser === true
81 42
    ) {
82
      $this->setActive($this->isCacheActiveForTheCurrentUser());
83
    }
84
85
    // If the cache is active, then try to auto-connect to the best possible cache-system.
86 42
    if ($this->isActive === true) {
87
88 42
      $this->setPrefix($this->getTheDefaultPrefix());
89
90
      if (
91
          $adapter === null
92 42
          ||
93 42
          !is_object($adapter)
94 42
          ||
95
          !$adapter instanceof iAdapter
96 42
      ) {
97
        $adapter = $this->autoConnectToAvailableCacheSystem();
98
      }
99
100
      // INFO: Memcache(d) has his own "serializer", so don't use it twice
101 42
      if (!is_object($serializer) && $serializer === null) {
102
        if (
103
            $adapter instanceof AdapterMemcached
104
            ||
105
            $adapter instanceof AdapterMemcache
106
        ) {
107
          $serializer = new SerializerNo();
108
        } else {
109
          // set default serializer
110
          $serializer = new SerializerIgbinary();
111
        }
112
      }
113 42
    }
114
115
    // Final checks ...
116
    if (
117
        $serializer instanceof iSerializer
118 42
        &&
119
        $adapter instanceof iAdapter
120 42
    ) {
121 42
      $this->setCacheIsReady(true);
122
123 42
      $this->adapter = $adapter;
124 42
      $this->serializer = $serializer;
125 42
    }
126 42
  }
127
128
  /**
129
   * enable / disable the cache
130
   *
131
   * @param boolean $isActive
132
   */
133 42
  public function setActive($isActive)
134
  {
135 42
    $this->isActive = (boolean)$isActive;
136 42
  }
137
138
  /**
139
   * check if the current use is a admin || dev || server == client
140
   *
141
   * @return bool
142
   */
143
  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...
144
  {
145
    $active = true;
146
147
    // test the cache, with this GET-parameter
148
    $testCache = isset($_GET['testCache']) ? (int)$_GET['testCache'] : 0;
149
150
    if ($testCache != 1) {
151
      if (
152
        // server == client
153
          (
154
              isset($_SERVER['SERVER_ADDR'])
155
              &&
156
              $_SERVER['SERVER_ADDR'] == $this->getClientIp()
157
          )
158
          ||
159
          // admin is logged-in
160
          $this->isAdminSession
161
          ||
162
          // user is a dev
163
          $this->checkForDev() === true
164
      ) {
165
        $active = false;
166
      }
167
    }
168
169
    return $active;
170
  }
171
172
  /**
173
   * returns the IP address of the client
174
   *
175
   * @param   bool $trust_proxy_headers   Whether or not to trust the
176
   *                                      proxy headers HTTP_CLIENT_IP
177
   *                                      and HTTP_X_FORWARDED_FOR. ONLY
178
   *                                      use if your $_SERVER is behind a
179
   *                                      proxy that sets these values
180
   *
181
   * @return  string
182
   */
183
  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...
184
  {
185
    $remoteAddr = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : 'NO_REMOTE_ADDR';
186
187
    if ($trust_proxy_headers) {
188
      return $remoteAddr;
189
    }
190
191
    if (isset($_SERVER['HTTP_CLIENT_IP']) && $_SERVER['HTTP_CLIENT_IP']) {
192
      $ip = $_SERVER['HTTP_CLIENT_IP'];
193
    } elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR']) && $_SERVER['HTTP_X_FORWARDED_FOR']) {
194
      $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
195
    } else {
196
      $ip = $remoteAddr;
197
    }
198
199
    return $ip;
200
  }
201
202
  /**
203
   * Check for local developer.
204
   *
205
   * @return bool
206
   */
207
  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...
208
  {
209
    $return = false;
210
211
    if (function_exists('checkForDev')) {
212
      $return = checkForDev();
213
    } else {
214
215
      // for testing with dev-address
216
      $noDev = isset($_GET['noDev']) ? (int)$_GET['noDev'] : 0;
217
      $remoteAddr = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : 'NO_REMOTE_ADDR';
218
219
      if (
220
          $noDev != 1
221
          &&
222
          (
223
              $remoteAddr === '127.0.0.1'
224
              ||
225
              $remoteAddr === '::1'
226
              ||
227
              PHP_SAPI === 'cli'
228
          )
229
      ) {
230
        $return = true;
231
      }
232
    }
233
234
    return $return;
235
  }
236
237
  /**
238
   * Set the default-prefix via "SERVER"-var + "SESSION"-language.
239
   */
240 42
  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...
241
  {
242 42
    return (isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : '') . '_' .
243 42
           (isset($_SERVER['THEME']) ? $_SERVER['THEME'] : '') . '_' .
244 42
           (isset($_SERVER['STAGE']) ? $_SERVER['STAGE'] : '') . '_' .
245 42
           (isset($_SESSION['language']) ? $_SESSION['language'] : '') . '_' .
246 42
           (isset($_SESSION['language_extra']) ? $_SESSION['language_extra'] : '');
247
  }
248
249
  /**
250
   * Auto-connect to the available cache-system on the server.
251
   *
252
   * @return iAdapter
253
   */
254
  protected function autoConnectToAvailableCacheSystem()
255
  {
256
    static $adapterCache;
257
258
    if (is_object($adapterCache) && $adapterCache instanceof iAdapter) {
259
      return $adapterCache;
260
    } else {
261
262
      $memcached = null;
263
      $isMemcachedAvailable = false;
264
      if (extension_loaded('memcached')) {
265
        $memcached = new \Memcached();
266
        /** @noinspection PhpUsageOfSilenceOperatorInspection */
267
        $isMemcachedAvailable = @$memcached->addServer('127.0.0.1', 11211);
268
      }
269
270
      if ($isMemcachedAvailable === false) {
271
        $memcached = null;
272
      }
273
274
      $adapterMemcached = new AdapterMemcached($memcached);
275
      if ($adapterMemcached->installed() === true) {
276
277
        // -------------------------------------------------------------
278
        // "Memcached"
279
        // -------------------------------------------------------------
280
        $adapter = $adapterMemcached;
281
282
      } else {
283
284
        $memcache = null;
285
        $isMemcacheAvailable = false;
286
        if (class_exists('\Memcache')) {
287
          $memcache = new \Memcache;
288
          /** @noinspection PhpUsageOfSilenceOperatorInspection */
289
          $isMemcacheAvailable = @$memcache->connect('127.0.0.1', 11211);
290
        }
291
292
        if ($isMemcacheAvailable === false) {
293
          $memcache = null;
294
        }
295
296
        $adapterMemcache = new AdapterMemcache($memcache);
297
        if ($adapterMemcache->installed() === true) {
298
299
          // -------------------------------------------------------------
300
          // "Memcache"
301
          // -------------------------------------------------------------
302
          $adapter = $adapterMemcache;
303
304
        } else {
305
306
          $redis = null;
307
          $isRedisAvailable = false;
308
          if (
309
              extension_loaded('redis')
310
              &&
311
              class_exists('\Predis\Client')
312
          ) {
313
            /** @noinspection PhpUndefinedNamespaceInspection */
314
            $redis = new \Predis\Client(
315
                array(
316
                    'scheme'  => 'tcp',
317
                    'host'    => '127.0.0.1',
318
                    'port'    => 6379,
319
                    'timeout' => '2.0',
320
                )
321
            );
322
            try {
323
              $redis->connect();
324
              $isRedisAvailable = $redis->getConnection()->isConnected();
325
            } catch (\Exception $e) {
326
              // nothing
327
            }
328
          }
329
330
          if ($isRedisAvailable === false) {
331
            $redis = null;
332
          }
333
334
          $adapterRedis = new AdapterPredis($redis);
335
          if ($adapterRedis->installed() === true) {
336
337
            // -------------------------------------------------------------
338
            // Redis
339
            // -------------------------------------------------------------
340
            $adapter = $adapterRedis;
341
342
          } else {
343
344
            $adapterXcache = new AdapterXcache();
345
            if ($adapterXcache->installed() === true) {
346
347
              // -------------------------------------------------------------
348
              // "Xcache"
349
              // -------------------------------------------------------------
350
              $adapter = $adapterXcache;
351
352
            } else {
353
354
              $adapterApc = new AdapterApc();
355
              if ($adapterApc->installed() === true) {
356
357
                // -------------------------------------------------------------
358
                // "APC"
359
                // -------------------------------------------------------------
360
                $adapter = $adapterApc;
361
362
              } else {
363
364
                $adapterApcu = new AdapterApcu();
365
                if ($adapterApcu->installed() === true) {
366
367
                  // -------------------------------------------------------------
368
                  // "APCu"
369
                  // -------------------------------------------------------------
370
                  $adapter = $adapterApcu;
371
372
                } else {
373
374
                  $adapterFile = new AdapterFile();
375
                  if ($adapterFile->installed() === true) {
376
377
                    // -------------------------------------------------------------
378
                    // File-Cache
379
                    // -------------------------------------------------------------
380
                    $adapter = $adapterFile;
381
382
                  } else {
383
384
                    // -------------------------------------------------------------
385
                    // Static-PHP-Cache
386
                    // -------------------------------------------------------------
387
                    $adapter = new AdapterArray();
388
                  }
389
                }
390
              }
391
            }
392
          }
393
        }
394
      }
395
396
      // save to static cache
397
      $adapterCache = $adapter;
398
    }
399
400
    return $adapter;
401
  }
402
403
  /**
404
   * Set "isReady" state.
405
   *
406
   * @param boolean $isReady
407
   */
408 42
  private function setCacheIsReady($isReady)
409
  {
410 42
    $this->isReady = (boolean)$isReady;
411 42
  }
412
413
  /**
414
   * Get the "isReady" state.
415
   *
416
   * @return boolean
417
   */
418 4
  public function getCacheIsReady()
419
  {
420 4
    return $this->isReady;
421
  }
422
423
  /**
424
   * Get cached-item by key.
425
   *
426
   * @param string $key
427
   * @param int    $staticCacheHitCounter WARNING: This static cache has no TTL, it will be cleaned on the next request
428
   *                                      and it will use more memory as e.g. memcache.
429
   *
430
   * @return mixed
431
   */
432 19
  public function getItem($key, $staticCacheHitCounter = 0)
433
  {
434
    // init
435 19
    $staticCacheHitCounter = (int)$staticCacheHitCounter;
436
437 19
    if ($this->adapter instanceof iAdapter) {
438 19
      $storeKey = $this->calculateStoreKey($key);
439
440
      // check if we already using static-cache
441 19
      if ($this->adapter instanceof AdapterArray) {
442 5
        $staticCacheHitCounter = 0;
443 5
      }
444
445 19
      if ($staticCacheHitCounter !== 0) {
446
        if (!isset(self::$STATIC_CACHE_COUNTER[$storeKey])) {
447
          self::$STATIC_CACHE_COUNTER[$storeKey] = 0;
448
        }
449
450
        if (self::$STATIC_CACHE_COUNTER[$storeKey] < ($staticCacheHitCounter + 1)) {
451
          self::$STATIC_CACHE_COUNTER[$storeKey]++;
452
        }
453
454
        // get from static-cache
455
        if (array_key_exists($storeKey, self::$STATIC_CACHE) === true) {
456
          return self::$STATIC_CACHE[$storeKey];
457
        }
458
      }
459
460 19
      $serialized = $this->adapter->get($storeKey);
461 19
      $value = $serialized ? $this->serializer->unserialize($serialized) : null;
462
463
      if (
464
          $staticCacheHitCounter !== 0
465 19
          &&
466
          self::$STATIC_CACHE_COUNTER[$storeKey] >= $staticCacheHitCounter
467 19
      ) {
468
        // save into static-cache
469
        self::$STATIC_CACHE[$storeKey] = $value;
470
      }
471
472 19
    } else {
473
      return null;
474
    }
475
476 19
    return $value;
477
  }
478
479
  /**
480
   * Calculate store-key (prefix + $rawKey).
481
   *
482
   * @param string $rawKey
483
   *
484
   * @return string
485
   */
486 33
  private function calculateStoreKey($rawKey)
487
  {
488 33
    $str = $this->getPrefix() . $rawKey;
489
490 33
    if ($this->adapter instanceof AdapterFile) {
491 6
      $str = $this->cleanStoreKey($str);
492 6
    }
493
494 33
    return $str;
495
  }
496
497
  /**
498
   * Clean store-key (required e.g. for the "File"-Adapter).
499
   *
500
   * @param string $str
501
   *
502
   * @return string
503
   */
504 6
  private function cleanStoreKey($str)
505
  {
506 6
    $str = preg_replace("/[\r\n\t ]+/", ' ', $str);
507 6
    $str = str_replace(
508 6
        array('"', '*', ':', '<', '>', '?', "'", '|'),
509
        array(
510 6
            '-+-',
511 6
            '-+-+-',
512 6
            '-+-+-+-',
513 6
            '-+-+-+-+-',
514 6
            '-+-+-+-+-+-',
515 6
            '-+-+-+-+-+-+-',
516 6
            '-+-+-+-+-+-+-+-',
517 6
            '-+-+-+-+-+-+-+-+-',
518 6
        ),
519
        $str
520 6
    );
521 6
    $str = html_entity_decode($str, ENT_QUOTES, 'UTF-8');
522 6
    $str = htmlentities($str, ENT_QUOTES, 'UTF-8');
523 6
    $str = preg_replace('/(&)([a-z])([a-z]+;)/i', '$2', $str);
524 6
    $str = str_replace(' ', '-', $str);
525 6
    $str = rawurlencode($str);
526 6
    $str = str_replace('%', '-', $str);
527
528 6
    return $str;
529
  }
530
531
  /**
532
   * Get the prefix.
533
   *
534
   * @return string
535
   */
536 33
  public function getPrefix()
537
  {
538 33
    return $this->prefix;
539
  }
540
541
  /**
542
   * !!! Set the prefix. !!!
543
   *
544
   * WARNING: Do not use if you don't know what you do. Because this will overwrite the default prefix.
545
   *
546
   * @param string $prefix
547
   */
548 42
  public function setPrefix($prefix)
549
  {
550 42
    $this->prefix = (string)$prefix;
551 42
  }
552
553
  /**
554
   * Set cache-item by key => value + date.
555
   *
556
   * @param string    $key
557
   * @param mixed     $value
558
   * @param \DateTime $date
559
   *
560
   * @return boolean
561
   * @throws \Exception
562
   */
563 6
  public function setItemToDate($key, $value, \DateTime $date)
564
  {
565 6
    $ttl = $date->getTimestamp() - time();
566
567 6
    if ($ttl <= 0) {
568 1
      throw new \Exception('Date in the past.');
569
    }
570
571 5
    $storeKey = $this->calculateStoreKey($key);
572
573 5
    return $this->setItem($storeKey, $value, $ttl);
574
  }
575
576
  /**
577
   * Set cache-item by key => value + ttl.
578
   *
579
   * @param string $key
580
   * @param mixed  $value
581
   * @param int    $ttl
582
   *
583
   * @return bool
584
   */
585 18
  public function setItem($key, $value, $ttl = 0)
586
  {
587
    if (
588 18
        $this->adapter instanceof iAdapter
589 18
        &&
590 18
        $this->serializer instanceof iSerializer
591 18
    ) {
592 18
      $storeKey = $this->calculateStoreKey($key);
593 18
      $serialized = $this->serializer->serialize($value);
594
595 18
      if ($ttl) {
596 7
        return $this->adapter->setExpired($storeKey, $serialized, $ttl);
597
      } else {
598 11
        return $this->adapter->set($storeKey, $serialized);
599
      }
600
    } else {
601
      return false;
602
    }
603
  }
604
605
  /**
606
   * Remove a cached-item.
607
   *
608
   * @param string $key
609
   *
610
   * @return bool
611
   */
612 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...
613
  {
614 2
    if ($this->adapter instanceof iAdapter) {
615 2
      $storeKey = $this->calculateStoreKey($key);
616
617 2
      if (!empty(self::$STATIC_CACHE)) {
618
619
        // remove static-cache
620
        if (array_key_exists($storeKey, self::$STATIC_CACHE) === true) {
621
          unset(
622
              self::$STATIC_CACHE[$storeKey],
623
              self::$STATIC_CACHE_COUNTER[$storeKey]
624
          );
625
        }
626
      }
627
628 2
      return $this->adapter->remove($storeKey);
629
    } else {
630
      return false;
631
    }
632
  }
633
634
  /**
635
   * Remove all cached-items.
636
   *
637
   * @return bool
638
   */
639 1
  public function removeAll()
640
  {
641 1
    if ($this->adapter instanceof iAdapter) {
642
643 1
      if (!empty(self::$STATIC_CACHE)) {
644
645
        // remove static-cache
646
        self::$STATIC_CACHE = array();
647
        self::$STATIC_CACHE_COUNTER = array();
648
      }
649
650 1
      return $this->adapter->removeAll();
651
    } else {
652
      return false;
653
    }
654
  }
655
656
  /**
657
   * Check if cached-item exists.
658
   *
659
   * @param string $key
660
   *
661
   * @return boolean
662
   */
663 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...
664
  {
665 6
    if ($this->adapter instanceof iAdapter) {
666 6
      $storeKey = $this->calculateStoreKey($key);
667
668 6
      if (!empty(self::$STATIC_CACHE)) {
669
670
        if (!isset(self::$STATIC_CACHE_COUNTER[$storeKey])) {
671
          self::$STATIC_CACHE_COUNTER[$storeKey] = 0;
672
        }
673
674
        // get from static-cache
675
        if (array_key_exists($storeKey, self::$STATIC_CACHE) === true) {
676
          return true;
677
        }
678
      }
679
680 6
      return $this->adapter->exists($storeKey);
681
    } else {
682
      return false;
683
    }
684
  }
685
686
  /**
687
   * Get the current adapter class-name.
688
   *
689
   * @return string
690
   */
691 2
  public function getUsedAdapterClassName()
692
  {
693 2
    return get_class($this->adapter);
694
  }
695
696
  /**
697
   * Get the current serializer class-name.
698
   *
699
   * @return string
700
   */
701 2
  public function getUsedSerializerClassName()
702
  {
703 2
    return get_class($this->serializer);
704
  }
705
}
706