MemcachedDriver   A
last analyzed

Complexity

Total Complexity 18

Size/Duplication

Total Lines 133
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 35
dl 0
loc 133
rs 10
c 0
b 0
f 0
wmc 18

8 Methods

Rating   Name   Duplication   Size   Complexity  
A getInstance() 0 3 1
A clear() 0 3 1
A check() 0 3 1
A checkMultidimensionalConfigArray() 0 4 2
A checkSimpleConfigArray() 0 4 2
A setConfig() 0 14 3
A __construct() 0 8 2
A connect() 0 29 6
1
<?php
2
/**
3
 * This file is part of the InMemoryList package.
4
 *
5
 * (c) Mauro Cassani<https://github.com/mauretto78>
6
 *
7
 *  For the full copyright and license information, please view the LICENSE
8
 *  file that was distributed with this source code.
9
 */
10
11
namespace InMemoryList\Infrastructure\Drivers;
12
13
use InMemoryList\Infrastructure\Drivers\Contracts\DriverInterface;
14
use InMemoryList\Infrastructure\Drivers\Exceptions\MemcachedDriverCheckException;
15
use InMemoryList\Infrastructure\Drivers\Exceptions\MemcachedDriverConnectionException;
16
use InMemoryList\Infrastructure\Drivers\Exceptions\MemcachedMalformedConfigException;
17
use Memcached;
18
19
class MemcachedDriver implements DriverInterface
20
{
21
    /**
22
     * @var
23
     */
24
    private $config;
25
26
    /**
27
     * @var \Memcached
28
     */
29
    private $instance;
30
31
    /**
32
     * MemcachedDriver constructor.
33
     *
34
     * @codeCoverageIgnore
35
     *
36
     * @param array $config
37
     *
38
     * @throws MemcachedDriverCheckException
39
     */
40
    public function __construct(array $config = [])
41
    {
42
        $this->setConfig($config);
43
        if (!$this->check()) {
44
            throw new MemcachedDriverCheckException('Memcached is not loaded.');
45
        }
46
47
        $this->connect();
48
    }
49
50
    /**
51
     * @param $config
52
     *
53
     * @throws MemcachedMalformedConfigException
54
     */
55
    private function setConfig($config)
56
    {
57
        $allowedConfigKeys = [
58
            'host',
59
            'port',
60
            'sasl_user',
61
            'sasl_password',
62
        ];
63
64
        foreach ($config as $key => $server) {
65
            (false === is_array($server)) ? $this->checkSimpleConfigArray($key, $allowedConfigKeys) : $this->checkMultidimensionalConfigArray($server, $allowedConfigKeys);
66
        }
67
68
        $this->config = $config;
69
    }
70
71
    /**
72
     * @param $key
73
     * @param $allowedConfigKeys
74
     *
75
     * @throws MemcachedMalformedConfigException
76
     */
77
    private function checkSimpleConfigArray($key, $allowedConfigKeys)
78
    {
79
        if (!in_array($key, $allowedConfigKeys)) {
80
            throw new MemcachedMalformedConfigException();
81
        }
82
    }
83
84
    /**
85
     * @param $server
86
     * @param $allowedConfigKeys
87
     */
88
    private function checkMultidimensionalConfigArray($server, $allowedConfigKeys)
89
    {
90
        foreach (array_keys($server) as $key) {
91
            $this->checkSimpleConfigArray($key, $allowedConfigKeys);
92
        }
93
    }
94
95
    /**
96
     * @codeCoverageIgnore
97
     *
98
     * @return bool
99
     */
100
    public function check()
101
    {
102
        return class_exists('\Memcached');
103
    }
104
105
    /**
106
     * @return bool
107
     */
108
    public function clear()
109
    {
110
        return $this->instance->flush();
111
    }
112
113
    public function connect()
114
    {
115
        $this->instance = new Memcached();
116
        $servers = $this->config ?: [];
117
118
        // if $servers is empty, connect with default parameters
119
        if (count($servers) < 1) {
120
            $servers = [
121
                [
122
                    'host' => '127.0.0.1',
123
                    'port' => 11211,
124
                ],
125
            ];
126
        }
127
128
        // if $servers is a monodimensional array convert to multidimensional
129
        if (!isset($servers[0])) {
130
            $servers = [
131
                [
132
                    'host' => $servers['host'],
133
                    'port' => $servers['port'],
134
                ],
135
            ];
136
        }
137
138
        // loop all servers
139
        foreach ($servers as $server) {
140
            if (!$this->instance->addServer($server['host'], $server['port'])) {
141
                throw new MemcachedDriverConnectionException('Memcached connection refused: [host'.$server['host'].' port'.$server['port'].']');
142
            }
143
        }
144
    }
145
146
    /**
147
     * @return mixed
148
     */
149
    public function getInstance()
150
    {
151
        return $this->instance;
152
    }
153
}
154