ConfigDumper::createConfig()   B
last analyzed

Complexity

Conditions 9
Paths 72

Size

Total Lines 51
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 30
CRAP Score 9

Importance

Changes 0
Metric Value
eloc 29
dl 0
loc 51
ccs 30
cts 30
cp 1
rs 8.0555
c 0
b 0
f 0
cc 9
nc 72
nop 2
crap 9

How to fix   Long Method   

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
2
/**
3
 * Sandro Keil (https://sandro-keil.de)
4
 *
5
 * @link      http://github.com/sandrokeil/interop-config for the canonical source repository
6
 * @copyright Copyright (c) 2017-2020 Sandro Keil
7
 * @license   http://github.com/sandrokeil/interop-config/blob/master/LICENSE.md New BSD License
8
 */
9
10
declare(strict_types=1);
11
12
namespace Interop\Config\Tool;
13
14
use Interop\Config\ProvidesDefaultOptions;
15
use Interop\Config\RequiresConfig;
16
use Interop\Config\RequiresConfigId;
17
use Interop\Config\RequiresMandatoryOptions;
18
19
/**
20
 * Dumps configuration based on factory definition
21
 *
22
 * @copyright Copyright (c) 2016 Zend Technologies USA Inc. (http://www.zend.com)
23
 */
24
class ConfigDumper extends AbstractConfig
25
{
26
    const CONFIG_TEMPLATE = <<<EOC
27
<?php
28
/**
29
 * This file is generated by \Interop\Config\Tool\ConfigDumper.
30
 *
31
 * @see https://sandrokeil.github.io/interop-config/reference/console-tools.html interop-config documentation
32
 */ 
33
34
EOC;
35
36
    /**
37
     * @var ConsoleHelper
38
     */
39
    private $helper;
40
41 13
    public function __construct(ConsoleHelper $helper = null)
42
    {
43 13
        $this->helper = $helper ?: new ConsoleHelper();
44 13
    }
45
46
    /**
47
     * @param array $config
48
     * @param string $className
49
     * @return array
50
     */
51 12
    public function createConfig(array $config, string $className): array
52
    {
53 12
        $reflectionClass = new \ReflectionClass($className);
54
55 12
        $interfaces = $reflectionClass->getInterfaceNames();
56
57 12
        $factory = $reflectionClass->newInstanceWithoutConstructor();
58 12
        $dimensions = [];
59 12
        $mandatoryOptions = [];
60 12
        $defaultOptions = [];
61
62 12
        if (in_array(RequiresConfig::class, $interfaces, true)) {
63 12
            $dimensions = $factory->dimensions();
64
        }
65
66 12
        if (in_array(RequiresConfigId::class, $interfaces, true)) {
67 8
            $configId = $this->helper->readLine(
68 8
                'config id (default)',
69 8
                'Multiple instances are supported, please enter a'
70
            );
71 8
            if ('' === $configId) {
72 1
                $configId = 'default';
73
            }
74 8
            $dimensions[] = $configId;
75
        }
76
77 12
        $parent = &$config;
78
79 12
        foreach ($dimensions as $dimension) {
80 12
            if (empty($parent[$dimension])) {
81 6
                $parent[$dimension] = [];
82
            }
83 12
            $parent = &$parent[$dimension];
84
        }
85
86 12
        if (in_array(RequiresMandatoryOptions::class, $interfaces, true)) {
87 5
            $mandatoryOptions = $this->readMandatoryOption($factory->mandatoryOptions(), $parent);
88
        }
89
90 12
        if (in_array(ProvidesDefaultOptions::class, $interfaces)) {
91 7
            $defaultOptions = $this->readDefaultOption($factory->defaultOptions(), $parent);
92
        }
93
94 12
        $options = array_replace_recursive(
95 12
            $defaultOptions instanceof \Iterator ? iterator_to_array($defaultOptions) : (array)$defaultOptions,
0 ignored issues
show
introduced by
$defaultOptions is never a sub-type of Iterator.
Loading history...
96 12
            (array)$mandatoryOptions
97
        );
98
99 12
        $parent = array_replace_recursive($parent, $options);
100
101 12
        return $config;
102
    }
103
104 5
    private function readMandatoryOption(iterable $mandatoryOptions, array $config, string $path = ''): array
105
    {
106 5
        $options = [];
107
108 5
        foreach ($mandatoryOptions as $key => $mandatoryOption) {
109 5
            if (!is_scalar($mandatoryOption)) {
110 2
                $options[$key] = $this->readMandatoryOption(
111 2
                    $mandatoryOptions[$key],
112 2
                    $config[$key] ?? [],
113 2
                    trim($path . '.' . $key, '.')
114
                );
115 2
                continue;
116
            }
117 5
            $previousValue = isset($config[$mandatoryOption]) ? ' (' . $config[$mandatoryOption] . ')' : '';
118
119 5
            $options[$mandatoryOption] = $this->helper->readLine(
120 5
                trim($path . '.' . $mandatoryOption, '.') . $previousValue
121
            );
122
123 5
            if ('' === $options[$mandatoryOption] && isset($config[$mandatoryOption])) {
124 1
                $options[$mandatoryOption] = $config[$mandatoryOption];
125
            }
126
        }
127 5
        return $options;
128
    }
129
130 7
    private function readDefaultOption(iterable $defaultOptions, array $config, string $path = ''): array
131
    {
132 7
        $options = [];
133
134 7
        foreach ($defaultOptions as $key => $defaultOption) {
135 7
            if (!is_scalar($defaultOption)) {
136 7
                $options[$key] = $this->readDefaultOption(
137 7
                    $defaultOptions[$key],
138 7
                    $config[$key] ?? [],
139 7
                    trim($path . '.' . $key, '.')
140
                );
141 7
                continue;
142
            }
143 7
            $previousValue = isset($config[$key])
144 3
                ? ' (' . $config[$key] . '), current value <value>' . $defaultOption . '</value>'
145 7
                : ' (' . $defaultOption . ')';
146
147 7
            $options[$key] = $this->helper->readLine(trim($path . '.' . $key, '.') . $previousValue);
148
149 7
            if ('' === $options[$key]) {
150 6
                $options[$key] = $config[$key] ?? $defaultOption;
151
            } else {
152 1
                $options[$key] = $this->convertToType($options[$key], $defaultOption);
153
            }
154
        }
155 7
        return $options;
156
    }
157
158 1
    private function convertToType($value, $originValue)
159
    {
160 1
        switch (gettype($originValue)) {
161 1
            case 'boolean':
162
                return (bool)$value;
163 1
            case 'integer':
164 1
                return (int)$value;
165 1
            case 'double':
166
                return (float)$value;
167 1
            case 'string':
168
            default:
169 1
                return $value;
170
        }
171
    }
172
173 1
    public function dumpConfigFile(iterable $config): string
174
    {
175 1
        return 'return ' . $this->prepareConfig($config) . ';';
176
    }
177
}
178