Completed
Push — master ( 3a2c71...4d4890 )
by Tobias
05:46
created

Configuration::createCachePluginNode()   B

Complexity

Conditions 3
Paths 1

Size

Total Lines 94
Code Lines 78

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 76
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 94
ccs 76
cts 77
cp 0.987
rs 8.4378
c 0
b 0
f 0
cc 3
eloc 78
nc 1
nop 0
crap 3

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
namespace Http\HttplugBundle\DependencyInjection;
4
5
use Http\Client\Common\Plugin\Cache\Generator\CacheKeyGenerator;
6
use Http\Client\Common\Plugin\Journal;
7
use Http\Message\CookieJar;
8
use Http\Message\Formatter;
9
use Http\Message\StreamFactory;
10
use Psr\Cache\CacheItemPoolInterface;
11
use Psr\Log\LoggerInterface;
12
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
13
use Symfony\Component\Config\Definition\Builder\NodeDefinition;
14
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
15
use Symfony\Component\Config\Definition\ConfigurationInterface;
16
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
17
use Symfony\Component\Config\Definition\Exception\InvalidTypeException;
18
19
/**
20
 * This class contains the configuration information for the bundle.
21
 *
22
 * This information is solely responsible for how the different configuration
23
 * sections are normalized, and merged.
24
 *
25
 * @author David Buchmann <[email protected]>
26
 * @author Tobias Nyholm <[email protected]>
27
 */
