Completed
Push — 2.0 ( a51c1d...cacff6 )
by Marco
04:49
created

Manager::createFromConfiguration()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 17
Code Lines 10

Duplication

Lines 17
Ratio 100 %

Code Coverage

Tests 10
CRAP Score 2

Importance

Changes 0
Metric Value
dl 17
loc 17
ccs 10
cts 10
cp 1
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 10
nc 2
nop 2
crap 2
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
 *
21
 * @package     Comodojo Spare Parts
22
 * @author      Marco Giovinazzi <[email protected]>
23
 * @license     MIT
24
 *
25
 * LICENSE:
26
 *
27
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
30
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
31
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
32
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
33
 * THE SOFTWARE.
34
 */
35
36
class Manager extends AbstractProvider implements CacheItemPoolManagerInterface {
37
38
    use NamespaceTrait, GenericManagerTrait {
39
        GenericManagerTrait::setNamespace insteadof NamespaceTrait;
40
    }
41
    use BasicCacheItemPoolTrait;
42
43
    const DEFAULT_PICK_MODE = 1;
44
45
    protected $pick_mode;
46
47
    protected $stack;
48
49
    protected $align_cache;
50
51
    protected $vacuum;
52
53
    protected $selected;
54
55 42 View Code Duplication
    public function __construct(
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...
56
        $pick_mode = null,
57
        LoggerInterface $logger = null,
58
        $align_cache = true,
59
        $flap_interval = null
60
    ) {
61
62 42
        $this->pick_mode = DataFilter::filterInteger($pick_mode, 1, 6, self::DEFAULT_PICK_MODE);
63
64 42
        $this->align_cache = DataFilter::filterBoolean($align_cache, true);
65
66 42
        $stack = new ArrayObject([]);
67
68 42
        $this->stack = new StackManager($stack->getIterator());
69 42
        $this->stack->setFlapInterval($flap_interval);
70
71 42
        parent::__construct($logger);
72
73 42
        $this->vacuum = new Vacuum($this->logger);
74
75 42
        $this->logger->info("Cache manager online; pick mode ".$this->pick_mode);
76
77 42
    }
78
79 42
    public function addProvider(EnhancedCacheItemPoolInterface $provider, $weight = 0) {
80
81 42
        return $this->genericAddProvider($provider, $weight);
82
83
    }
84
85 39
    public function getItem($key) {
86
87 39
        return $this->selectFrom('GET', $key);
88
89
    }
90
91 20
    public function hasItem($key) {
92
93 20
        return $this->selectFrom('HAS', $key);
94
95
    }
96
97 3 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...
98
99 3
        if ( $this->align_cache === false && $this->pick_mode < 5) {
100
            return $this->selectProvider()->deleteItem($key);
101
        }
102
103 3
        $result = [];
104
105 3
        foreach ($this->stack as $provider) {
106
107 3
            $result[] = $provider[0]->deleteItem($key);
108
109
        }
110
111 3
        return !in_array(false, $result);
112
113
    }
114
115 34
    public function save(CacheItemInterface $item) {
116
117 34
        if ( $this->align_cache === false && $this->pick_mode < 5) {
118
            return $this->selectProvider()->save($item);
119
        }
120
121 34
        $result = [];
122
123 34
        foreach ($this->stack as $provider) {
124
125 34
            $pro = $provider[0];
126
127 34
            $provider_result = $pro->save($item);
128
129 34
            $this->logger->debug("Saving item ".$item->getKey()." into provider ".
130 34
                $pro->getId().": ".($provider_result ? "OK" : "NOK - ".$pro->getStateMessage()));
131
132 34
            $result[] = $provider_result;
133
134
        }
135
136 34
        return !in_array(false, $result);
137
138
    }
139
140 1 View Code Duplication
    public static function createFromConfiguration(Configuration $configuration, LoggerInterface $logger) {
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...
141
142 1
        list($manager_configuration, $providers) = ConfigurationParser::parse($configuration, $logger);
143
144 1
        $manager = new Manager(...$manager_configuration);
145
146 1
        foreach ($providers as $name => $provider) {
147 1
            $instance = $provider->instance;
148 1
            $weight = $provider->weight;
149 1
            $id = $instance->getId();
150 1
            $logger->debug("Adding provider $name ($id) to cache manager (w $weight)");
151 1
            $manager->addProvider($instance, $weight);
152
        }
153
154 1
        return $manager;
155
156
    }
157
158 40
    protected function selectFrom($mode, $key) {
159
160 40 View Code Duplication
        if ( $this->pick_mode < 5 ) {
0 ignored issues
show
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...
161
162 34
            $result = $this->fromSingleProvider($mode, $key);
163
164 6
        } else if ( $this->pick_mode == 5 ) {
165
166 1
            $result = $this->fromAllProviders($mode, $key);
167
168
        } else {
169
170 5
            $result = $this->traverse($mode, $key);
171
172
        }
173
174 40
        return $result;
175
176
    }
177
178 34
    protected function fromSingleProvider($mode, $key) {
179
180 34
        $provider = $this->selectProvider();
181
182 34
        if ( $mode == 'HAS' ) return $provider->hasItem($key);
183
184 33
        return $provider->getItem($key);
185
186
    }
187
188 1
    protected function fromAllProviders($mode, $key) {
189
190 1
        $result = [];
191
192 1
        if ( $mode == 'GET' ) {
193
194 1
            foreach ($this->stack as $provider) {
195
196 1
                $result[] = $provider[0]->getItem($key);
197
198
                // selected provider has no sense in this case
199 1
                $this->selected = $provider[0];
200
201
            }
202
203 1
            if ( count(array_unique($result)) == 1 ) return $result[0];
204
205 1
            return new Item($key);
206
207 View Code Duplication
        } else {
0 ignored issues
show
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...
208
209 1
            foreach ($this->stack as $provider) {
210
211 1
                $result[] = $provider[0]->hasItem($key);
212
213
                // selected provider has no sense in this case
214 1
                $this->selected = $provider[0];
215
216
            }
217
218 1
            return !in_array(false, $result);
219
220
        }
221
222
    }
223
224 5
    protected function traverse($mode, $key) {
225
226 5
        $this->stack->rewind();
227
228 5
        if ( $mode == 'GET' ) {
229
230 5
            foreach ($this->stack as $provider) {
231
232 5
                $item = $provider[0]->getItem($key);
233
234 5
                if ( $item->isHit() ) {
235
236
                    // selected provider has no sense in this case
237 5
                    $this->selected = $provider[0];
238
239 5
                    return $item;
240
241
                }
242
243
            }
244
245
            // selected provider has no sense in this case
246
            $this->selected = $this->vacuum;
247
248
            return new Item($key);
249
250 View Code Duplication
        } else {
0 ignored issues
show
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...
251
252 5
            foreach ($this->stack as $provider) {
253
254 5
                $item = $provider[0]->hasItem($key);
255
256 5
                if ( $item === true ) {
257
258
                    // selected provider has no sense in this case
259 5
                    $this->selected = $provider[0];
260
261 5
                    return true;
262
263
                }
264
265
            }
266
267
            // selected provider has no sense in this case
268
            $this->selected = $this->vacuum;
269
270
            return false;
271
272
        }
273
274
    }
275
276
}
277