Completed
Pull Request — master (#34)
by Carlos
02:34
created

MemcachedAdapter   B

Complexity

Total Complexity 36

Size/Duplication

Total Lines 139
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
wmc 36
lcom 1
cbo 3
dl 0
loc 139
rs 8.8
c 0
b 0
f 0

11 Methods

Rating   Name   Duplication   Size   Complexity  
C __construct() 0 39 11
A get() 0 10 2
A getMulti() 0 4 1
A set() 0 4 1
A setMulti() 0 4 1
A contains() 0 10 2
A delete() 0 6 1
A deleteMulti() 0 6 1
A flush() 0 4 1
C validateMemcacheConfiguration() 0 24 14
A setNamespace() 0 5 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Linio\Component\Cache\Adapter;
6
7
use Linio\Component\Cache\Exception\InvalidConfigurationException;
8
use Linio\Component\Cache\Exception\KeyNotFoundException;
9
use Memcached;
10
11
class MemcachedAdapter extends AbstractAdapter implements AdapterInterface
12
{
13
    /**
14
     * @var int
15
     */
16
    protected $ttl;
17
18
    /**
19
     * @var Memcached
20
     */
21
    protected $memcached;
22
23
    public function __construct(array $config = [])
24
    {
25
        $this->validateMemcacheConfiguration($config);
26
27
        // default config
28
        $this->ttl = 0;
29
30
        // config
31
        if (isset($config['ttl'])) {
32
            $this->ttl = $config['ttl'];
33
        }
34
35
        $persistentId = null;
36
        if (isset($config['connection_persistent']) && $config['connection_persistent']) {
37
            $persistentId = '1';
38
39
            if (isset($config['pool_size']) && $config['pool_size'] > 1) {
40
                $persistentId = (string) mt_rand(1, $config['pool_size']);
41
            }
42
        }
43
44
        $this->memcached = new Memcached($persistentId);
45
46
        if (empty($this->memcached->getServerList())) {
47
            $this->memcached->addServers($config['servers']);
48
        }
49
50
        if (isset($config['options']) && !empty($config['options'])) {
51
            $this->memcached->setOptions($config['options']);
0 ignored issues
show
Bug introduced by
The method setOptions() does not exist on Memcached. Did you maybe mean setOption()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
52
        }
53
54
        if ($this->namespace) {
55
            $this->memcached->setOption(Memcached::OPT_PREFIX_KEY, $this->namespace);
56
        }
57
58
        if (isset($config['cache_not_found_keys'])) {
59
            $this->cacheNotFoundKeys = (bool) $config['cache_not_found_keys'];
60
        }
61
    }
62
63
    public function get(string $key)
64
    {
65
        $value = $this->memcached->get($key);
66
67
        if ($this->memcached->getResultCode() == Memcached::RES_NOTFOUND) {
68
            throw new KeyNotFoundException();
69
        }
70
71
        return $value;
72
    }
73
74
    public function getMulti(array $keys): array
75
    {
76
        return $this->memcached->getMulti($keys);
77
    }
78
79
    public function set(string $key, $value): bool
80
    {
81
        return $this->memcached->set($key, $value, $this->ttl);
82
    }
83
84
    public function setMulti(array $data): bool
85
    {
86
        return $this->memcached->setMulti($data, $this->ttl);
87
    }
88
89
    public function contains(string $key): bool
90
    {
91
        try {
92
            $this->get($key);
93
        } catch (KeyNotFoundException $exception) {
94
            return false;
95
        }
96
97
        return true;
98
    }
99
100
    public function delete(string $key): bool
101
    {
102
        $this->memcached->delete($key);
103
104
        return true;
105
    }
106
107
    public function deleteMulti(array $keys): bool
108
    {
109
        $this->memcached->deleteMulti($keys);
0 ignored issues
show
Bug introduced by
The method deleteMulti() does not exist on Memcached. Did you maybe mean delete()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
110
111
        return true;
112
    }
113
114
    public function flush(): bool
115
    {
116
        return $this->memcached->flush();
117
    }
118
119
    protected function validateMemcacheConfiguration(array $config)
120
    {
121
        if (!array_key_exists('servers', $config)) {
122
            throw new InvalidConfigurationException('Missing configuration parameter: servers');
123
        }
124
125
        if (!is_array($config['servers'])) {
126
            throw new InvalidConfigurationException('Invalid configuration parameter: servers');
127
        }
128
129
        foreach ($config['servers'] as $server) {
130
            if (!is_array($server) || count($server) < 2 || count($server) > 3 || !is_numeric($server[1]) || (isset($server[2]) && !is_numeric($server[2]))) {
131
                throw new InvalidConfigurationException('Invalid configuration parameter: servers');
132
            }
133
        }
134
135
        if (array_key_exists('options', $config) && !is_array($config['options'])) {
136
            throw new InvalidConfigurationException('Invalid configuration parameter: options');
137
        }
138
139
        if (isset($config['ttl']) && !is_numeric($config['ttl'])) {
140
            throw new InvalidConfigurationException('Invalid configuration parameter: ttl');
141
        }
142
    }
143
144
    public function setNamespace(string $namespace)
145
    {
146
        parent::setNamespace($namespace);
147
        $this->memcached->setOption(Memcached::OPT_PREFIX_KEY, $this->namespace);
148
    }
149
}
150