Completed
Push — master ( affc35...f4e6d4 )
by Alex
01:36
created

Configuration   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 149
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 7

Test Coverage

Coverage 98.94%

Importance

Changes 0
Metric Value
wmc 8
lcom 1
cbo 7
dl 0
loc 149
ccs 93
cts 94
cp 0.9894
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
B getConfigTreeBuilder() 0 43 1
B normalizeRootNode() 0 28 3
A addVariablesNode() 0 17 1
B addErrorLoggingLevelNode() 0 34 2
A addArrayNode() 0 17 1
1
<?php
2
declare(strict_types=1);
3
4
namespace AlexMasterov\PsyshBundle\DependencyInjection;
5
6
use Symfony\Component\Config\Definition\{
7
    Builder\ArrayNodeDefinition,
8
    Builder\TreeBuilder,
9
    ConfigurationInterface,
10
    Exception\InvalidConfigurationException
11
};
12
13
class Configuration implements ConfigurationInterface
14
{
15
    /**
16
     * @inheritDoc
17
     */
18 3
    public function getConfigTreeBuilder()
19
    {
20 3
        $treeBuilder = new TreeBuilder();
21 3
        $rootNode = $treeBuilder->root('psysh');
22
23
        $rootNode
24 3
            ->children()
25 3
                ->append($this->addVariablesNode())
26 3
                ->append($this->addArrayNode('commands'))
27 3
                ->append($this->addArrayNode('default_includes'))
28 3
                ->append($this->addErrorLoggingLevelNode())
29 3
                ->scalarNode('config_dir')->end()
30 3
                ->scalarNode('data_dir')->end()
31 3
                ->scalarNode('runtime_dir')
32 3
                    ->info('Set the shell\'s temporary directory location')
33 3
                ->end()
34 3
                ->integerNode('history_size')
35 3
                    ->info('If set to zero (0), the history size is unlimited')
36 3
                ->end()
37 3
                ->scalarNode('history_file')->end()
38 3
                ->scalarNode('manual_db_file')->end()
39 3
                ->booleanNode('tab_completion')->end()
40 3
                ->append($this->addArrayNode('tab_completion_matchers'))
41 3
                ->scalarNode('startup_message')->end()
42 3
                ->booleanNode('require_semicolons')->end()
43 3
                ->booleanNode('erase_duplicates')->end()
44 3
                ->booleanNode('pcntl')->end()
45 3
                ->booleanNode('readline')->end()
46 3
                ->booleanNode('unicode')->end()
47 3
                ->enumNode('color_mode')
48 3
                    ->values(['auto', 'forced', 'disabled'])
49 3
                ->end()
50 3
                ->scalarNode('pager')->treatNullLike('less')->end()
51 3
                ->enumNode('update_check')->defaultValue('never')
52 3
                    ->values(['never', 'always', 'daily', 'weekly', 'monthly'])
53 3
                ->end()
54 3
            ->end()
55
        ;
56
57 3
        $this->normalizeRootNode($rootNode);
58
59 3
        return $treeBuilder;
60
    }
61
62 3
    private function normalizeRootNode(ArrayNodeDefinition $rootNode): void
63
    {
64
        $normalizer = static function (array $config): array {
65 2
            static $keys = [
66
                'pcntl'    => 'usePcntl',
67
                'readline' => 'useReadline',
68
                'unicode'  => 'useUnicode',
69
            ];
70
71
            // config_dir -> configDir
72
            $camelize = static function (string $value): string {
73 2
                return \str_replace('_', '', \lcfirst(\ucwords(\strtolower($value), '_')));
74 2
            };
75
76 2
            $normalized = [];
77 2
            foreach ($config as $key => $value) {
78 2
                if (empty($value)) {
79 1
                    continue;
80
                }
81 2
                $key = $keys[$key] ?? $camelize($key);
82 2
                $normalized[$key] = $value;
83
            }
84
85 2
            return $normalized;
86 3
        };
87
88 3
        $rootNode->validate()->always()->then($normalizer)->end();
89 3
    }
90
91 3
    private function addVariablesNode(): ArrayNodeDefinition
92
    {
93 3
        $node = new ArrayNodeDefinition('variables');
94
        $node
95 3
            ->normalizeKeys(false)
96 3
            ->useAttributeAsKey('name')
97 3
            ->prototype('variable')->end()
98 3
            ->validate()
99 3
                ->always()
100
                ->then(static function ($variables) {
101 2
                    return \array_filter($variables, 'is_string');
102 3
                })
103 3
            ->end()
104
        ;
105
106 3
        return $node;
107
    }
108
109 3
    private function addErrorLoggingLevelNode(): ArrayNodeDefinition
110
    {
111 3
        $node = new ArrayNodeDefinition('error_logging_level');
112
        $node
113 3
            ->beforeNormalization()
114 3
                ->ifString()
115
                ->then(static function ($v) {
116 2
                    return \preg_split('/\s*,\s*/', $v, -1, \PREG_SPLIT_NO_EMPTY);
117 3
                })
118 3
            ->end()
119 3
            ->prototype('scalar')->end()
120 3
            ->validate()
121 3
                ->always()
122
                ->then(static function ($methods) {
123
                    $invalidMethods = \array_filter($methods, static function ($method) {
124 2
                        return false === \defined("E_{$method}");
125 2
                    });
126
127 2
                    if (empty($invalidMethods)) {
128
                        return \array_reduce($methods, static function ($level, $method) {
129 1
                            return $level |= \constant("E_{$method}");
130 1
                        });
131
                    }
132
133 1
                    throw new InvalidConfigurationException(\sprintf(
134 1
                        'The errors are not supported: "%s".',
135 1
                        \implode('", "', $invalidMethods)
136
                    ));
137 3
                })
138 3
            ->end()
139
        ;
140
141 3
        return $node;
142
    }
143
144 3
    private function addArrayNode(string $name): ArrayNodeDefinition
145
    {
146 3
        $node = new ArrayNodeDefinition($name);
147
        $node
148 3
            ->normalizeKeys(false)
149 3
            ->useAttributeAsKey('name')
150 3
            ->beforeNormalization()
151 3
                ->ifString()
152 3
                ->then(static function ($v) {
153
                    return \preg_split('/\s*,\s*/', $v, -1, \PREG_SPLIT_NO_EMPTY);
154 3
                })
155 3
            ->end()
156 3
            ->prototype('scalar')->end()
157
        ;
158
159 3
        return $node;
160
    }
161
}
162