Completed
Pull Request — master (#44)
by Tobias
14:26
created

Configuration::configureClients()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 20
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 1
Metric Value
c 2
b 0
f 1
dl 0
loc 20
rs 9.4285
cc 1
eloc 18
nc 1
nop 1
1
<?php
2
3
namespace Http\HttplugBundle\DependencyInjection;
4
5
use Symfony\Component\Config\Definition\ArrayNode;
6
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
7
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
8
use Symfony\Component\Config\Definition\ConfigurationInterface;
9
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
10
11
/**
12
 * This class contains the configuration information for the bundle.
13
 *
14
 * This information is solely responsible for how the different configuration
15
 * sections are normalized, and merged.
16
 *
17
 * @author David Buchmann <[email protected]>
18
 * @author Tobias Nyholm <[email protected]>
19
 */
20
class Configuration implements ConfigurationInterface
21
{
22
    /**
23
     * {@inheritdoc}
24
     */
25
    public function getConfigTreeBuilder()
26
    {
27
        $treeBuilder = new TreeBuilder();
28
        $rootNode = $treeBuilder->root('httplug');
29
30
        $this->configureClients($rootNode);
31
        $this->configurePlugins($rootNode);
32
33
        $rootNode
34
            ->validate()
35
                ->ifTrue(function ($v) {
36
                    return !empty($v['classes']['client'])
37
                        || !empty($v['classes']['message_factory'])
38
                        || !empty($v['classes']['uri_factory'])
39
                        || !empty($v['classes']['stream_factory']);
40
                })
41
                ->then(function ($v) {
42
                    foreach ($v['classes'] as $key => $class) {
43
                        if (null !== $class && !class_exists($class)) {
44
                            throw new InvalidConfigurationException(sprintf(
45
                                'Class %s specified for httplug.classes.%s does not exist.',
46
                                $class,
47
                                $key
48
                            ));
49
                        }
50
                    }
51
52
                    return $v;
53
                })
54
            ->end()
55
            ->children()
56
                ->arrayNode('main_alias')
57
                    ->addDefaultsIfNotSet()
58
                    ->info('Configure which service the main alias point to.')
59
                    ->children()
60
                        ->scalarNode('client')->defaultValue('httplug.client.default')->end()
61
                        ->scalarNode('message_factory')->defaultValue('httplug.message_factory.default')->end()
62
                        ->scalarNode('uri_factory')->defaultValue('httplug.uri_factory.default')->end()
63
                        ->scalarNode('stream_factory')->defaultValue('httplug.stream_factory.default')->end()
64
                    ->end()
65
                ->end()
66
                ->arrayNode('classes')
67
                    ->addDefaultsIfNotSet()
68
                    ->info('Overwrite a service class instead of using the discovery mechanism.')
69
                    ->children()
70
                        ->scalarNode('client')->defaultNull()->end()
71
                        ->scalarNode('message_factory')->defaultNull()->end()
72
                        ->scalarNode('uri_factory')->defaultNull()->end()
73
                        ->scalarNode('stream_factory')->defaultNull()->end()
74
                    ->end()
75
                ->end()
76
                ->arrayNode('toolbar')
77
                    ->addDefaultsIfNotSet()
78
                    ->info('Extend the debug profiler with inforation about requests.')
79
                    ->children()
80
                        ->enumNode('enabled')
81
                            ->info('If "auto" (default), the toolbar is activated when kernel.debug is true. You can force the toolbar on and off by changing this option.')
82
                            ->values([true, false, 'auto'])
83
                            ->defaultValue('auto')
84
                        ->end()
85
                        ->scalarNode('formatter')->defaultNull()->end()
86
                    ->end()
87
                ->end()
88
            ->end();
89
90
        return $treeBuilder;
91
    }
92
93
    protected function configureClients(ArrayNodeDefinition $root)
94
    {
95
        $root->children()
96
            ->arrayNode('clients')
97
                ->useAttributeAsKey('name')
98
                ->prototype('array')
99
                ->children()
100
                    ->scalarNode('factory')
101
                        ->isRequired()
102
                        ->cannotBeEmpty()
103
                        ->info('The service id of a factory to use when creating the adapter.')
104
                    ->end()
105
                    ->arrayNode('plugins')
106
                        ->info('A list of service ids of plugins. The order is important.')
107
                        ->prototype('scalar')->end()
108
                    ->end()
109
                    ->variableNode('config')->defaultValue([])->end()
110
                ->end()
111
            ->end();
112
    }
113
114
    /**
115
     * @param ArrayNodeDefinition $root
116
     */
117
    protected function configurePlugins(ArrayNodeDefinition $root)
118
    {
119
        $root->children()
120
            ->arrayNode('plugins')
121
                ->addDefaultsIfNotSet()
122
                ->children()
123
                    ->append($this->addAuthenticationPluiginNode())
124
125
                    ->arrayNode('cache')
126
                    ->canBeEnabled()
127
                    ->addDefaultsIfNotSet()
128
                        ->children()
129
                            ->scalarNode('cache_pool')
130
                                ->info('This must be a service id to a service implementing Psr\Cache\CacheItemPoolInterface')
131
                                ->isRequired()
132
                                ->cannotBeEmpty()
133
                            ->end()
134
                            ->scalarNode('stream_factory')
135
                                ->info('This must be a service id to a service implementing Http\Message\StreamFactory')
136
                                ->defaultValue('httplug.stream_factory')
137
                                ->cannotBeEmpty()
138
                            ->end()
139
                            ->arrayNode('config')
140
                                ->addDefaultsIfNotSet()
141
                                ->children()
142
                                    ->scalarNode('default_ttl')->defaultNull()->end()
143
                                    ->scalarNode('respect_cache_headers')->defaultTrue()->end()
144
                                ->end()
145
                            ->end()
146
                        ->end()
147
                    ->end() // End cache plugin
148
149
                    ->arrayNode('cookie')
150
                    ->canBeEnabled()
151
                        ->children()
152
                            ->scalarNode('cookie_jar')
153
                                ->info('This must be a service id to a service implementing Http\Message\CookieJar')
154
                                ->isRequired()
155
                                ->cannotBeEmpty()
156
                            ->end()
157
                        ->end()
158
                    ->end() // End cookie plugin
159
160
                    ->arrayNode('decoder')
161
                    ->canBeDisabled()
162
                    ->addDefaultsIfNotSet()
163
                        ->children()
164
                            ->scalarNode('use_content_encoding')->defaultTrue()->end()
165
                        ->end()
166
                    ->end() // End decoder plugin
167
168
                    ->arrayNode('history')
169
                    ->canBeEnabled()
170
                        ->children()
171
                            ->scalarNode('journal')
172
                                ->info('This must be a service id to a service implementing Http\Client\Plugin\Journal')
173
                                ->isRequired()
174
                                ->cannotBeEmpty()
175
                            ->end()
176
                        ->end()
177
                    ->end() // End history plugin
178
179
                    ->arrayNode('logger')
180
                    ->canBeDisabled()
181
                    ->addDefaultsIfNotSet()
182
                        ->children()
183
                            ->scalarNode('logger')
184
                                ->info('This must be a service id to a service implementing Psr\Log\LoggerInterface')
185
                                ->defaultValue('logger')
186
                                ->cannotBeEmpty()
187
                            ->end()
188
                            ->scalarNode('formatter')
189
                                ->info('This must be a service id to a service implementing Http\Message\Formatter')
190
                                ->defaultNull()
191
                            ->end()
192
                        ->end()
193
                    ->end() // End logger plugin
194
195
                    ->arrayNode('redirect')
196
                    ->canBeDisabled()
197
                    ->addDefaultsIfNotSet()
198
                        ->children()
199
                            ->scalarNode('preserve_header')->defaultTrue()->end()
200
                            ->scalarNode('use_default_for_multiple')->defaultTrue()->end()
201
                        ->end()
202
                    ->end() // End redirect plugin
203
204
                    ->arrayNode('retry')
205
                    ->canBeDisabled()
206
                    ->addDefaultsIfNotSet()
207
                        ->children()
208
                            ->scalarNode('retry')->defaultValue(1)->end()
209
                        ->end()
210
                    ->end() // End retry plugin
211
212
                    ->arrayNode('stopwatch')
213
                    ->canBeDisabled()
214
                    ->addDefaultsIfNotSet()
215
                        ->children()
216
                            ->scalarNode('stopwatch')
217
                                ->info('This must be a service id to a service extending Symfony\Component\Stopwatch\Stopwatch')
218
                                ->defaultValue('debug.stopwatch')
219
                                ->cannotBeEmpty()
220
                            ->end()
221
                        ->end()
222
                    ->end() // End stopwatch plugin
223
224
                ->end()
225
            ->end()
226
        ->end();
227
    }
228
229
    /**
230
     * Add configuration for authentication plugin
231
     *
232
     * @return ArrayNodeDefinition|\Symfony\Component\Config\Definition\Builder\NodeDefinition
233
     */
234
    private function addAuthenticationPluiginNode()
235
    {
236
        $builder = new TreeBuilder();
237
        $node = $builder->root('authentication');
238
        $node
239
            ->useAttributeAsKey('name')
240
            ->prototype('array')
241
                ->validate()
242
                    ->always()
243
                    ->then(function($config) {
244
                        switch ($config['type']) {
245 View Code Duplication
                            case 'basic':
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...
246
                                if (empty($config['username']) || empty($config['password'])) {
247
                                    throw new InvalidConfigurationException('Authentication "basic" requires both "username" and "password".');
248
                                }
249
                                break;
250
                            case 'bearer':
251
                                if (empty($config['bearer'])) {
252
                                    throw new InvalidConfigurationException('Authentication "bearer" requires a "token".');
253
                                }
254
                                break;
255
                            case 'service':
256
                                if (empty($config['service'])) {
257
                                    throw new InvalidConfigurationException('Authentication "service" requires a "service".');
258
                                }
259
                                break;
260 View Code Duplication
                            case 'wsse':
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...
261
                                if (empty($config['username']) || empty($config['password'])) {
262
                                    throw new InvalidConfigurationException('Authentication "wsse" requires both "username" and "password".');
263
                                }
264
                                break;
265
                        }
266
267
                        return $config;
268
                    })
269
                ->end()
270
                ->children()
271
                    ->enumNode('type')
272
                        ->values(['basic', 'bearer', 'wsse', 'service'])
273
                        ->isRequired()
274
                        ->cannotBeEmpty()
275
                    ->end()
276
                    ->scalarNode('username')->end()
277
                    ->scalarNode('password')->end()
278
                    ->scalarNode('token')->end()
279
                    ->scalarNode('service')->end()
280
                    ->end()
281
                ->end()
282
            ->end(); // End authentication plugin
283
284
        return $node;
285
    }
286
}
287