Completed
Push — 2.0 ( beffc6...ae2d90 )
by Marco
14:38
created

Cache::getAutoSetTime()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
c 1
b 1
f 0
dl 0
loc 5
rs 9.4285
cc 1
eloc 2
nc 1
nop 0
1
<?php namespace Comodojo\Cache;
2
3
use \Comodojo\Cache\Components\StackManager;
4
use \Comodojo\Cache\Providers\AbstractProvider;
5
use \Comodojo\Cache\Providers\ProviderInterface;
6
use \Psr\Log\LoggerInterface;
7
use \Comodojo\Exception\CacheException;
8
use \Exception;
9
10
/**
11
 * Cache manager
12
 *
13
 * @package     Comodojo Spare Parts
14
 * @author      Marco Giovinazzi <[email protected]>
15
 * @license     MIT
16
 *
17
 * LICENSE:
18
 *
19
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25
 * THE SOFTWARE.
26
 */
27
28
class Cache extends AbstractProvider {
29
30
    /**
31
     * Select the first (enabled) provider in queue, do not traverse the queue.
32
     */
33
    const PICK_FIRST = 1;
34
35
    /**
36
     * Select the last (enabled) provider in queue, do not traverse the queue.
37
     */
38
    const PICK_LAST = 2;
39
40
    /**
41
     * Select a random (enabled) provider in queue, do not traverse the queue.
42
     */
43
    const PICK_RANDOM = 3;
44
45
    /**
46
     * Select by weight, stop at first enabled provider.
47
     */
48
    const PICK_BYWEIGHT = 4;
49
50
    /**
51
     * Ask to all (enabled) providers and match responses.
52
     */
53
    const PICK_ALL = 5;
54
55
    /**
56
     * Select the first (enabled) provider, in case of null response traverse
57
     * the queue.
58
     */
59
    const PICK_TRAVERSE = 6;
60
61
    protected $selector;
62
63
    protected $stack;
64
65
    protected $provider;
66
67
    protected $auto_set_time = false;
68
69
    public function __construct($select_mode = null, LoggerInterface $logger = null, $default_ttl = 3600, $flap_interval = 600) {
0 ignored issues
show
Unused Code introduced by
The parameter $default_ttl is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
70
71
        $this->selector = filter_var($select_mode, FILTER_VALIDATE_INT, array(
72
            'options' => array(
73
                'min_range' => 1,
74
                'max_range' => 6,
75
                'default'   => 1
76
            )
77
        ));
78
79
        $this->stack = new StackManager($flap_interval);
80
81
        parent::__construct($logger);
82
83
    }
84
85
    public function getAutoSetTime() {
86
87
        return $this->auto_set_time;
88
89
    }
90
91
    public function setAutoSetTime($mode=true) {
92
93
        $this->auto_set_time = filter_var($mode, FILTER_VALIDATE_BOOLEAN, array(
94
            'options' => array(
95
                'default'   => true
96
            )
97
        ));
98
99
        return $this;
100
101
    }
102
103
    public function setFlapInterval($ttl) {
104
105
        $ttl = filter_var($ttl, FILTER_VALIDATE_INT, array(
106
            'options' => array(
107
                'min_range' => 1,
108
                'default'   => 700
109
            )
110
        ));
111
112
        return $this->stack->setFlapInterval($ttl);
113
114
    }
115
116
    public function getFlapInterval() {
117
118
        return $this->stack->getFlapInterval();
119
    }
120
121
    public function addProvider(ProviderInterface $provider, $weight = 0) {
122
123
        try {
124
125
            if ( $provider->isEnabled() === false ) {
126
127
                $id = $provider->getCacheId();
128
                $type = get_class($provider);
129
130
                $this->logger->warning("Adding provider $type [$id] as disabled: it will never serve cache requests");
131
132
            }
133
134
            $provider->setTime($this->getTime())
135
                ->setTtl($this->getTtl())
136
                ->setLogger($this->getLogger());
137
138
            $id = $this->stack->add($provider, $weight);
139
140
        } catch (CacheException $ce) {
141
142
            throw $ce;
143
144
        }
145
146
        return $id;
147
148
    }
149
150
    public function removeProvider($id) {
151
152
        $this->stack->remove($id);
153
154
    }
155
156
    public function getProvider($id) {
157
158
        return $this->stack->get($id);
159
160
    }
161
162
    public function getProviders($enabled=false) {
163
164
        return $enabled ? $this->stack->getAll() : $this->stack->getAll(false);
165
166
    }
167
168
    public function getSelectedProvider() {
169
170
        return $this->provider;
171
172
    }
173
174
    /* Following methods implement ProviderInterface */
175
176
    // public function getNamespace();
0 ignored issues
show
Unused Code Comprehensibility introduced by
56% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
177
178
    public function setNamespace($namespace = null) {
179
180
        $return = parent::setNamespace($namespace);
181
182
        foreach ( $this->stack->getAll(false) as $provider ) $provider->setNamespace($namespace);
183
184
        return $return;
185
186
    }
187
188 View Code Duplication
    public function setTime($time = null) {
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...
189
190
        $return = parent::setTime($time);
191
192
        foreach ( $this->stack->getAll(false) as $provider ) $provider->setTime($time);
193
194
        return $return;
195
196
    }
197
198 View Code Duplication
    public function setTtl($ttl = null) {
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...
199
200
        $return = parent::setTtl($ttl);
201
202
        foreach ( $this->stack->getAll(false) as $provider ) $provider->setTtl($ttl);
203
204
        return $return;
205
206
    }
207
208
    public function setLogger(LoggerInterface $logger = null) {
209
210
        $return = parent::setLogger($logger);
211
212
        foreach ( $this->stack->getAll(false) as $provider ) $provider->setLogger($logger);
213
214
        return $return;
215
216
    }
217
218
    public function set($name, $data, $ttl = null) {
219
220
        if ( !$this->isEnabled() ) return false;
221
222
        if ( $this->auto_set_time ) $this->setTime();
223
224
        $set = array();
225
226
        foreach ($this->stack->getAll() as $id => $provider) {
227
228
            $set[] = $provider->set($name, $data, $ttl);
229
230
            if ( $provider->getErrorState() ) $this->stack->disable($id);
231
232
        };
233
234
        return !in_array(false, $set);
235
236
    }
237
238
    public function get($name) {
239
240
        if ( !$this->isEnabled() ) return null;
241
242
        if ( $this->auto_set_time ) $this->setTime();
243
244
        if ( $this->selector < 5 ) {
245
246
            $result = $this->getFromSingleProvider($this->selector, $name);
247
248
        } else if ( $this->selector == 5 ) {
249
250
            $result = $this->getFromAllProviders($name);
251
252
        } else {
253
254
            $result = $this->getTraverse($name);
255
256
        }
257
258
        return $result;
259
260
    }
261
262 View Code Duplication
    public function delete($name=null) {
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...
263
264
        if ( !$this->isEnabled() ) return false;
265
266
        $delete = array();
267
268
        foreach ($this->stack->getAll() as $id => $provider) {
269
270
            $delete[] = $provider->delete($name);
271
272
            if ( $provider->getErrorState() ) $this->stack->disable($id);
273
274
        };
275
276
        return !in_array(false, $delete);
277
278
    }
279
280 View Code Duplication
    public function flush() {
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...
281
282
        if ( !$this->isEnabled() ) return false;
283
284
        $flush = array();
285
286
        foreach ($this->stack->getAll() as $id => $provider) {
287
288
            $flush[] = $provider->flush();
289
290
            if ( $provider->getErrorState() ) $this->stack->disable($id);
291
292
        };
293
294
        return !in_array(false, $flush);
295
296
    }
297
298
    public function status() {
299
300
        $return = array();
301
302
        if ( !$this->isEnabled() ) {
303
304
            foreach ($this->stack->getAll(false) as $id => $provider) {
305
                $return[] = array(
306
                    "provider"  => get_class($provider),
307
                    "enabled"   => false,
308
                    "objects"   => null,
309
                    "options"   => array()
310
                );
311
            }
312
313
        } else {
314
315
            foreach ($this->stack->getAll(false) as $id => $provider) {
316
                $return[] = $provider->status();
317
            }
318
319
        }
320
321
        return $return;
322
323
    }
324
325
    // public function getCacheId();
0 ignored issues
show
Unused Code Comprehensibility introduced by
56% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
326
327
    // public function getLogger();
0 ignored issues
show
Unused Code Comprehensibility introduced by
56% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
328
329
    // public function setErrorState($message = null);
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
330
    // public function resetErrorState();
0 ignored issues
show
Unused Code Comprehensibility introduced by
56% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
331
    // public function getErrorState();
0 ignored issues
show
Unused Code Comprehensibility introduced by
56% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
332
    // public function getErrorMessage();
0 ignored issues
show
Unused Code Comprehensibility introduced by
56% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
333
334
335
    private function getFromSingleProvider($selector, $name) {
0 ignored issues
show
Unused Code introduced by
The parameter $selector is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
336
337
        switch ($this->selector) {
338
339
            case 1:
340
                $this->provider = $this->stack->getFirst();
341
                break;
342
            case 2:
343
                $this->provider = $this->stack->getLast();
344
                break;
345
            case 3:
346
                $this->provider = $this->stack->getRandom();
347
                break;
348
            case 4:
349
                $this->provider = $this->stack->getByWeight();
350
                break;
351
352
        }
353
354
        $result = $this->provider->get($name);
355
356
        if ( $this->provider->getErrorState() ) $this->stack->disable($this->provider->getCacheId());
357
358
        return $result;
359
360
    }
361
362
    private function getFromAllProviders($name) {
363
364
        $data = array();
365
366
        $providers = $this->stack->getAll();
367
368
        foreach ($providers as $id => $provider) {
369
            $data[] = $this->provider->get($name);
370
            if ( $this->provider->getErrorState() ) $this->stack->disable($this->provider->getCacheId());
371
        }
372
373
        $values = array_unique(array_map('serialize', $data));
374
375
        if (count($values) == 1) {
376
            return $data[0];
377
        }
378
379
        return null;
380
381
    }
382
383
    private function getTraverse($name) {
384
385
        $data = null;
386
387
        $providers = $this->stack->getAll();
388
389
        foreach ($providers as $id => $provider) {
390
            $data = $provider->get($name);
391
            if ( $provider->getErrorState() ) {
392
                $this->stack->disable($provider->getCacheId());
393
            } else {
394
                if ( $data != null ) return $data;
395
            }
396
        }
397
398
        return $data;
399
400
    }
401
402
}
403