Completed
Push — master ( b16e40...058ee0 )
by Marco
07:56
created

Manager::save()   B

Complexity

Conditions 6
Paths 4

Size

Total Lines 26
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 6

Importance

Changes 0
Metric Value
dl 0
loc 26
ccs 12
cts 12
cp 1
rs 8.439
c 0
b 0
f 0
cc 6
eloc 12
nc 4
nop 1
crap 6
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 46 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 46
        $this->pick_mode = DataFilter::filterInteger($pick_mode, 1, 6, self::DEFAULT_PICK_MODE);
63
64 46
        $this->align_cache = DataFilter::filterBoolean($align_cache, false);
65
66 46
        $stack = new ArrayObject([]);
67
68 46
        $this->stack = new StackManager($stack->getIterator());
69 46
        $this->stack->setFlapInterval($flap_interval);
70
71 46
        parent::__construct($logger);
72
73 46
        $this->vacuum = new Vacuum($this->logger);
74
75 46
        $this->logger->debug("Cache manager online; pick mode ".$this->pick_mode);
76
77 46
    }
78
79 45
    public function addProvider(EnhancedCacheItemPoolInterface $provider, $weight = 0) {
80
81 45
        return $this->genericAddProvider($provider, $weight);
82
83
    }
84
85 42
    public function getItem($key) {
86
87 42
        return $this->selectFrom('GET', $key);
88
89
    }
90
91 21
    public function hasItem($key) {
92
93 21
        return $this->selectFrom('HAS', $key);
94
95
    }
96
97 4 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 4
        if ( iterator_count($this->stack) == 0 ) return $this->vacuum->deleteItem($key);
100
101 3
        if ( $this->align_cache === false && $this->pick_mode < 5 ) {
102
            return $this->selectProvider()->deleteItem($key);
103
        }
104
105 3
        $result = [];
106
107 3
        foreach ( $this->stack as $provider ) {
108
109 3
            $result[] = $provider[0]->deleteItem($key);
110
111
        }
112
113 3
        return !in_array(false, $result);
114
115
    }
116
117 37
    public function save(CacheItemInterface $item) {
118
119 37
        if ( iterator_count($this->stack) == 0 ) return $this->vacuum->save($item);
120
121 36
        if ( $this->align_cache === false && $this->pick_mode < 5 ) {
122 1
            return $this->selectProvider()->save($item);
123
        }
124
125 35
        $result = [];
126
127 35
        foreach ( $this->stack as $provider ) {
128
129 35
            $pro = $provider[0];
130
131 35
            $provider_result = $pro->save($item);
132
133 35
            $this->logger->debug("Saving item ".$item->getKey()." into provider ".
134 35
                $pro->getId().": ".($provider_result ? "OK" : "NOK - ".$pro->getStateMessage()));
135
136 35
            $result[] = $provider_result;
137
138
        }
139
140 35
        return !in_array(false, $result);
141
142
    }
143
144 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...
145
146 1
        list($enable, $manager_configuration, $providers) = ConfigurationParser::parse($configuration, $logger);
147
148 1
        $manager = new Manager(...$manager_configuration);
149
150 1
        if ( $enable ) {
151 1
            foreach ( $providers as $name => $provider ) {
152 1
                $instance = $provider->instance;
153 1
                $weight = $provider->weight;
154 1
                $id = $instance->getId();
155 1
                $logger->debug("Adding provider $name ($id) to cache manager (w $weight)");
156 1
                $manager->addProvider($instance, $weight);
157
            }
158
        }
159
160 1
        return $manager;
161
162
    }
163
164 43
    protected function selectFrom($mode, $key) {
165
166 43 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...
167
168 37
            $result = $this->fromSingleProvider($mode, $key);
169
170 6
        } else if ( $this->pick_mode == 5 ) {
171
172 1
            $result = $this->fromAllProviders($mode, $key);
173
174
        } else {
175
176 5
            $result = $this->traverse($mode, $key);
177
178
        }
179
180 43
        return $result;
181
182
    }
183
184 37
    protected function fromSingleProvider($mode, $key) {
185
186 37
        $provider = $this->selectProvider();
187
188 37
        if ( $mode == 'HAS' ) return $provider->hasItem($key);
189
190 36
        return $provider->getItem($key);
191
192
    }
193
194 1
    protected function fromAllProviders($mode, $key) {
195
196 1
        $result = [];
197
198 1
        if ( $mode == 'GET' ) {
199
200 1
            foreach ( $this->stack as $provider ) {
201
202 1
                $result[] = $provider[0]->getItem($key);
203
204
                // selected provider has no sense in this case
205 1
                $this->selected = $provider[0];
206
207
            }
208
209 1
            if ( count(array_unique($result)) == 1 ) return $result[0];
210
211 1
            return new Item($key);
212
213 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...
214
215 1
            foreach ( $this->stack as $provider ) {
216
217 1
                $result[] = $provider[0]->hasItem($key);
218
219
                // selected provider has no sense in this case
220 1
                $this->selected = $provider[0];
221
222
            }
223
224 1
            return !in_array(false, $result);
225
226
        }
227
228
    }
229
230 5
    protected function traverse($mode, $key) {
231
232 5
        $this->stack->rewind();
233
234 5
        if ( $mode == 'GET' ) {
235
236 5
            foreach ( $this->stack as $provider ) {
237
238 5
                $item = $provider[0]->getItem($key);
239
240 5
                if ( $item->isHit() ) {
241
242
                    // selected provider has no sense in this case
243 5
                    $this->selected = $provider[0];
244
245 5
                    return $item;
246
247
                }
248
249
            }
250
251
            // selected provider has no sense in this case
252
            $this->selected = $this->vacuum;
253
254
            return new Item($key);
255
256 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...
257
258 5
            foreach ( $this->stack as $provider ) {
259
260 5
                $item = $provider[0]->hasItem($key);
261
262 5
                if ( $item === true ) {
263
264
                    // selected provider has no sense in this case
265 5
                    $this->selected = $provider[0];
266
267 5
                    return true;
268
269
                }
270
271
            }
272
273
            // selected provider has no sense in this case
274
            $this->selected = $this->vacuum;
275
276
            return false;
277
278
        }
279
280
    }
281
282
}
283