Completed
Push — master ( 9c8fa5...4938be )
by Lars
10:50
created

Cache   D

Complexity

Total Complexity 81

Size/Duplication

Total Lines 554
Duplicated Lines 3.61 %

Coupling/Cohesion

Components 2
Dependencies 11

Test Coverage

Coverage 44.25%

Importance

Changes 26
Bugs 11 Features 3
Metric Value
wmc 81
c 26
b 11
f 3
lcom 2
cbo 11
dl 20
loc 554
ccs 100
cts 226
cp 0.4425
rs 4.5142

19 Methods

Rating   Name   Duplication   Size   Complexity  
C __construct() 0 51 13
A setActive() 0 4 1
C isCacheActiveForTheCurrentUser() 0 28 7
B getClientIp() 0 18 7
C checkForDev() 0 29 8
B getTheDefaultPrefix() 0 8 6
F autoConnectToAvailableCacheSystem() 0 121 17
A setCacheIsReady() 0 4 1
A getCacheIsReady() 0 4 1
A getItem() 0 12 3
A calculateStoreKey() 0 10 2
B cleanStoreKey() 0 26 1
A getPrefix() 0 4 1
A setPrefix() 0 4 1
A setItemToDate() 0 12 2
A setItem() 0 19 4
A removeItem() 10 10 2
A removeAll() 0 8 2
A existsItem() 10 10 2

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like Cache 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 Cache, and based on these observations, apply Extract Interface, too.

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
   * __construct
53
   *
54
   * @param null|iAdapter    $adapter
55
   * @param null|iSerializer $serializer
56
   * @param boolean          $checkForUser   check for dev-ip or if cms-user is logged-in
57
   * @param boolean          $cacheEnabled   false will disable the cache (use it e.g. for global settings)
58
   * @param string|boolean   $isAdminSession set a user-id, if the user is a admin (so we can disable cache for this
59
   *                                         user)
60
   */
61 43
  public function __construct($adapter = null, $serializer = null, $checkForUser = true, $cacheEnabled = true, $isAdminSession = false)
62
  {
63 43
    $this->isAdminSession = $isAdminSession;
64
65
    // check for active-cache
66 43
    $this->setActive($cacheEnabled);
67 43
    if ($this->isActive === true && $checkForUser === true) {
68
      $this->setActive($this->isCacheActiveForTheCurrentUser());
69
    }
70
71 43
    if ($this->isActive === true) {
72
73 43
      $this->setPrefix($this->getTheDefaultPrefix());
74
75
      if (
76
          $adapter === null
77 43
          ||
78 43
          !is_object($adapter)
79 43
          ||
80
          !$adapter instanceof iAdapter
81 43
      ) {
82
        $adapter = $this->autoConnectToAvailableCacheSystem();
83
      }
84
85
      // Memcache(d) has his own "serializer", so don't use it twice
86 43
      if (!is_object($serializer) && $serializer === null) {
87
        if (
88
            $adapter instanceof AdapterMemcached
89
            ||
90
            $adapter instanceof AdapterMemcache
91 1
        ) {
92
          $serializer = new SerializerNo();
93
        } else {
94
          // set serializer as default
95
          $serializer = new SerializerIgbinary();
96
        }
97
      }
98 43
    }
99
100
    // check if we will use the cache
101
    if (
102
        $serializer instanceof iSerializer
103 43
        &&
104
        $adapter instanceof iAdapter
105 43
    ) {
106 43
      $this->setCacheIsReady(true);
107
108 43
      $this->adapter = $adapter;
109 43
      $this->serializer = $serializer;
110 43
    }
111 43
  }
112
113
  /**
114
   * enable / disable the cache
115
   *
116
   * @param boolean $isActive
117
   */
118 43
  public function setActive($isActive)
119
  {
120 43
    $this->isActive = (boolean)$isActive;
121 43
  }
122
123
  /**
124
   * check if the current use is a admin || dev || server == client
125
   *
126
   * @return bool
127
   */
128
  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...
