Completed
Push — 2.0 ( a52f91...c9f4d8 )
by Marco
12:16
created

AbstractEnhancedProvider   A

Complexity

Total Complexity 35

Size/Duplication

Total Lines 266
Duplicated Lines 53.01 %

Coupling/Cohesion

Components 1
Dependencies 9

Importance

Changes 0
Metric Value
wmc 35
lcom 1
cbo 9
dl 141
loc 266
rs 9
c 0
b 0
f 0

14 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 1
getStats() 0 1 ?
B getItem() 0 24 4
A hasItem() 20 20 3
A clear() 0 16 2
A clearNamespace() 16 16 2
A deleteItem() 20 20 3
A save() 0 20 3
A test() 19 19 2
B getItems() 0 31 5
A deleteItems() 16 16 2
A saveDeferred() 11 11 1
B commit() 25 25 4
A checkQueueNamespace() 14 14 3

How to fix   Duplicated Code   

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:

1
<?php namespace Comodojo\Cache\Providers;
2
3
use \Comodojo\Cache\Traits\StatefulTrait;
4
use \Comodojo\Cache\Traits\NamespaceTrait;
5
use \Comodojo\Cache\Interfaces\EnhancedCacheItemPoolInterface;
6
use \Comodojo\Cache\Components\UniqueId;
7
use \Psr\Log\LoggerInterface;
8
use \Comodojo\Cache\Item;
9
use \Comodojo\Cache\Components\KeyValidator;
10
use \Psr\Cache\CacheItemInterface;
11
use \DateTime;
12
use \Comodojo\Exception\CacheException;
13
use \Comodojo\Exception\InvalidCacheArgumentException;
14
use \Exception;
15
16
/**
17
 * Abstract stateful provider implementation
18
 *
19
 * @package     Comodojo Spare Parts
20
 * @author      Marco Giovinazzi <[email protected]>
21
 * @license     MIT
22
 *
23
 * LICENSE:
24
 *
25
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
28
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
29
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
30
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
31
 * THE SOFTWARE.
32
 */
33
34
abstract class AbstractEnhancedProvider
35
    extends AbstractProvider
