Completed
Push — master ( ed2656...372aca )
by Marco
06:09
created

ConfigurationParser::buildProviders()   D

Complexity

Conditions 17
Paths 24

Size

Total Lines 114
Code Lines 69

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 43
CRAP Score 18.9418

Importance

Changes 0
Metric Value
dl 0
loc 114
ccs 43
cts 53
cp 0.8113
rs 4.8361
c 0
b 0
f 0
cc 17
eloc 69
nc 24
nop 2
crap 18.9418

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php namespace Comodojo\Cache\Components;
2
3
use \Comodojo\Foundation\Base\Configuration;
4
use \Comodojo\Foundation\Validation\DataFilter;
5
use \Comodojo\Foundation\Utils\ArrayOps;
6
use \Psr\Log\LoggerInterface;
7
use \Comodojo\Cache\Providers\Apc as CacheApc;
8
use \Comodojo\Cache\Providers\Apcu as CacheApcu;
9
use \Comodojo\Cache\Providers\Filesystem as CacheFilesystem;
10
use \Comodojo\Cache\Providers\Memcached as CacheMemcached;
11
use \Comodojo\Cache\Providers\Memory as CacheMemory;
12
use \Comodojo\Cache\Providers\PhpRedis as CachePhpRedis;
13
use \Comodojo\Cache\Providers\Vacuum as CacheVacuum;
14
15
/**
16
 * @package     Comodojo Cache
17
 * @author      Marco Giovinazzi <[email protected]>
18
 * @license     MIT
19
 *
20
 * LICENSE:
21
 *
22
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
28
 * THE SOFTWARE.
29
 */