129
  {
130
    $active = true;
131
132
    // test the cache, with this GET-parameter
133
    $testCache = isset($_GET['testCache']) ? (int)$_GET['testCache'] : 0;
134
135
    if ($testCache != 1) {
136
      if (
137
        // server == client
138
          (
139
              isset($_SERVER['SERVER_ADDR'])
140
              &&
141
              $_SERVER['SERVER_ADDR'] == $this->getClientIp()
142
          )
143
          ||
144
          // admin is logged-in
145
          $this->isAdminSession
146
          ||
147
          // user is a dev
148
          $this->checkForDev() === true
149
      ) {
150
        $active = false;
151
      }
152
    }
153
154
    return $active;
155
  }
156
157
  /**
158
   * returns the IP address of the client
159
   *
160
   * @param   bool $trust_proxy_headers   Whether or not to trust the
161
   *                                      proxy headers HTTP_CLIENT_IP
162
   *                                      and HTTP_X_FORWARDED_FOR. ONLY
163
   *                                      use if your $_SERVER is behind a
164
   *                                      proxy that sets these values
165
   *
166
   * @return  string
167
   */
168
  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...
169
  {
170
    $remoteAddr = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : 'NO_REMOTE_ADDR';
171
172
    if ($trust_proxy_headers) {
173
      return $remoteAddr;
174
    }
175
176
    if (isset($_SERVER['HTTP_CLIENT_IP']) && $_SERVER['HTTP_CLIENT_IP']) {
177
      $ip = $_SERVER['HTTP_CLIENT_IP'];
178
    } elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR']) && $_SERVER['HTTP_X_FORWARDED_FOR']) {
179
      $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
180
    } else {
181
      $ip = $remoteAddr;
182
    }
183
184
    return $ip;
185
  }
186
187
  /**
188
   * check for developer
189
   *
190
   * @return bool
191
   */
192
  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...
193
  {
194
    $return = false;
195
196
    if (function_exists('checkForDev')) {
197
      $return = checkForDev();
198
    } else {
199
200
      // for testing with dev-address
201
      $noDev = isset($_GET['noDev']) ? (int)$_GET['noDev'] : 0;
202
      $remoteAddr = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : 'NO_REMOTE_ADDR';
203
204
      if (
205
          $noDev != 1
206
          &&
207
          (
208
              $remoteAddr === '127.0.0.1'
209
              ||
210
              $remoteAddr === '::1'
211
              ||
212
              PHP_SAPI === 'cli'
213
          )
214
      ) {
215
        $return = true;
216
      }
217
    }
218
219
    return $return;
220
  }
221
222
  /**
223
   * set the default-prefix via "SERVER"-var + "SESSION"-language
224
   */
225 43
  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...
226
  {
227 43
    return (isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : '') . '_' .
228 43
           (isset($_SERVER['THEME']) ? $_SERVER['THEME'] : '') . '_' .
229 43
           (isset($_SERVER['STAGE']) ? $_SERVER['STAGE'] : '') . '_' .
230 43
           (isset($_SESSION['language']) ? $_SESSION['language'] : '') . '_' .
231 43
           (isset($_SESSION['language_extra']) ? $_SESSION['language_extra'] : '');
232
  }
233
234
  /**
235
   * auto-connect to the available cache-system on the server
236
   *
237
   * @return iAdapter
238
   */
239
  protected function autoConnectToAvailableCacheSystem()