28
class Configuration implements ConfigurationInterface
29
{
30
    /**
31
     * Whether to use the debug mode.
32
     *
33
     * @see https://github.com/doctrine/DoctrineBundle/blob/v1.5.2/DependencyInjection/Configuration.php#L31-L41
34
     *
35
     * @var bool
36
     */
37
    private $debug;
38
39
    /**
40
     * @param bool $debug
41
     */
42 26
    public function __construct($debug)
43
    {
44 26
        $this->debug = (bool) $debug;
45 26
    }
46
47
    /**
48
     * {@inheritdoc}
49
     */
50 26
    public function getConfigTreeBuilder()
51
    {
52 26
        $treeBuilder = new TreeBuilder();
53 26
        $rootNode = $treeBuilder->root('httplug');
54
55 26
        $this->configureClients($rootNode);
56 26
        $this->configureSharedPlugins($rootNode);
57
58
        $rootNode
59 26
            ->validate()
60
                ->ifTrue(function ($v) {
61 22
                    return !empty($v['classes']['client'])
62 19
                        || !empty($v['classes']['message_factory'])
63 19
                        || !empty($v['classes']['uri_factory'])
64 22
                        || !empty($v['classes']['stream_factory']);
65 26
                })
66
                ->then(function ($v) {
67 3
                    foreach ($v['classes'] as $key => $class) {
68 3
                        if (null !== $class && !class_exists($class)) {
69 1
                            throw new InvalidConfigurationException(sprintf(
70 1
                                'Class %s specified for httplug.classes.%s does not exist.',
71 1
                                $class,
72 3
                                $key
73
                            ));
74
                        }
75
                    }
76
77 2
                    return $v;
78 26
                })
79 26
            ->end()
80 26
            ->beforeNormalization()
81
                ->ifTrue(function ($v) {
82 26
                    return is_array($v) && array_key_exists('toolbar', $v) && is_array($v['toolbar']);
83 26
                })
84
                ->then(function ($v) {
85 4
                    if (array_key_exists('profiling', $v)) {
86 1
                        throw new InvalidConfigurationException('Can\'t configure both "toolbar" and "profiling" section. The "toolbar" config is deprecated as of version 1.3.0, please only use "profiling".');
87
                    }
88
89 3
                    @trigger_error('"httplug.toolbar" config is deprecated since version 1.3 and will be removed in 2.0. Use "httplug.profiling" instead.', E_USER_DEPRECATED);
90
91 3
                    if (array_key_exists('enabled', $v['toolbar']) && 'auto' === $v['toolbar']['enabled']) {
92 1
                        @trigger_error('"auto" value in "httplug.toolbar" config is deprecated since version 1.3 and will be removed in 2.0. Use a boolean value instead.', E_USER_DEPRECATED);
93 1
                        $v['toolbar']['enabled'] = $this->debug;
94
                    }
95
96 3
                    $v['profiling'] = $v['toolbar'];
97
98 3
                    unset($v['toolbar']);
99
100 3
                    return $v;
101 26
                })
102 26
            ->end()
103 26
            ->fixXmlConfig('client')
104 26
            ->children()
105 26
                ->arrayNode('main_alias')
106 26
                    ->addDefaultsIfNotSet()
107 26
                    ->info('Configure which service the main alias point to.')
108 26
                    ->children()
109 26
                        ->scalarNode('client')->defaultValue('httplug.client.default')->end()
110 26
                        ->scalarNode('message_factory')->defaultValue('httplug.message_factory.default')->end()
111 26
                        ->scalarNode('uri_factory')->defaultValue('httplug.uri_factory.default')->end()
112 26
                        ->scalarNode('stream_factory')->defaultValue('httplug.stream_factory.default')->end()
113 26
                    ->end()
114 26
                ->end()
115 26
                ->arrayNode('classes')
116 26
                    ->addDefaultsIfNotSet()
117 26
                    ->info('Overwrite a service class instead of using the discovery mechanism.')
118 26
                    ->children()
119 26
                        ->scalarNode('client')->defaultNull()->end()
120 26
                        ->scalarNode('message_factory')->defaultNull()->end()
121 26
                        ->scalarNode('uri_factory')->defaultNull()->end()
122 26
                        ->scalarNode('stream_factory')->defaultNull()->end()
123 26
                    ->end()
124 26
                ->end()
125 26
                ->arrayNode('profiling')
126 26
                    ->addDefaultsIfNotSet()
127 26
                    ->treatFalseLike(['enabled' => false])
128 26
                    ->treatTrueLike(['enabled' => true])
129 26
                    ->treatNullLike(['enabled' => $this->debug])
130 26
                    ->info('Extend the debug profiler with information about requests.')
131 26
                    ->children()
132 26
                        ->booleanNode('enabled')
133 26
                            ->info('Turn the toolbar on or off. Defaults to kernel debug mode.')
134 26
                            ->defaultValue($this->debug)
135 26
                        ->end()
136 26
                        ->scalarNode('formatter')->defaultNull()->end()
137 26
                        ->integerNode('captured_body_length')
138 26
                            ->defaultValue(0)
139 26
                            ->info('Limit long HTTP message bodies to x characters. If set to 0 we do not read the message body. Only available with the default formatter (FullHttpMessageFormatter).')
140 26
                        ->end()
141 26
                    ->end()
142 26
                ->end()
143 26
                ->arrayNode('discovery')
144 26
                    ->addDefaultsIfNotSet()
145 26
                    ->info('Control what clients should be found by the discovery.')
146 26
                    ->children()
147 26
                        ->scalarNode('client')
148 26
                            ->defaultValue('auto')
149 26
                            ->info('Set to "auto" to see auto discovered client in the web profiler. If provided a service id for a client then this client will be found by auto discovery.')
150 26
                        ->end()
151 26
                        ->scalarNode('async_client')
152 26
                            ->defaultNull()
153 26
                            ->info('Set to "auto" to see auto discovered client in the web profiler. If provided a service id for a client then this client will be found by auto discovery.')
154 26
                        ->end()
155 26
                    ->end()
156 26
                ->end()
157 26
            ->end();
158
159 26
        return $treeBuilder;
160
    }
161
162 26
    private function configureClients(ArrayNodeDefinition $root)
163
    {
164 26
        $root->children()
165 26
            ->arrayNode('clients')
166 26
                ->useAttributeAsKey('name')
167 26
                ->prototype('array')
168 26
                ->fixXmlConfig('plugin')
169 26
                ->validate()
170
                    ->ifTrue(function ($config) {
171
                        // Make sure we only allow one of these to be true
172 9
                        return (bool) $config['flexible_client'] + (bool) $config['http_methods_client'] + (bool) $config['batch_client'] >= 2;
173 26
                    })
174 26
                    ->thenInvalid('A http client can\'t be decorated with several of FlexibleHttpClient, HttpMethodsClient and BatchClient. Only one of the following options can be true. ("flexible_client", "http_methods_client", "batch_client")')
175 26
                ->end()
176 26
                ->validate()
177
                    ->ifTrue(function ($config) {
178 9
                        return 'httplug.factory.auto' === $config['factory'] && !empty($config['config']);
179 26
                    })
180 26
                    ->thenInvalid('If you want to use the "config" key you must also specify a valid "factory".')
181 26
                ->end()
182 26
                ->children()
183 26
                    ->scalarNode('factory')
184 26
                        ->defaultValue('httplug.factory.auto')
185 26
                        ->cannotBeEmpty()
186 26
                        ->info('The service id of a factory to use when creating the adapter.')
187 26
                    ->end()
188 26
                    ->booleanNode('flexible_client')
189 26
                        ->defaultFalse()
190 26
                        ->info('Set to true to get the client wrapped in a FlexibleHttpClient which emulates async or sync behavior.')
191 26
                    ->end()
192 26
                    ->booleanNode('http_methods_client')
193 26
                        ->defaultFalse()
194 26
                        ->info('Set to true to get the client wrapped in a HttpMethodsClient which emulates provides functions for HTTP verbs.')
195 26
                    ->end()
196 26
                    ->booleanNode('batch_client')
197 26
                        ->defaultFalse()
198 26
                        ->info('Set to true to get the client wrapped in a BatchClient which allows you to send multiple request at the same time.')
199 26
                    ->end()
200 26
                    ->variableNode('config')->defaultValue([])->end()
201 26
                    ->append($this->createClientPluginNode())
202 26
                ->end()
203 26
            ->end()
204 26
        ->end();
205 26
    }
206
207
    /**
208
     * @param ArrayNodeDefinition $root
209
     */
210 26
    private function configureSharedPlugins(ArrayNodeDefinition $root)
211
    {
212
        $pluginsNode = $root
213 26
            ->children()
214 26
                ->arrayNode('plugins')
215 26
                ->info('Global plugin configuration. Plugins need to be explicitly added to clients.')
216 26
                ->addDefaultsIfNotSet()
217
            // don't call end to get the plugins node
218
        ;
219 26
        $this->addSharedPluginNodes($pluginsNode);
220 26
    }
221
222
    /**
223
     * Createplugins node of a client.
224
     *
225
     * @return ArrayNodeDefinition The plugin node
226
     */
227 26
    private function createClientPluginNode()
228
    {
229 26
        $builder = new TreeBuilder();
230 26
        $node = $builder->root('plugins');
231
232
        /** @var ArrayNodeDefinition $pluginList */
233
        $pluginList = $node
234 26
            ->info('A list of plugin service ids and client specific plugin definitions. The order is important.')
235 26
            ->prototype('array')
236
        ;
237
        $pluginList
238
            // support having just a service id in the list
239 26
            ->beforeNormalization()
240
                ->always(function ($plugin) {
241 10
                    if (is_string($plugin)) {
242
                        return [
243 9
                            'reference' => [
244
                                'enabled' => true,
245 9
                                'id' => $plugin,
246
                            ],
247
                        ];
248
                    }
249
250 7
                    return $plugin;
251 26
                })
252 26
            ->end()
253
254 26
            ->validate()
255
                ->always(function ($plugins) {
256 9
                    foreach ($plugins as $name => $definition) {
257 9
                        if ('authentication' === $name) {
258 9
                            if (!count($definition)) {
259 9
                                unset($plugins['authentication']);
260
                            }
261 9
                        } elseif (!$definition['enabled']) {
262 9
                            unset($plugins[$name]);
263
                        }
264
                    }
265
266 9
                    return $plugins;
267 26
                })
268 26
            ->end()
269
        ;
270 26
        $this->addSharedPluginNodes($pluginList, true);
271
272
        $pluginList
273 26
            ->children()
274 26
                ->arrayNode('reference')
275 26
                    ->canBeEnabled()
276 26
                    ->info('Reference to a plugin service')
277 26
                    ->children()
278 26
                        ->scalarNode('id')
279 26
                            ->info('Service id of a plugin')
280 26
                            ->isRequired()
281 26
                            ->cannotBeEmpty()
282 26
                        ->end()
283 26
                    ->end()
284 26
                ->end()
285 26
                ->arrayNode('add_host')
286 26
                    ->canBeEnabled()
287 26
                    ->addDefaultsIfNotSet()
288 26
                    ->info('Set scheme, host and port in the request URI.')
289 26
                    ->children()
290 26
                        ->scalarNode('host')
291 26
                            ->info('Host name including protocol and optionally the port number, e.g. https://api.local:8000')
292 26
                            ->isRequired()
293 26
                            ->cannotBeEmpty()
294 26
                        ->end()
295 26
                        ->scalarNode('replace')
296 26
                            ->info('Whether to replace the host if request already specifies one')
297 26
                            ->defaultValue(false)
298 26
                        ->end()
299 26
                    ->end()
300 26
                ->end()
301 26
                ->arrayNode('header_append')
302 26
                    ->canBeEnabled()
303 26
                    ->info('Append headers to the request. If the header already exists the value will be appended to the current value.')
304 26
                    ->fixXmlConfig('header')
305 26
                    ->children()
306 26
                        ->arrayNode('headers')
307 26
                            ->info('Keys are the header names, values the header values')
308 26
                            ->normalizeKeys(false)
309 26
                            ->useAttributeAsKey('name')
310 26
                            ->prototype('scalar')->end()
311 26
                        ->end()
312 26
                    ->end()
313 26
                ->end()
314 26
                ->arrayNode('header_defaults')
315 26
                    ->canBeEnabled()
316 26
                    ->info('Set header to default value if it does not exist.')
317 26
                    ->fixXmlConfig('header')
318 26
                    ->children()
319 26
                        ->arrayNode('headers')
320 26
                            ->info('Keys are the header names, values the header values')
321 26
                            ->normalizeKeys(false)
322 26
                            ->useAttributeAsKey('name')
323 26
                            ->prototype('scalar')->end()
324 26
                        ->end()
325 26
                    ->end()
326 26
                ->end()
327 26
                ->arrayNode('header_set')
328 26
                    ->canBeEnabled()
329 26
                    ->info('Set headers to requests. If the header does not exist it wil be set, if the header already exists it will be replaced.')
330 26
                    ->fixXmlConfig('header')
331 26
                    ->children()
332 26
                        ->arrayNode('headers')
333 26
                            ->info('Keys are the header names, values the header values')
334 26
                            ->normalizeKeys(false)
335 26
                            ->useAttributeAsKey('name')
336 26
                            ->prototype('scalar')->end()
337 26
                        ->end()
338 26
                    ->end()
339 26
                ->end()
340 26
                ->arrayNode('header_remove')
341 26
                    ->canBeEnabled()
342 26
                    ->info('Remove headers from requests.')
343 26
                    ->fixXmlConfig('header')
344 26
                    ->children()
345 26
                        ->arrayNode('headers')
346 26
                            ->info('List of header names to remove')
347 26
                            ->prototype('scalar')->end()
348 26
                        ->end()
349 26
                    ->end()
350 26
                ->end()
351 26
            ->end()
352 26
        ->end();
353
354 26
        return $node;
355
    }
356
357
    /**
358
     * Add the definitions for shared plugin configurations.
359
     *
360
     * @param ArrayNodeDefinition $pluginNode The node to add to.
361
     * @param bool                $disableAll Some shared plugins are enabled by default. On the client, all are disabled by default.
362
     */
363 26
    private function addSharedPluginNodes(ArrayNodeDefinition $pluginNode, $disableAll = false)
364
    {
365 26
        $children = $pluginNode->children();
366
367 26
        $children->append($this->createAuthenticationPluginNode());
368 26
        $children->append($this->createCachePluginNode());
369
370
        $children
371 26
            ->arrayNode('cookie')
372 26
                ->canBeEnabled()
373 26
                ->children()
374 26
                    ->scalarNode('cookie_jar')
375 26
                        ->info('This must be a service id to a service implementing '.CookieJar::class)
376 26
                        ->isRequired()
377 26
                        ->cannotBeEmpty()
378 26
                    ->end()
379 26
                ->end()
380 26
            ->end();
381
        // End cookie plugin
382
383
        $children
384 26
            ->arrayNode('history')
385 26
                ->canBeEnabled()
386 26
                ->children()
387 26
                    ->scalarNode('journal')
388 26
                        ->info('This must be a service id to a service implementing '.Journal::class)
389 26
                        ->isRequired()
390 26
                        ->cannotBeEmpty()
391 26
                    ->end()
392 26
                ->end()
393 26
            ->end();
394
        // End history plugin
395
396 26
        $decoder = $children->arrayNode('decoder');
397 26
        $disableAll ? $decoder->canBeEnabled() : $decoder->canBeDisabled();
398 26
        $decoder->addDefaultsIfNotSet()
399 26
            ->children()
400 26
                ->scalarNode('use_content_encoding')->defaultTrue()->end()
401 26
            ->end()
402 26
        ->end();
403
        // End decoder plugin
404
405 26
        $logger = $children->arrayNode('logger');
406 26
        $disableAll ? $logger->canBeEnabled() : $logger->canBeDisabled();
407 26
        $logger->addDefaultsIfNotSet()
408 26
            ->children()
409 26
                ->scalarNode('logger')
410 26
                    ->info('This must be a service id to a service implementing '.LoggerInterface::class)
411 26
                    ->defaultValue('logger')
412 26
                    ->cannotBeEmpty()
413 26
                ->end()
414 26
                ->scalarNode('formatter')
415 26
                    ->info('This must be a service id to a service implementing '.Formatter::class)
416 26
                    ->defaultNull()
417 26
                ->end()
418 26
            ->end()
419 26
        ->end();
420
        // End logger plugin
421
422 26
        $redirect = $children->arrayNode('redirect');
423 26
        $disableAll ? $redirect->canBeEnabled() : $redirect->canBeDisabled();
424 26
        $redirect->addDefaultsIfNotSet()
425 26
            ->children()
426 26
                ->scalarNode('preserve_header')->defaultTrue()->end()
427 26
                ->scalarNode('use_default_for_multiple')->defaultTrue()->end()
428 26
            ->end()
429 26
        ->end();
430
        // End redirect plugin
431
432 26
        $retry = $children->arrayNode('retry');
433 26
        $disableAll ? $retry->canBeEnabled() : $retry->canBeDisabled();
434 26
        $retry->addDefaultsIfNotSet()
435 26
            ->children()
436 26
                ->scalarNode('retry')->defaultValue(1)->end() // TODO: should be called retries for consistency with the class
437 26
            ->end()
438 26
        ->end();
439
        // End retry plugin
440
441 26
        $stopwatch = $children->arrayNode('stopwatch');
442 26
        $disableAll ? $stopwatch->canBeEnabled() : $stopwatch->canBeDisabled();
443 26
        $stopwatch->addDefaultsIfNotSet()
444 26
            ->children()
445 26
                ->scalarNode('stopwatch')
446 26
                    ->info('This must be a service id to a service extending Symfony\Component\Stopwatch\Stopwatch')
447 26
                    ->defaultValue('debug.stopwatch')
448 26
                    ->cannotBeEmpty()
449 26
                ->end()
450 26
            ->end()
451 26
        ->end();
452
        // End stopwatch plugin
453 26
    }
454
455
    /**
456
     * Create configuration for authentication plugin.
457
     *
458
     * @return NodeDefinition Definition for the authentication node in the plugins list.
459
     */
460 26
    private function createAuthenticationPluginNode()
461
    {
462 26
        $builder = new TreeBuilder();
463 26
        $node = $builder->root('authentication');
464
        $node
465 26
            ->useAttributeAsKey('name')
466 26
            ->prototype('array')
467 26
                ->validate()
468 26
                    ->always()
469
                    ->then(function ($config) {
470 7
                        switch ($config['type']) {
471 7
                            case 'basic':
472 6
                                $this->validateAuthenticationType(['username', 'password'], $config, 'basic');
473
474 6
                                break;
475 2
                            case 'bearer':
476 1
                                $this->validateAuthenticationType(['token'], $config, 'bearer');
477
478 1
                                break;
479 2
                            case 'service':
480 2
                                $this->validateAuthenticationType(['service'], $config, 'service');
481
482 1
                                break;
483 1
                            case 'wsse':
484 1
                                $this->validateAuthenticationType(['username', 'password'], $config, 'wsse');
485
486 1
                                break;
487
                        }
488
489 6
                        return $config;
490 26
                    })
491 26
                ->end()
492 26
                ->children()
493 26
                    ->enumNode('type')
494 26
                        ->values(['basic', 'bearer', 'wsse', 'service'])
495 26
                        ->isRequired()
496 26
                        ->cannotBeEmpty()
497 26
                    ->end()
498 26
                    ->scalarNode('username')->end()
499 26
                    ->scalarNode('password')->end()
500 26
                    ->scalarNode('token')->end()
501 26
                    ->scalarNode('service')->end()
502 26
                    ->end()
503 26
                ->end()
504 26
            ->end(); // End authentication plugin
505
506 26
        return $node;
507
    }
508
509
    /**
510
     * Validate that the configuration fragment has the specified keys and none other.
511
     *
512
     * @param array  $expected Fields that must exist
513
     * @param array  $actual   Actual configuration hashmap
514
     * @param string $authName Name of authentication method for error messages
515
     *
516
     * @throws InvalidConfigurationException If $actual does not have exactly the keys specified in $expected (plus 'type')
517
     */
518 7
    private function validateAuthenticationType(array $expected, array $actual, $authName)
519
    {
520 7
        unset($actual['type']);
521 7
        $actual = array_keys($actual);
522 7
        sort($actual);
523 7
        sort($expected);
524
525 7
        if ($expected === $actual) {
526 6
            return;
527
        }
528
529 1
        throw new InvalidConfigurationException(sprintf(
530 1
            'Authentication "%s" requires %s but got %s',
531 1
            $authName,
532 1
            implode(', ', $expected),
533 1
            implode(', ', $actual)
534
        ));
535
    }
536
537
    /**
538
     * Create configuration for cache plugin.
539
     *
540
     * @return NodeDefinition Definition for the cache node in the plugins list.
541
     */
542 26
    private function createCachePluginNode()
543
    {
544 26
        $builder = new TreeBuilder();
545
546 26
        $config = $builder->root('config');
547
        $config
548 26
            ->fixXmlConfig('method')
549 26
            ->fixXmlConfig('respect_response_cache_directive')
550 26
            ->addDefaultsIfNotSet()
551 26
            ->validate()
552
                ->ifTrue(function ($config) {
553
                    // Cannot set both respect_cache_headers and respect_response_cache_directives
554 5
                    return isset($config['respect_cache_headers'], $config['respect_response_cache_directives']);
555 26
                })
556 26
                ->thenInvalid('You can\'t provide config option "respect_cache_headers" and "respect_response_cache_directives" simultaniously. Use "respect_response_cache_directives" instead.')
557 26
            ->end()
558 26
            ->children()
559 26
                ->scalarNode('cache_key_generator')
560 26
                    ->info('This must be a service id to a service implementing '.CacheKeyGenerator::class)
561 26
                ->end()
562 26
                ->integerNode('cache_lifetime')
563 26
                    ->info('The minimum time we should store a cache item')
564 26
                ->end()
565 26
                ->integerNode('default_ttl')
566 26
                    ->info('The default max age of a Response')
567 26
                ->end()
568 26
                ->enumNode('hash_algo')
569 26
                    ->info('Hashing algorithm to use')
570 26
                    ->values(hash_algos())
571 26
                    ->cannotBeEmpty()
572 26
                ->end()
573 26
                ->arrayNode('methods')
574 26
                    ->info('Which request methods to cache')
575 26
                    ->defaultValue(['GET', 'HEAD'])
576 26
                    ->prototype('scalar')
577 26
                        ->validate()
578
                            ->ifTrue(function ($v) {
579
                                /* RFC7230 sections 3.1.1 and 3.2.6 except limited to uppercase characters. */
580 1
                                return preg_match('/[^A-Z0-9!#$%&\'*+\-.^_`|~]+/', $v);
581 26
                            })
582 26
                            ->thenInvalid('Invalid method: %s')
583 26
                        ->end()
584 26
                    ->end()
585 26
                ->end()
586 26
                ->scalarNode('respect_cache_headers')
587 26
                    ->info('Whether we should care about cache headers or not [DEPRECATED]')
588 26
                    ->beforeNormalization()
589
                        ->always(function ($v) {
590 3
                            @trigger_error('The option "respect_cache_headers" is deprecated since version 1.3 and will be removed in 2.0. Use "respect_response_cache_directives" instead.', E_USER_DEPRECATED);
591
592 3
                            return $v;
593 26
                        })
594 26
                    ->end()
595 26
                    ->validate()
596 26
                        ->ifNotInArray([null, true, false])
597 26
                        ->thenInvalid('Value for "respect_cache_headers" must be null or boolean')
598 26
                    ->end()
599 26
                ->end()
600 26
                ->variableNode('respect_response_cache_directives')
601 26
                    ->info('A list of cache directives to respect when caching responses')
602 26
                    ->validate()
603 26
                        ->always(function ($v) {
604 2
                            if (is_null($v) || is_array($v)) {
605 2
                                return $v;
606
                            }
607
608
                            throw new InvalidTypeException();
609 26
                        })
610 26
                    ->end()
611 26
                ->end()
612 26
            ->end()
613
        ;
614
615 26
        $cache = $builder->root('cache');
616
        $cache
617 26
            ->canBeEnabled()
618 26
            ->addDefaultsIfNotSet()
619 26
            ->children()
620 26
                ->scalarNode('cache_pool')
621 26
                    ->info('This must be a service id to a service implementing '.CacheItemPoolInterface::class)
622 26
                    ->isRequired()
623 26
                    ->cannotBeEmpty()
624 26
                ->end()
625 26
                ->scalarNode('stream_factory')
626 26
                    ->info('This must be a service id to a service implementing '.StreamFactory::class)
627 26
                    ->defaultValue('httplug.stream_factory')
628 26
                    ->cannotBeEmpty()
629 26
                ->end()
630 26
            ->end()
631 26
            ->append($config)
632
        ;
633
634 26
        return $cache;
635
    }
636
}
637