Manager::createFromConfiguration()   A
last analyzed

Complexity

Conditions 3
Paths 2

Size

Total Lines 17
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 3

Importance

Changes 0
Metric Value
eloc 10
dl 0
loc 17
ccs 11
cts 11
cp 1
rs 9.9332
c 0
b 0
f 0
cc 3
nc 2
nop 3
crap 3
1
<?php namespace Comodojo\Cache;
2
3
use \Comodojo\Cache\Item;
4
use \Comodojo\Cache\Providers\AbstractProvider;
5
use \Comodojo\Cache\Providers\Vacuum;
6
use \Comodojo\Cache\Interfaces\CacheItemPoolManagerInterface;
7
use \Comodojo\Cache\Interfaces\EnhancedCacheItemPoolInterface;
8
use \Comodojo\Cache\Traits\NamespaceTrait;
9
use \Comodojo\Cache\Traits\BasicCacheItemPoolTrait;
10
use \Comodojo\Cache\Traits\GenericManagerTrait;
11
use \Comodojo\Cache\Components\StackManager;
12
use \Comodojo\Foundation\Validation\DataFilter;
13
use \Comodojo\Cache\Components\ConfigurationParser;
14
use \Comodojo\Foundation\Base\Configuration;
15
use \Psr\Cache\CacheItemInterface;
16
use \Psr\Log\LoggerInterface;
17
use \ArrayObject;
18
19
/**
20
 * @package     Comodojo Cache
21
 * @author      Marco Giovinazzi <[email protected]>
22
 * @license     MIT
23
 *
24
 * LICENSE:
25
 *
26
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
27
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
29
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
30
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
31
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
32
 * THE SOFTWARE.
33
 */