240
  {
241
    static $adapterCache;
242
243
    if (is_object($adapterCache) && $adapterCache instanceof iAdapter) {
244
      return $adapterCache;
245
    } else {
246
247
      $memcached = null;
248
      $isMemcachedAvailable = false;
249
      if (extension_loaded('memcached')) {
250
        $memcached = new \Memcached();
251
        $isMemcachedAvailable = $memcached->addServer('127.0.0.1', '11211');
252
      }
253
254
      if ($isMemcachedAvailable === false) {
255
        $memcached = null;
256
      }
257
258
      $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...
259
      if ($adapterMemcached->installed() === true) {
260
261
        // fallback to Memcached
262
        $adapter = $adapterMemcached;
263
264
      } else {
265
266
        $memcache = null;
267
        $isMemcacheAvailable = false;
268
        if (class_exists('\Memcache')) {
269
          $memcache = new \Memcache;
270
          /** @noinspection PhpUsageOfSilenceOperatorInspection */
271
          $isMemcacheAvailable = @$memcache->connect('127.0.0.1', 11211);
272
        }
273
274
        if ($isMemcacheAvailable === false) {
275
          $memcache = null;
276
        }
277
278
        $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...
279
        if ($adapterMemcache->installed() === true) {
280
281
          // fallback to Memcache
282
          $adapter = $adapterMemcache;
283
284
        } else {
285
286
          $redis = null;
287
          $isRedisAvailable = false;
288
          if (
289
              extension_loaded('redis')
290
              &&
291
              class_exists('\Predis\Client')
292
          ) {
293
            /** @noinspection PhpUndefinedNamespaceInspection */
294
            $redis = new \Predis\Client(
295
                array(
296
                    'scheme'  => 'tcp',
297
                    'host'    => '127.0.0.1',
298
                    'port'    => 6379,
299
                    'timeout' => '2.0',
300
                )
301
            );
302
            try {
303
              $redis->connect();
304
              $isRedisAvailable = $redis->getConnection()->isConnected();
305
            } catch (\Exception $e) {
306
              // nothing
307
            }
308
          }
309
310
          if ($isRedisAvailable === false) {
311
            $redis = null;
312
          }
313
314
          $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...
315
          if ($adapterRedis->installed() === true) {
316
317
            // fallback to Redis
318
            $adapter = $adapterRedis;
319
320
          } else {
321
322
            $adapterXcache = new AdapterXcache();
323
            if ($adapterXcache->installed() === true) {
324
325
              // fallback to Xcache
326
              $adapter = $adapterXcache;
327
328
            } else {
329
330
              $adapterApc = new AdapterApc();
331
              if ($adapterApc->installed() === true) {
332
333
                // fallback to APC || APCu
334
                $adapter = $adapterApc;
335
336
              } else {
337
338
                $adapterFile = new AdapterFile();
339
                if ($adapterFile->installed() === true) {
340
341
                  // fallback to File-Cache
342
                  $adapter = $adapterFile;
343
344
                } else {
345
                  // no cache-adapter available -> use a array
346
                  $adapter = new AdapterArray();
347
                }
348
              }
349
            }
350
          }
351
        }
352
      }
353
354
      // save to static cache
355
      $adapterCache = $adapter;
356
    }
357
358
    return $adapter;
359
  }
360
361
  /**
362
   * set cacheIsReady state
363
   *
364
   * @param boolean $isReady
365
   */
366 43
  private function setCacheIsReady($isReady)
367
  {
368 43
    $this->isReady = (boolean)$isReady;
369 43
  }
370
371
  /**
372
   * get the cacheIsReady state
373
   *
374
   * @return boolean
375
   */
376 5
  public function getCacheIsReady()
377
  {
378 5
    return $this->isReady;
379
  }
380
381
  /**
382
   * get cached-item by key
383
   *
384
   * @param string $key
385
   *
386
   * @return mixed
387
   */
388 20
  public function getItem($key)
389
  {
390 20
    if ($this->adapter instanceof iAdapter) {
391 20
      $storeKey = $this->calculateStoreKey($key);
392 20
      $serialized = $this->adapter->get($storeKey);
393 20
      $value = $serialized ? $this->serializer->unserialize($serialized) : null;
394 20
    } else {
395
      return null;
396
    }
397
398 20
    return $value;
399
  }
400
401
  /**
402
   * calculate store-key (prefix + $rawKey)
403
   *
404
   * @param String $rawKey
405
   *
406
   * @return string
407
   */
408 37
  private function calculateStoreKey($rawKey)
409
  {
410 37
    $str = $this->getPrefix() . $rawKey;
411
412 37
    if ($this->adapter instanceof AdapterFile) {
413 6
      $str = $this->cleanStoreKey($str);
414 6
    }
415
416 37
    return $str;
417
  }
418
419
  /**
420
   * @param string $str
421
   *
422
   * @return string
423
   */
424 6
  private function cleanStoreKey($str)