0 ignored issues
show
Coding Style introduced by
The extends keyword must be on the same line as the class name
Loading history...
Coding Style introduced by
Expected 0 spaces between "AbstractProvider" and comma; 1 found
Loading history...
36
    implements EnhancedCacheItemPoolInterface {
0 ignored issues
show
Coding Style introduced by
The implements keyword must be on the same line as the class name
Loading history...
37
38
    use StatefulTrait;
39
    use NamespaceTrait;
40
41
    protected $driver;
42
43
    private $queue = [];
44
45
    public function __construct(LoggerInterface $logger = null) {
46
47
        parent::__construct($logger);
48
49
        $this->setId(UniqueId::get())->test();
50
51
    }
52
53
    abstract public function getStats();
54
55
    public function getItem($key) {
56
57
        if ( KeyValidator::validateKey($key) === false ) {
58
            throw new InvalidCacheArgumentException('Invalid key provided');
59
        }
60
61
        try {
62
63
            $data = $this->driver->get($key, $this->getNamespace());
64
65
        } catch (Exception $e) {
66
67
            $this->setState(self::CACHE_ERROR, $e->getMessage());
68
            $data = null;
69
70
        }
71
72
        if ( $data === null ) return new Item($key);
73
74
        $item = new Item($key, true);
75
76
        return $item->set(unserialize($data));
77
78
    }
79
80 View Code Duplication
    public function hasItem($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...
81
82
        if ( KeyValidator::validateKey($key) === false ) {
83
            throw new InvalidCacheArgumentException('Invalid key provided');
84
        }
85
86
        try {
87
88
            $data = $this->driver->has($key, $this->getNamespace());
89
90
        } catch (Exception $e) {
91
92
            $this->setState(self::CACHE_ERROR, $e->getMessage());
93
            $data = false;
94
95
        }
96
97
        return $data;
98
99
    }
100
101
    public function clear() {
102
103
        try {
104
105
            $data = $this->driver->clear();
106
107
        } catch (Exception $e) {
108
109
            $this->setState(self::CACHE_ERROR, $e->getMessage());
110
            $data = false;
111
112
        }
113
114
        return $data;
115
116
    }
117
118 View Code Duplication
    public function clearNamespace() {
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...
119
120
        try {
121
122
            $data = $this->driver->clear($this->getNamespace());
123
124
        } catch (Exception $e) {
125
126
            $this->setState(self::CACHE_ERROR, $e->getMessage());
127
            $data = false;
128
129
        }
130
131
        return $data;
132
133
    }
134
135 View Code Duplication
    public function deleteItem($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...
136
137
        if ( KeyValidator::validateKey($key) === false ) {
138
            throw new InvalidCacheArgumentException('Invalid key provided');
139
        }
140
141
        try {
142
143
            $data = $this->driver->delete($key, $this->getNamespace());
144
145
        } catch (Exception $e) {
146
147
            $this->setState(self::CACHE_ERROR, $e->getMessage());
148
            $data = false;
149
150
        }
151
152
        return $data;
153
154
    }
155
156
    public function save(CacheItemInterface $item) {
157
158
        $ttl = $item->getTtl();
159
160
        if ( $ttl < 0 ) return false;
161
162
        try {
163
164
            $data = $this->driver->set($item->getKey(), $this->getNamespace(), serialize($item->getRaw()), $ttl);
165
166
        } catch (Exception $e) {
167
168
            $this->setState(self::CACHE_ERROR, $e->getMessage());
169
            $data = false;
170
171
        }
172
173
        return $data;
174
175
    }
176
177 View Code Duplication
    public function test() {
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...
178
179
        if ( $this->driver->test() ) {
180
181
            $this->setState(self::CACHE_SUCCESS);
182
183
            return true;
184
185
        }
186
187
        $error = $this->driver->getName()." driver unavailable, disabling provider ".$this->getId()." administratively";
188
189
        $this->logger->error($error);
190
191
        $this->setState(self::CACHE_ERROR, $error);
192
193
        return false;
194
195
    }
196
197
    public function getItems(array $keys = []) {
198
199
        if ( empty($keys) ) return [];
200
201
        $result = [];
202
203
        try {
204
205
            $data = $this->driver->getMultiple($keys, $this->getNamespace());
206
207
        } catch (Exception $e) {
208
209
            $this->setState(self::CACHE_ERROR, $e->getMessage());
210
            $data = array_combine($keys, array_fill(0, count($keys), null));
211
212
        }
213
214
        foreach ( $data as $key => $value ) {
215
216
            if ( $value == null ) {
217
                $result[$key] = new Item($key);
218
            } else {
219
                $result[$key] = new Item($key, true);
220
                $result[$key]->set(unserialize($value));
221
            }
222
223
        }
224
225
        return $result;
226
227
    }
228
229 View Code Duplication
    public function deleteItems(array $keys) {
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...
230
231
        try {
232
233
            $data = $this->driver->deleteMultiple($keys, $this->getNamespace());
234
235
        } catch (Exception $e) {
236
237
            $this->setState(self::CACHE_ERROR, $e->getMessage());
238
            $data = false;
239
240
        }
241
242
        return $data;
243
244
    }
245
246 View Code Duplication
    public function saveDeferred(CacheItemInterface $item) {
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...
247
248
        $this->checkQueueNamespace(true);
249
250
        $namespace = $this->getNamespace();
251
252
        $this->queue[$namespace][$item->getKey()] = $item;
253
254
        return true;
255
256
    }
257
258 View Code Duplication
    public function commit() {
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...
259
260
        $result = [];
261
262
        $active_namespace = $this->getNamespace();
263
264
        foreach ($this->queue as $namespace => $queue) {
265
266
            $this->setNamespace($namespace);
267
268
            foreach ($queue as $key => $item) {
269
270
                $result[] = $this->save($item);
271
272
            }
273
274
        }
275
276
        $this->queue = [];
277
278
        $this->setNamespace($active_namespace);
279
280
        return in_array(false, $result) ? false : true;
281
282
    }
283
284 View Code Duplication
    private function checkQueueNamespace($create = false) {
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...
285
286
        $namespace = $this->getNamespace();
287
288
        if ( array_key_exists($namespace, $this->queue) ) {
289
            return true;
290
        } else if ( $create ) {
291
            $this->queue[$namespace] = [];
292
            return true;
293
        } else {
294
            return false;
295
        }
296
297
    }
298
299
}
300