30
31
class ConfigurationParser {
32
33
    protected static $algorithms = array(
34
        'PICK_FIRST' => 1,
35
        'PICK_LAST' => 2,
36
        'PICK_RANDOM' => 3,
37
        'PICK_BYWEIGHT' => 4,
38
        'PICK_ALL' => 4,
39
        'PICK_TRAVERSE' => 6
40
    );
41
42 2
    public static function parse(Configuration $configuration, LoggerInterface $logger, $stanza = null) {
0 ignored issues
show
Unused Code introduced by
The parameter $stanza 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...
43
44 2
        list($enable, $manager) = self::parseManagerConfiguration($configuration, $logger);
45 2
        $providers = self::buildProviders($configuration, $logger);
46
47
        return [
48 2
            $enable,
49 2
            $manager,
50 2
            $providers
51
        ];
52
53
    }
54
55 1
    protected static function BuildApcProvider(LoggerInterface $logger) {
56
57 1
        return new CacheApc([], $logger);
58
59
    }
60
61 1
    protected static function BuildApcuProvider(LoggerInterface $logger) {
62
63 1
        return new CacheApcu([], $logger);
64
65
    }
66
67 1
    protected static function BuildFilesystemProvider(array $properties, LoggerInterface $logger) {
68
69 1
        return new CacheFilesystem($properties, $logger);
70
71
    }
72
73 1
    protected static function BuildMemcachedProvider(array $properties, LoggerInterface $logger) {
74
75 1
        return new CacheMemcached($properties, $logger);
76
77
    }
78
79 1
    protected static function BuildMemoryProvider(LoggerInterface $logger) {
80
81 1
        return new CacheMemory([], $logger);
82
83
    }
84
85 1
    protected static function BuildPhpRedisProvider(array $properties, LoggerInterface $logger) {
86
87 1
        return new CachePhpRedis($properties, $logger);
88
89
    }
90
91
    protected static function BuildVacuumProvider(LoggerInterface $logger) {
92
93
        return new CacheVacuum([], $logger);
94
95
    }
96
97 2
    protected static function parseManagerConfiguration(Configuration $configuration, LoggerInterface $logger, $stanza = null) {
98
99 2
        $cache = null;
100
101 2
        if ( $stanza !== null ) {
102
            $cache = $configuration->get($stanza);
103
        }
104
105 2
        if ( $cache === null ) {
106 2
            $cache = $configuration->get('cache');
107
        }
108
109
        $stdConfig = [
110 2
            'pick_mode' => null,
111 2
            'logger' => $logger,
112
            'align_cache' => true,
113
            'flap_interval' => null
114
        ];
115
116 2
        $enable = true;
117
118 2
        if ( $cache !== null && is_array($cache) ) {
119 2
            $lower_cache = array_change_key_case($cache, CASE_LOWER);
120 2
            if ( isset($lower_cache['logger']) ) unset($lower_cache['logger']);
121 2
            $stdConfig = array_merge($stdConfig, array_intersect_key($lower_cache, $stdConfig));
122 2
            if ( isset($lower_cache['enable']) && $lower_cache['enable'] === false ) $enable = false;
123
        }
124
125 2
        if ( $stdConfig['pick_mode'] !== null ) $stdConfig['pick_mode'] = self::getPickMode($stdConfig['pick_mode']);
126
127 2
        return [$enable, array_values($stdConfig)];
128
129
    }
130
131 2
    protected static function buildProviders(Configuration $configuration, LoggerInterface $logger) {
132
133 2
        $cache = $configuration->get('cache');
134 2
        $build = [];
135
136 2
        if ( $cache === null ) return $build;
137
138 2
        $lower_cache = array_change_key_case($cache, CASE_LOWER);
139
140 2
        if ( !isset($lower_cache['providers']) || !is_array($lower_cache['providers']) ) return $build;
141
142 2
        $providers = $lower_cache['providers'];
143
144 2
        foreach ( $providers as $name => $specs ) {
145
146 2
            if ( !is_array($specs) ) {
147
                $logger->error("Invalid specs for cache provider: $name");
148
                continue;
149
            }
150
151 2
            $spec = array_change_key_case($specs, CASE_LOWER);
152
153 2
            if ( empty($spec['type']) ) {
154
                $logger->error("Missing type for cache provider: $name");
155
                continue;
156
            }
157
158 2
            $type = strtoupper($spec['type']);
159
160
            switch ( $type ) {
161
162 2
                case 'APC':
163 2
                    $provider = static::BuildApcProvider($logger);
164 2
                    break;
165
166 2
                case 'APCU':
167 2
                    $provider = static::BuildApcuProvider($logger);
168 2
                    break;
169
170 2
                case 'FILESYSTEM':
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
171
172
                    $stdConfig = [
173 2
                        'cache_folder' => null
174
                    ];
175
176 2
                    if ( isset($spec['cache_folder']) ) {
177 2
                        if ( $spec['cache_folder'][0] == "/" ) {
178
                            $stdConfig['cache_folder'] = $spec['cache_folder'];
179
                        } else {
180 2
                            $stdConfig['cache_folder'] = $configuration->get('base-path')."/".$spec['cache_folder'];
181
                        }
182
                    }
183
184 2
                    $provider = static::BuildFilesystemProvider($stdConfig, $logger);
185
186 2
                    break;
187
188 2
                case 'MEMCACHED':
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
189
190
                    $valid_values = [
191 2
                        'server',
192
                        'port',
193
                        'weight',
194
                        'persistent_id',
195
                        'username',
196
                        'password'
197
                    ];
198
199 2
                    $stdConfig = ArrayOps::filterByKeys($valid_values, $spec);
200
201 2
                    $provider = static::BuildMemcachedProvider($stdConfig, $logger);
202 2
                    break;
203
204 2
                case 'MEMORY':
205 2
                    $provider = static::BuildMemoryProvider($logger);
206 2
                    break;
207
208 2
                case 'PHPREDIS':
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
209
210
                    $valid_values = [
211 2
                        'server',
212
                        'port',
213
                        'timeout',
214
                        'logger',
215
                        'password'
216
                    ];
217
218 2
                    $stdConfig = ArrayOps::filterByKeys($valid_values, $spec);
219
220 2
                    $provider = static::BuildPhpRedisProvider($stdConfig, $logger);
221 2
                    break;
222
223
                case 'VACUUM':
224
                    $provider = static::BuildVacuumProvider($logger);
225
                    break;
226
227
                default:
228
                    $logger->error("Unknown type $type for cache provider: $name");
229
                    continue 2;
230
                    break;
0 ignored issues
show
Unused Code introduced by
break; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
231
232
            }
233
234 2
            $build[$name] = (object) [
235 2
                "instance" => $provider,
236 2
                "weight" => isset($spec['weight']) ?
237 2
                    DataFilter::filterInteger($spec['weight'], 0, 100, 0) : 0
238
            ];
239
240
        }
241
242 2
        return $build;
243
244
    }
245
246 2
    protected static function getPickMode($algorithm = null) {
247
248 2
        $algorithm = strtoupper($algorithm);
249
250 2
        if ( array_key_exists($algorithm, self::$algorithms) ) return self::$algorithms[$algorithm];
251
252
        return self::$algorithms['PICK_FIRST'];
253
254
    }
255
256
}
257