34
35
class Manager extends AbstractProvider implements CacheItemPoolManagerInterface {
36
37
    use NamespaceTrait, GenericManagerTrait {
38
        GenericManagerTrait::setNamespace insteadof NamespaceTrait;
39
    }
40
    use BasicCacheItemPoolTrait;
41
42
    const DEFAULT_PICK_MODE = 1;
43
44
    protected $pick_mode;
45
46
    protected $stack;
47
48
    protected $align_cache;
49
50
    protected $vacuum;
51
52
    protected $selected;
53
54 46
    public function __construct(
55
        $pick_mode = null,
56
        LoggerInterface $logger = null,
57
        $align_cache = true,
58
        $flap_interval = null
59
    ) {
60
61 46
        $this->pick_mode = DataFilter::filterInteger($pick_mode, 1, 6, self::DEFAULT_PICK_MODE);
0 ignored issues
show
Bug introduced by
6 of type integer is incompatible with the type array expected by parameter $max of Comodojo\Foundation\Vali...Filter::filterInteger(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

61
        $this->pick_mode = DataFilter::filterInteger($pick_mode, 1, /** @scrutinizer ignore-type */ 6, self::DEFAULT_PICK_MODE);
Loading history...
Bug introduced by
1 of type integer is incompatible with the type array expected by parameter $min of Comodojo\Foundation\Vali...Filter::filterInteger(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

61
        $this->pick_mode = DataFilter::filterInteger($pick_mode, /** @scrutinizer ignore-type */ 1, 6, self::DEFAULT_PICK_MODE);
Loading history...
Bug introduced by
self::DEFAULT_PICK_MODE of type integer is incompatible with the type array expected by parameter $default of Comodojo\Foundation\Vali...Filter::filterInteger(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

61
        $this->pick_mode = DataFilter::filterInteger($pick_mode, 1, 6, /** @scrutinizer ignore-type */ self::DEFAULT_PICK_MODE);
Loading history...
62
63 46
        $this->align_cache = DataFilter::filterBoolean($align_cache, false);
0 ignored issues
show
Bug introduced by
false of type false is incompatible with the type array expected by parameter $default of Comodojo\Foundation\Vali...Filter::filterBoolean(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

63
        $this->align_cache = DataFilter::filterBoolean($align_cache, /** @scrutinizer ignore-type */ false);
Loading history...
64
65 46
        $stack = new ArrayObject([]);
66
67 46
        $this->stack = new StackManager($stack->getIterator());
68 46
        $this->stack->setFlapInterval($flap_interval);
69
70 46
        parent::__construct($logger);
71
72 46
        $this->vacuum = new Vacuum([], $this->logger);
73
74 46
        $this->logger->debug("Cache manager online; pick mode ".$this->pick_mode);
75
76 46
    }
77
78 45
    public function addProvider(EnhancedCacheItemPoolInterface $provider, $weight = 0) {
79
80 45
        return $this->genericAddProvider($provider, $weight);
81
82
    }
83
84 42
    public function getItem($key) {
85
86 42
        return $this->selectFrom('GET', $key);
87
88
    }
89
90 21
    public function hasItem($key) {
91
92 21
        return $this->selectFrom('HAS', $key);
93
94
    }
95
96 4
    public function deleteItem($key) {
97
98 4
        if ( iterator_count($this->stack) == 0 ) return $this->vacuum->deleteItem($key);
99
100 3
        if ( $this->align_cache === false && $this->pick_mode < 5 ) {
0 ignored issues
show
introduced by
The condition $this->align_cache === false is always false.
Loading history...
101
            return $this->selectProvider()->deleteItem($key);
102
        }
103
104 3
        $result = [];
105
106 3
        foreach ( $this->stack as $provider ) {
107
108 3
            $result[] = $provider[0]->deleteItem($key);
109
110
        }
111
112 3
        return !in_array(false, $result);
113
114
    }
115
116 37
    public function save(CacheItemInterface $item) {
117
118 37
        if ( iterator_count($this->stack) == 0 ) return $this->vacuum->save($item);
119
120 36
        if ( $this->align_cache === false && $this->pick_mode < 5 ) {
0 ignored issues
show
introduced by
The condition $this->align_cache === false is always false.
Loading history...
121 1
            return $this->selectProvider()->save($item);
122
        }
123
124 35
        $result = [];
125
126 35
        foreach ( $this->stack as $provider ) {
127
128 35
            $pro = $provider[0];
129
130 35
            $provider_result = $pro->save($item);
131
132 35
            $this->logger->debug("Saving item ".$item->getKey()." into provider ".
133 35
                $pro->getId().": ".($provider_result ? "OK" : "NOK - ".$pro->getStateMessage()));
134
135 35
            $result[] = $provider_result;
136
137
        }
138
139 35
        return !in_array(false, $result);
140
141
    }
142
143 1
    public static function createFromConfiguration(Configuration $configuration, LoggerInterface $logger, $stanza = null) {
144
145 1
        list($enable, $manager_configuration, $providers) = ConfigurationParser::parse($configuration, $logger, $stanza);
146
147 1
        $manager = new Manager(...$manager_configuration);
0 ignored issues
show
Bug introduced by
$manager_configuration is expanded, but the parameter $pick_mode of Comodojo\Cache\Manager::__construct() does not expect variable arguments. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

147
        $manager = new Manager(/** @scrutinizer ignore-type */ ...$manager_configuration);
Loading history...
148
149 1
        if ( $enable ) {
150 1
            foreach ( $providers as $name => $provider ) {
151 1
                $instance = $provider->instance;
152 1
                $weight = $provider->weight;
153 1
                $id = $instance->getId();
154 1
                $logger->debug("Adding provider $name ($id) to cache manager (w $weight)");
155 1
                $manager->addProvider($instance, $weight);
156
            }
157
        }
158
159 1
        return $manager;
160
161
    }
162
163 43
    protected function selectFrom($mode, $key) {
164
165 43
        if ( $this->pick_mode < 5 ) {
166
167 37
            $result = $this->fromSingleProvider($mode, $key);
168
169 6
        } else if ( $this->pick_mode == 5 ) {
170
171 1
            $result = $this->fromAllProviders($mode, $key);
172
173
        } else {
174
175 5
            $result = $this->traverse($mode, $key);
176
177
        }
178
179 43
        return $result;
180
181
    }
182
183 37
    protected function fromSingleProvider($mode, $key) {
184
185 37
        $provider = $this->selectProvider();
186
187 37
        if ( $mode == 'HAS' ) return $provider->hasItem($key);
188
189 36
        return $provider->getItem($key);
190
191
    }
192
193 1
    protected function fromAllProviders($mode, $key) {
194
195 1
        $result = [];
196
197 1
        if ( $mode == 'GET' ) {
198
199 1
            foreach ( $this->stack as $provider ) {
200
201 1
                $result[] = $provider[0]->getItem($key);
202
203
                // selected provider has no sense in this case
204 1
                $this->selected = $provider[0];
205
206
            }
207
208 1
            if ( count(array_unique($result)) == 1 ) return $result[0];
209
210 1
            return new Item($key);
211
212
        } else {
213
214 1
            foreach ( $this->stack as $provider ) {
215
216 1
                $result[] = $provider[0]->hasItem($key);
217
218
                // selected provider has no sense in this case
219 1
                $this->selected = $provider[0];
220
221
            }
222
223 1
            return !in_array(false, $result);
224
225
        }
226
227
    }
228
229 5
    protected function traverse($mode, $key) {
230
231 5
        $this->stack->rewind();
232
233 5
        if ( $mode == 'GET' ) {
234
235 5
            foreach ( $this->stack as $provider ) {
236
237 5
                $item = $provider[0]->getItem($key);
238
239 5
                if ( $item->isHit() ) {
240
241
                    // selected provider has no sense in this case
242 5
                    $this->selected = $provider[0];
243
244 5
                    return $item;
245
246
                }
247
248
            }
249
250
            // selected provider has no sense in this case
251
            $this->selected = $this->vacuum;
252
253
            return new Item($key);
254
255
        } else {
256
257 5
            foreach ( $this->stack as $provider ) {
258
259 5
                $item = $provider[0]->hasItem($key);
260
261 5
                if ( $item === true ) {
262
263
                    // selected provider has no sense in this case
264 5
                    $this->selected = $provider[0];
265
266 5
                    return true;
267
268
                }
269
270
            }
271
272
            // selected provider has no sense in this case
273
            $this->selected = $this->vacuum;
274
275
            return false;
276
277
        }
278
279
    }
280
281
}
282