425
  {
426 6
    $str = preg_replace("/[\r\n\t ]+/", ' ', $str);
427 6
    $str = str_replace(
428 6
        array('"', '*', ':', '<', '>', '?', "'", '|'),
429
        array(
430 6
            '-+-',
431 6
            '-+-+-',
432 6
            '-+-+-+-',
433 6
            '-+-+-+-+-',
434 6
            '-+-+-+-+-+-',
435 6
            '-+-+-+-+-+-+-',
436 6
            '-+-+-+-+-+-+-+-',
437 6
            '-+-+-+-+-+-+-+-+-',
438 6
        ),
439
        $str
440 6
    );
441 6
    $str = html_entity_decode($str, ENT_QUOTES, 'UTF-8');
442 6
    $str = htmlentities($str, ENT_QUOTES, 'UTF-8');
443 6
    $str = preg_replace('/(&)([a-z])([a-z]+;)/i', '$2', $str);
444 6
    $str = str_replace(' ', '-', $str);
445 6
    $str = rawurlencode($str);
446 6
    $str = str_replace('%', '-', $str);
447
448 6
    return $str;
449
  }
450
451
  /**
452
   * @return string
453
   */
454 37
  public function getPrefix()
455
  {
456 37
    return $this->prefix;
457
  }
458
459
  /**
460
   * set prefix [WARNING: do not use if you don't know what you do]
461
   *
462
   * @param string $prefix
463
   */
464 43
  public function setPrefix($prefix)
465
  {
466 43
    $this->prefix = (string)$prefix;
467 43
  }
468
469
  /**
470
   * set cache-item by key => value + date
471
   *
472
   * @param string    $key
473
   * @param mixed     $value
474
   * @param \DateTime $date
475
   *
476
   * @return boolean
477
   * @throws \Exception
478
   */
479 7
  public function setItemToDate($key, $value, \DateTime $date)
480
  {
481 7
    $ttl = $date->getTimestamp() - time();
482
483 7
    if ($ttl <= 0) {
484 1
      throw new \Exception('Date in the past.');
485
    }
486
487 6
    $storeKey = $this->calculateStoreKey($key);
488
489 6
    return $this->setItem($storeKey, $value, $ttl);
490
  }
491
492
  /**
493
   * set cache-item by key => value + ttl
494
   *
495
   * @param string $key
496
   * @param mixed  $value
497
   * @param int    $ttl
498
   *
499
   * @return bool
500
   */
501 20
  public function setItem($key, $value, $ttl = 0)
502
  {
503
    if (
504 20
        $this->adapter instanceof iAdapter
505 20
        &&
506 20
        $this->serializer instanceof iSerializer
507 20
    ) {
508 20
      $storeKey = $this->calculateStoreKey($key);
509 20
      $serialized = $this->serializer->serialize($value);
510
511 20
      if ($ttl) {
512 8
        return $this->adapter->setExpired($storeKey, $serialized, $ttl);
513
      } else {
514 12
        return $this->adapter->set($storeKey, $serialized);
515
      }
516
    } else {
517
      return false;
518
    }
519
  }
520
521
  /**
522
   * remove cached-item
523
   *
524
   * @param string $key
525
   *
526
   * @return bool
527
   */
528 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...
529
  {
530 2
    if ($this->adapter instanceof iAdapter) {
531 2
      $storeKey = $this->calculateStoreKey($key);
532
533 2
      return $this->adapter->remove($storeKey);
534
    } else {
535
      return false;
536
    }
537
  }
538
539
  /**
540
   * remove cache
541
   *
542
   * @return bool
543
   */
544 1
  public function removeAll()
545
  {
546 1
    if ($this->adapter instanceof iAdapter) {
547 1
      return $this->adapter->removeAll();
548
    } else {
549
      return false;
550
    }
551
  }
552
553
  /**
554
   * check if cached-item exists
555
   *
556
   * @param string $key
557
   *
558
   * @return boolean
559
   */
560 7 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...
561
  {
562 7
    if ($this->adapter instanceof iAdapter) {
563 7
      $storeKey = $this->calculateStoreKey($key);
564
565 7
      return $this->adapter->exists($storeKey);
566
    } else {
567
      return false;
568
    }
569
  }
570
571
}
572