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

AbstractEnhancedProvider::set()   C

Complexity

Conditions 7
Paths 8

Size

Total Lines 30
Code Lines 15

Duplication

Lines 3
Ratio 10 %

Importance

Changes 0
Metric Value
dl 3
loc 30
rs 6.7272
c 0
b 0
f 0
cc 7
eloc 15
nc 8
nop 3
1
<?php namespace Comodojo\SimpleCache\Providers;
2
3
use \Comodojo\Cache\Traits\StatefulTrait;
4
use \Comodojo\Cache\Traits\NamespaceTrait;
5
use \Comodojo\SimpleCache\Interfaces\EnhancedSimpleCacheInterface;
6
use \Comodojo\Cache\Components\UniqueId;
7
use \Psr\Log\LoggerInterface;
8
use \Comodojo\Cache\Components\KeyValidator;
9
use \DateTime;
10
use \DateInterval;
11
use \Traversable;
12
use \Comodojo\Exception\SimpleCacheException;
13
use \Comodojo\Exception\InvalidSimpleCacheArgumentException;
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 EnhancedSimpleCacheInterface {
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 = [];
0 ignored issues
show
Unused Code introduced by
The property $queue is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
44
45
    public function __construct(LoggerInterface $logger = null) {
46
47
        parent::__construct($logger);
48
49
        $this->setId(UniqueId::get())->test();
50
51
    }
52
53
    public function get($key, $default = null) {
54
55
        if ( KeyValidator::validateKey($key) === false ) {
56
            throw new InvalidSimpleCacheArgumentException('Invalid key provided');
57
        }
58
59
        try {
60
61
            $data = $this->driver->get($key, $this->getNamespace());
62
63
        } catch (Exception $e) {
64
65
            $this->setState(self::CACHE_ERROR, $e->getMessage());
66
            $data = null;
67
68
        }
69
70
        if ( $data === null ) return $default;
71
72
        return unserialize($data);
73
74
    }
75
76
    public function set($key, $value, $ttl = null) {
77
78
        if ( KeyValidator::validateKey($key) === false ) {
79
            throw new InvalidSimpleCacheArgumentException('Invalid key provided');
80
        }
81
82
        if ( $value === null ) {
83
            throw new InvalidSimpleCacheArgumentException('Cannot cache a null value');
84
        }
85
86
        $real_ttl;
0 ignored issues
show
Bug introduced by
The variable $real_ttl seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?

This error can happen if you refactor code and forget to move the variable initialization.

Let’s take a look at a simple example:

function someFunction() {
    $x = 5;
    echo $x;
}

The above code is perfectly fine. Now imagine that we re-order the statements:

function someFunction() {
    echo $x;
    $x = 5;
}

In that case, $x would be read before it is initialized. This was a very basic example, however the principle is the same for the found issue.

Loading history...
87
88 View Code Duplication
        if ( $ttl == null || $ttl == 0 ) $real_ttl = 0;
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing $ttl of type null|integer|Psr\SimpleCache\DateInterval against null; this is ambiguous if the integer can be zero. Consider using a strict comparison === instead.
Loading history...
Duplication introduced by
This code seems to be duplicated across 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...
89
        else if ( $ttl instanceof DateInterval ) $real_ttl = $ttl->format('%s');
90
        else $real_ttl = intval($ttl);
91
92
        try {
93
94
            $data = $this->driver->set($key, $this->getNamespace(), serialize($value), $real_ttl);
95
96
        } catch (Exception $e) {
97
98
            $this->setState(self::CACHE_ERROR, $e->getMessage());
99
            $data = false;
100
101
        }
102
103
        return $data;
104
105
    }
106
107 View Code Duplication
    public function delete($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...
108
109
        if ( KeyValidator::validateKey($key) === false ) {
110
            throw new InvalidSimpleCacheArgumentException('Invalid key provided');
111
        }
112
113
        try {
114
115
            $data = $this->driver->delete($key, $this->getNamespace());
116
117
        } catch (Exception $e) {
118
119
            $this->setState(self::CACHE_ERROR, $e->getMessage());
120
            $data = false;
121
122
        }
123
124
        return $data;
125
126
    }
127
128
    public function clear() {
129
130
        try {
131
132
            $data = $this->driver->clear();
133
134
        } catch (Exception $e) {
135
136
            $this->setState(self::CACHE_ERROR, $e->getMessage());
137
            $data = false;
138
139
        }
140
141
        return $data;
142
143
    }
144
145
    public function getMultiple($keys, $default = null) {
146
147
        if ( !is_array($keys) && !($keys instanceof Traversable ) ) {
148
            throw new InvalidSimpleCacheArgumentException('Invalid keys provided');
149
        }
150
151
        foreach ($keys as $key) {
152
            if ( KeyValidator::validateKey($key) === false ) {
153
                throw new InvalidSimpleCacheArgumentException('Invalid key provided');
154
            }
155
        }
156
157
        try {
158
159
            $data = $this->driver->getMultiple($keys, $this->getNamespace());
160
161
        } catch (Exception $e) {
162
163
            $this->setState(self::CACHE_ERROR, $e->getMessage());
164
            $data = array_combine($keys, array_fill(0, count($keys), null));
165
166
        }
167
168
        return array_map(function($value) use($default) {
169
            if ( $value === null ) return $default;
170
            return unserialize($value);
171
        }, $data);
172
173
    }
174
175
    public function setMultiple($values, $ttl = null) {
176
177
        if ( !is_array($values) && !($values instanceof Traversable ) ) {
178
            throw new InvalidSimpleCacheArgumentException('Invalid keys provided');
179
        }
180
181
        $real_values = [];
182
183
        foreach ($values as $key => $value) {
184
            if ( KeyValidator::validateKey($key) === false ) {
185
                throw new InvalidSimpleCacheArgumentException('Invalid key provided');
186
            }
187
            if ( $value === null ) {
188
                throw new InvalidSimpleCacheArgumentException('Cannot cache a null value');
189
            }
190
            $real_values[$key] = serialize($value);
191
        }
192
193
        $real_ttl;
0 ignored issues
show
Bug introduced by
The variable $real_ttl seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?

This error can happen if you refactor code and forget to move the variable initialization.

Let’s take a look at a simple example:

function someFunction() {
    $x = 5;
    echo $x;
}

The above code is perfectly fine. Now imagine that we re-order the statements:

function someFunction() {
    echo $x;
    $x = 5;
}

In that case, $x would be read before it is initialized. This was a very basic example, however the principle is the same for the found issue.

Loading history...
194
195 View Code Duplication
        if ( $ttl == null || $ttl == 0 ) $real_ttl = 0;
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing $ttl of type null|integer|Psr\SimpleCache\DateInterval against null; this is ambiguous if the integer can be zero. Consider using a strict comparison === instead.
Loading history...
Duplication introduced by
This code seems to be duplicated across 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...
196
        else if ( $ttl instanceof DateInterval ) $real_ttl = $ttl->format('%s');
197
        else $real_ttl = intval($ttl);
198
199
        try {
200
201
            $data = $this->driver->setMultiple($real_values, $this->getNamespace(), $real_ttl);
202
203
        } catch (Exception $e) {
204
205
            $this->setState(self::CACHE_ERROR, $e->getMessage());
206
            $data = false;
207
208
        }
209
210
        return $data;
211
212
    }
213
214
    public function deleteMultiple($keys) {
215
216
        if ( !is_array($keys) && !($keys instanceof Traversable ) ) {
217
            throw new InvalidSimpleCacheArgumentException('Invalid keys provided');
218
        }
219
220
        foreach ($keys as $key) {
221
            if ( KeyValidator::validateKey($key) === false ) {
222
                throw new InvalidSimpleCacheArgumentException('Invalid key provided');
223
            }
224
        }
225
226
        try {
227
228
            $data = $this->driver->deleteMultiple($keys, $this->getNamespace());
229
230
        } catch (Exception $e) {
231
232
            $this->setState(self::CACHE_ERROR, $e->getMessage());
233
            $data = false;
234
235
        }
236
237
        return $data;
238
239
    }
240
241 View Code Duplication
    public function has($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...
242
243
        if ( KeyValidator::validateKey($key) === false ) {
244
            throw new InvalidSimpleCacheArgumentException('Invalid key provided');
245
        }
246
247
        try {
248
249
            $data = $this->driver->has($key, $this->getNamespace());
250
251
        } catch (Exception $e) {
252
253
            $this->setState(self::CACHE_ERROR, $e->getMessage());
254
            $data = false;
255
256
        }
257
258
        return $data;
259
260
    }
261
262
    abstract public function getStats();
263
264 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...
265
266
        try {
267
268
            $data = $this->driver->clear($this->getNamespace());
269
270
        } catch (Exception $e) {
271
272
            $this->setState(self::CACHE_ERROR, $e->getMessage());
273
            $data = false;
274
275
        }
276
277
        return $data;
278
279
    }
280
281 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...
282
283
        if ( $this->driver->test() ) {
284
285
            $this->setState(self::CACHE_SUCCESS);
286
287
            return true;
288
289
        }
290
291
        $error = $this->driver->getName()." driver unavailable, disabling provider ".$this->getId()." administratively";
292
293
        $this->logger->error($error);
294
295
        $this->setState(self::CACHE_ERROR, $error);
296
297
        return false;
298
299
    }
300
301
}
302