Completed
Push — master ( b9da65...b16e40 )
by Marco
04:58
created

ConfigurationParser::buildProviders()   D

Complexity

Conditions 19
Paths 28

Size

Total Lines 115
Code Lines 70

Duplication

Lines 29
Ratio 25.22 %

Code Coverage

Tests 56
CRAP Score 21.414

Importance

Changes 0
Metric Value
dl 29
loc 115
ccs 56
cts 69
cp 0.8116
rs 4.764
c 0
b 0
f 0
cc 19
eloc 70
nc 28
nop 2
crap 21.414

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

This check looks for function calls that miss required arguments.

Loading history...
179
180 2
                    break;
181
182 2 View Code Duplication
                case 'MEMCACHED':
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...
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...
183
184
                    $stdConfig = [
185 2
                        'server' => '127.0.0.1',
186 2
                        'port' => 11211,
187 2
                        'weight' => 0,
188 2
                        'persistent_id' => null,
189
                        'logger' => $logger
190 2
                    ];
191
192 2
                    if ( isset($spec['logger']) ) unset($spec['logger']);
193 2
                    $stdConfig = array_merge($stdConfig, array_intersect_key($spec, $stdConfig));
194
195 2
                    $provider = static::BuildMemcachedProvider(...array_values($stdConfig));
0 ignored issues
show
Bug introduced by
The call to BuildMemcachedProvider() misses some required arguments starting with $port.
Loading history...
196 2
                    break;
197
198 2
                case 'MEMORY':
199 2
                    $provider = static::BuildMemoryProvider($logger);
200 2
                    break;
201
202 2 View Code Duplication
                case 'PHPREDIS':
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...
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...
203
204
                    $stdConfig = [
205 2
                        'server' => '127.0.0.1',
206 2
                        'port' => 6379,
207 2
                        'timeout' => 0,
208
                        'logger' => $logger
209 2
                    ];
210
211 2
                    if ( isset($spec['logger']) ) unset($spec['logger']);
212 2
                    $stdConfig = array_merge($stdConfig, array_intersect_key($spec, $stdConfig));
213
214 2
                    $provider = static::BuildPhpRedisProvider(...array_values($stdConfig));
0 ignored issues
show
Bug introduced by
The call to BuildPhpRedisProvider() misses some required arguments starting with $port.
Loading history...
215 2
                    break;
216
217
                case 'VACUUM':
218
                    $provider = static::BuildVacuumProvider($logger);
219
                    break;
220
221
                default:
222
                    $logger->error("Unknown type $type for cache provider: $name");
223
                    continue 2;
224
                    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...
225
226
            }
227
228 2
            $build[$name] = (object) [
229 2
                "instance" => $provider,
230 2
                "weight" => isset($spec['weight']) ?
231 2
                    DataFilter::filterInteger($spec['weight'], 0, 100, 0) : 0
232 2
            ];
233
234 2
        }
235
236 2
        return $build;
237
238
    }
239
240 2
    protected static function getPickMode($algorithm = null) {
241
242 2
        $algorithm = strtoupper($algorithm);
243
244 2
        if ( array_key_exists($algorithm, self::$algorithms) ) return self::$algorithms[$algorithm];
245
246
        return self::$algorithms['PICK_FIRST'];
247
248
    }
249
250
}
251