Completed
Pull Request — master (#235)
by David
03:36
created

Configuration::getHttpDispatcherNode()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 29
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 23
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 29
ccs 23
cts 23
cp 1
rs 8.8571
c 0
b 0
f 0
cc 1
eloc 24
nc 1
nop 0
crap 1
1
<?php
2
3
/*
4
 * This file is part of the FOSHttpCacheBundle package.
5
 *
6
 * (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace FOS\HttpCacheBundle\DependencyInjection;
13
14
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
15
use Symfony\Component\Config\Definition\Builder\NodeBuilder;
16
use Symfony\Component\Config\Definition\Builder\NodeDefinition;
17
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
18
use Symfony\Component\Config\Definition\ConfigurationInterface;
19
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
20
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
21
22
/**
23
 * This class contains the configuration information for the bundle.
24
 *
25
 * This information is solely responsible for how the different configuration
26
 * sections are normalized, and merged.
27
 *
28
 * @author David de Boer <[email protected]>
29
 * @author David Buchmann <[email protected]>
30
 */
31
class Configuration implements ConfigurationInterface
32
{
33
    /**
34
     * @var bool
35
     */
36
    private $debug;
37
38
    /**
39
     * @param bool $debug Whether to use the debug mode
40
     */
41 33
    public function __construct($debug)
42
    {
43 33
        $this->debug = $debug;
44 33
    }
45
46
    /**
47
     * {@inheritdoc}
48
     */
49 33
    public function getConfigTreeBuilder()
50
    {
51 33
        $treeBuilder = new TreeBuilder();
52 33
        $rootNode = $treeBuilder->root('fos_http_cache');
53
54
        $rootNode
55 33
            ->validate()
56
                ->ifTrue(function ($v) {
57 31
                    return $v['cache_manager']['enabled']
58 31
                        && !isset($v['proxy_client'])
59 31
                        && !isset($v['cache_manager']['custom_proxy_client'])
60
                    ;
61 33
                })
62
                ->then(function ($v) {
63 7
                    if ('auto' === $v['cache_manager']['enabled']) {
64 6
                        $v['cache_manager']['enabled'] = false;
65
66 6
                        return $v;
67
                    }
68 1
                    throw new InvalidConfigurationException('You need to configure a proxy_client or specify a custom_proxy_client to use the cache_manager.');
69 33
                })
70 33
            ->end()
71 33
            ->validate()
72
                ->ifTrue(function ($v) {
73 30
                    return $v['tags']['enabled'] && !$v['cache_manager']['enabled'];
74 33
                })
75
                ->then(function ($v) {
76 8
                    if ('auto' === $v['tags']['enabled']) {
77 7
                        $v['tags']['enabled'] = false;
78
79 7
                        return $v;
80
                    }
81 1
                    throw new InvalidConfigurationException('You need to configure a proxy_client to get the cache_manager needed for tag handling.');
82 33
                })
83 33
            ->end()
84 33
            ->validate()
85
                ->ifTrue(function ($v) {
86 29
                    return $v['invalidation']['enabled'] && !$v['cache_manager']['enabled'];
87 33
                })
88
                ->then(function ($v) {
89 7
                    if ('auto' === $v['invalidation']['enabled']) {
90 6
                        $v['invalidation']['enabled'] = false;
91
92 6
                        return $v;
93
                    }
94 1
                    throw new InvalidConfigurationException('You need to configure a proxy_client to get the cache_manager needed for invalidation handling.');
95 33
                })
96 33
            ->end()
97 33
            ->validate()
98 33
                ->ifTrue(
99
                    function ($v) {
100 28
                        return $v['user_context']['logout_handler']['enabled']
101 28
                            && !isset($v['proxy_client']);
102 33
                    }
103
                )
104
                ->then(function ($v) {
105 8
                    if ('auto' === $v['user_context']['logout_handler']['enabled']) {
106 8
                        $v['user_context']['logout_handler']['enabled'] = false;
107
108 8
                        return $v;
109
                    }
110
                    throw new InvalidConfigurationException('You need to configure a proxy_client for the logout_handler.');
111 33
                })
112
        ;
113
114 33
        $this->addCacheControlSection($rootNode);
115 33
        $this->addProxyClientSection($rootNode);
116 33
        $this->addCacheManagerSection($rootNode);
117 33
        $this->addTagSection($rootNode);
118 33
        $this->addInvalidationSection($rootNode);
119 33
        $this->addUserContextListenerSection($rootNode);
120 33
        $this->addFlashMessageSection($rootNode);
121 33
        $this->addTestSection($rootNode);
122 33
        $this->addDebugSection($rootNode);
123
124 33
        return $treeBuilder;
125
    }
126
127
    /**
128
     * Cache header control main section.
129
     *
130
     * @param ArrayNodeDefinition $rootNode
131
     */
132 33
    private function addCacheControlSection(ArrayNodeDefinition $rootNode)
133
    {
134
        $rules = $rootNode
135 33
            ->children()
136 33
                ->arrayNode('cache_control')
137 33
                    ->fixXmlConfig('rule')
138 33
                    ->children()
139 33
                        ->arrayNode('defaults')
140 33
                            ->addDefaultsIfNotSet()
141 33
                            ->children()
142 33
                                ->booleanNode('overwrite')
143 33
                                    ->info('Whether to overwrite existing cache headers')
144 33
                                    ->defaultFalse()
145 33
                                ->end()
146 33
                            ->end()
147 33
                        ->end()
148 33
                        ->arrayNode('rules')
149 33
                            ->prototype('array')
150 33
                                ->children();
151
152 33
        $this->addMatch($rules);
153
        $rules
154 33
            ->arrayNode('headers')
155 33
                ->isRequired()
156
                // todo validate there is some header defined
157 33
                ->children()
158 33
                    ->enumNode('overwrite')
159 33
                        ->info('Whether to overwrite cache headers for this rule, defaults to the cache_control.defaults.overwrite setting')
160 33
                        ->values(array('default', true, false))
161 33
                        ->defaultValue('default')
162 33
                    ->end()
163 33
                    ->arrayNode('cache_control')
164 33
                        ->info('Add the specified cache control directives.')
165 33
                        ->children()
166 33
                            ->scalarNode('max_age')->end()
167 33
                            ->scalarNode('s_maxage')->end()
168 33
                            ->booleanNode('private')->end()
169 33
                            ->booleanNode('public')->end()
170 33
                            ->booleanNode('must_revalidate')->end()
171 33
                            ->booleanNode('proxy_revalidate')->end()
172 33
                            ->booleanNode('no_transform')->end()
173 33
                            ->booleanNode('no_cache')->end()
174 33
                            ->scalarNode('stale_if_error')->end()
175 33
                            ->scalarNode('stale_while_revalidate')->end()
176 33
                        ->end()
177 33
                    ->end()
178 33
                    ->booleanNode('etag')
179 33
                        ->defaultValue(false)
180 33
                        ->info('Set a simple ETag which is just the md5 hash of the response body')
181 33
                    ->end()
182 33
                    ->scalarNode('last_modified')
183 33
                        ->validate()
184
                            ->ifTrue(function ($v) {
185 2
                                if (is_string($v)) {
186 2
                                    new \DateTime($v);
187
                                }
188
189 1
                                return false;
190 33
                            })
191 33
                            ->thenInvalid('') // this will never happen as new DateTime will throw an exception if $v is no date
192 33
                        ->end()
193 33
                        ->info('Set a default last modified timestamp if none is set yet. Value must be parseable by DateTime')
194 33
                    ->end()
195 33
                    ->scalarNode('reverse_proxy_ttl')
196 33
                        ->defaultNull()
197 33
                        ->info('Specify an X-Reverse-Proxy-TTL header with a time in seconds for a caching proxy under your control.')
198 33
                    ->end()
199 33
                    ->arrayNode('vary')
200
                        ->beforeNormalization()->ifString()->then(function ($v) {
201 2
                            return preg_split('/\s*,\s*/', $v);
202 33
                        })->end()
203 33
                        ->prototype('scalar')->end()
204 33
                        ->info('Define a list of additional headers on which the response varies.')
205 33
                    ->end()
206 33
                ->end()
207 33
            ->end()
208
        ;
209 33
    }
210
211
    /**
212
     * Shared configuration between cache control, tags and invalidation.
213
     *
214
     * @param NodeBuilder $rules
215
     */
216 33
    private function addMatch(NodeBuilder $rules)
217
    {
218
        $rules
219 33
            ->arrayNode('match')
220 33
                ->cannotBeOverwritten()
221 33
                ->isRequired()
222 33
                ->fixXmlConfig('method')
223 33
                ->fixXmlConfig('ip')
224 33
                ->fixXmlConfig('attribute')
225 33
                ->validate()
226
                    ->ifTrue(function ($v) {
227 9
                        return !empty($v['additional_cacheable_status']) && !empty($v['match_response']);
228 33
                    })
229 33
                    ->thenInvalid('You may not set both additional_cacheable_status and match_response.')
230 33
                ->end()
231 33
                ->validate()
232
                    ->ifTrue(function ($v) {
233 8
                        return !empty($v['match_response']) && !class_exists('Symfony\Component\ExpressionLanguage\ExpressionLanguage');
234 33
                    })
235 33
                    ->thenInvalid('Configured a match_response but ExpressionLanguage is not available')
236 33
                ->end()
237 33
                ->children()
238 33
                    ->scalarNode('path')
239 33
                        ->defaultNull()
240 33
                        ->info('Request path.')
241 33
                    ->end()
242 33
                    ->scalarNode('host')
243 33
                        ->defaultNull()
244 33
                        ->info('Request host name.')
245 33
                    ->end()
246 33
                    ->arrayNode('methods')
247
                        ->beforeNormalization()->ifString()->then(function ($v) {
248 3
                            return preg_split('/\s*,\s*/', $v);
249 33
                        })->end()
250 33
                        ->useAttributeAsKey('name')
251 33
                        ->prototype('scalar')->end()
252 33
                        ->info('Request HTTP methods.')
253 33
                    ->end()
254 33
                    ->arrayNode('ips')
255
                        ->beforeNormalization()->ifString()->then(function ($v) {
256 3
                            return preg_split('/\s*,\s*/', $v);
257 33
                        })->end()
258 33
                        ->useAttributeAsKey('name')
259 33
                        ->prototype('scalar')->end()
260 33
                        ->info('List of client IPs.')
261 33
                    ->end()
262 33
                    ->arrayNode('attributes')
263 33
                        ->useAttributeAsKey('name')
264 33
                        ->prototype('scalar')->end()
265 33
                        ->info('Regular expressions on request attributes.')
266 33
                    ->end()
267 33
                    ->arrayNode('additional_cacheable_status')
268 33
                        ->prototype('scalar')->end()
269 33
                        ->info('Additional response HTTP status codes that will match.')
270 33
                    ->end()
271 33
                    ->scalarNode('match_response')
272 33
                        ->defaultNull()
273 33
                        ->info('Expression to decide whether response should be matched. Replaces HTTP code check and additional_cacheable_status.')
274 33
                    ->end()
275 33
                ->end()
276 33
            ->end()
277
        ;
278 33
    }
279
280 33
    private function addProxyClientSection(ArrayNodeDefinition $rootNode)
281
    {
282
        $rootNode
283 33
            ->children()
284 33
                ->arrayNode('proxy_client')
285 33
                    ->children()
286 33
                        ->enumNode('default')
287 33
                            ->values(array('varnish', 'nginx', 'symfony'))
288 33
                            ->info('If you configure more than one proxy client, you need to specify which client is the default.')
289 33
                        ->end()
290 33
                        ->arrayNode('varnish')
291 33
                            ->children()
292 33
                                    ->append($this->getHttpDispatcherNode())
293 33
                            ->end()
294 33
                        ->end()
295
296 33
                        ->arrayNode('nginx')
297 33
                            ->children()
298 33
                                ->scalarNode('purge_location')
299 33
                                    ->defaultValue(false)
300 33
                                    ->info('Path to trigger the purge on Nginx for different location purge.')
301 33
                                ->end()
302 33
                                ->append($this->getHttpDispatcherNode())
303 33
                            ->end()
304 33
                        ->end()
305
306 33
                        ->arrayNode('symfony')
307 33
                            ->children()
308 33
                                ->append($this->getHttpDispatcherNode())
309 33
                            ->end()
310 33
                        ->end()
311
312 33
                    ->end()
313 33
                ->end()
314 33
            ->end();
315 33
    }
316
317
    /**
318
     * Get the configuration node for a HTTP dispatcher in a proxy client.
319
     *
320
     * @return NodeDefinition
321
     */
322 33
    private function getHttpDispatcherNode()
323
    {
324 33
        $treeBuilder = new TreeBuilder();
325 33
        $node = $treeBuilder->root('http');
326
327
        $node
328 33
            ->fixXmlConfig('server')
329 33
            ->isRequired()
330 33
            ->children()
331 33
                ->arrayNode('servers')
332 33
                    ->info('Addresses of the hosts the caching proxy is running on. May be hostname or ip, and with :port if not the default port 80.')
333 33
                    ->useAttributeAsKey('name')
334 33
                    ->isRequired()
335 33
                    ->requiresAtLeastOneElement()
336 33
                    ->prototype('scalar')->end()
337 33
                ->end()
338 33
                ->scalarNode('base_url')
339 33
                    ->defaultNull()
340 33
                    ->info('Default host name and optional path for path based invalidation.')
341 33
                ->end()
342 33
                ->scalarNode('http_client')
343 33
                    ->defaultNull()
344 33
                    ->info('Httplug async client service name to use for sending the requests.')
345 33
                ->end()
346 33
            ->end()
347
        ;
348
349 33
        return $node;
350
    }
351
352 33
    private function addTestSection(ArrayNodeDefinition $rootNode)
353
    {
354
        $rootNode
355 33
            ->children()
356 33
                ->arrayNode('test')
357 33
                    ->children()
358 33
                        ->scalarNode('cache_header')
359 33
                            ->defaultValue('X-Cache')
360 33
                            ->info('HTTP cache hit/miss header')
361 33
                        ->end()
362 33
                        ->arrayNode('proxy_server')
363 33
                            ->info('Configure how caching proxy will be run in your tests')
364 33
                            ->children()
365 33
                                ->enumNode('default')
366 33
                                    ->values(array('varnish', 'nginx'))
367 33
                                    ->info('If you configure more than one proxy server, specify which client is the default.')
368 33
                                ->end()
369 33
                                ->arrayNode('varnish')
370 33
                                    ->children()
371 33
                                        ->scalarNode('config_file')->isRequired()->end()
372 33
                                        ->scalarNode('binary')->defaultValue('varnishd')->end()
373 33
                                        ->integerNode('port')->defaultValue(6181)->end()
374 33
                                        ->scalarNode('ip')->defaultValue('127.0.0.1')->end()
375 33
                                    ->end()
376 33
                                ->end()
377 33
                                ->arrayNode('nginx')
378 33
                                    ->children()
379 33
                                        ->scalarNode('config_file')->isRequired()->end()
380 33
                                        ->scalarNode('binary')->defaultValue('nginx')->end()
381 33
                                        ->integerNode('port')->defaultValue(8080)->end()
382 33
                                        ->scalarNode('ip')->defaultValue('127.0.0.1')->end()
383 33
                                    ->end()
384 33
                                ->end()
385 33
                            ->end()
386 33
                        ->end()
387 33
                    ->end()
388 33
                ->end()
389 33
            ->end();
390 33
    }
391
392
    /**
393
     * Cache manager main section.
394
     *
395
     * @param ArrayNodeDefinition $rootNode
396
     */
397 33
    private function addCacheManagerSection(ArrayNodeDefinition $rootNode)
398
    {
399
        $rootNode
400 33
            ->children()
401 33
                ->arrayNode('cache_manager')
402 33
                    ->addDefaultsIfNotSet()
403 33
                    ->beforeNormalization()
404 33
                        ->ifArray()
405
                        ->then(function ($v) {
406 6
                            $v['enabled'] = isset($v['enabled']) ? $v['enabled'] : true;
407
408 6
                            return $v;
409 33
                        })
410 33
                    ->end()
411 33
                    ->info('Configure the cache manager. Needs a proxy_client to be configured.')
412 33
                    ->children()
413 33
                        ->enumNode('enabled')
414 33
                            ->values(array(true, false, 'auto'))
415 33
                            ->defaultValue('auto')
416 33
                            ->info('Allows to disable the invalidation manager. Enabled by default if you configure a proxy client.')
417 33
                        ->end()
418 33
                        ->scalarNode('custom_proxy_client')
419 33
                            ->info('Service name of a custom proxy client to use. With a custom client, generate_url_type defaults to ABSOLUTE_URL and tag support needs to be explicitly enabled. If no custom proxy client is specified, the first proxy client you configured is used.')
420 33
                        ->end()
421 33
                        ->enumNode('generate_url_type')
422 33
                            ->values(array(
423 33
                                'auto',
424
                                UrlGeneratorInterface::ABSOLUTE_PATH,
425
                                UrlGeneratorInterface::ABSOLUTE_URL,
426
                                UrlGeneratorInterface::NETWORK_PATH,
427
                                UrlGeneratorInterface::RELATIVE_PATH,
428
                            ))
429 33
                            ->defaultValue('auto')
430 33
                            ->info('Set what URLs to generate on invalidate/refresh Route. Auto means path if base_url is set on the default proxy client, full URL otherwise.')
431 33
                        ->end()
432 33
                    ->end()
433
        ;
434 33
    }
435
436 33
    private function addTagSection(ArrayNodeDefinition $rootNode)
437
    {
438
        $rules = $rootNode
439 33
            ->children()
440 33
                ->arrayNode('tags')
441 33
                    ->addDefaultsIfNotSet()
442 33
                    ->fixXmlConfig('rule')
443 33
                    ->children()
444 33
                        ->enumNode('enabled')
445 33
                            ->values(array(true, false, 'auto'))
446 33
                            ->defaultValue('auto')
447 33
                            ->info('Allows to disable the event subscriber for tag configuration and annotations when your project does not use the annotations. Enabled by default if you configured the cache manager.')
448 33
                        ->end()
449 33
                        ->scalarNode('expression_language')
450 33
                            ->defaultNull()
451 33
                            ->info('Service name of a custom ExpressionLanugage to use.')
452 33
                        ->end()
453 33
                        ->scalarNode('header')
454 33
                            ->defaultValue('X-Cache-Tags')
455 33
                            ->info('HTTP header that contains cache tags')
456 33
                        ->end()
457 33
                        ->arrayNode('rules')
458 33
                            ->prototype('array')
459 33
                                ->fixXmlConfig('tag')
460 33
                                ->fixXmlConfig('tag_expression')
461 33
                                ->validate()
462 33
                                    ->ifTrue(function ($v) {
463 3
                                        return !empty($v['tag_expressions']) && !class_exists('Symfony\Component\ExpressionLanguage\ExpressionLanguage');
464 33
                                    })
465 33
                                    ->thenInvalid('Configured a tag_expression but ExpressionLanugage is not available')
466 33
                                ->end()
467 33
                                ->children();
468
469 33
        $this->addMatch($rules);
470
471
        $rules
472 33
            ->arrayNode('tags')
473 33
                ->prototype('scalar')
474 33
                ->info('Tags to add to the response on safe requests, to invalidate on unsafe requests')
475 33
            ->end()->end()
476 33
            ->arrayNode('tag_expressions')
477 33
                ->prototype('scalar')
478 33
                ->info('Tags to add to the response on safe requests, to invalidate on unsafe requests')
479 33
            ->end()
480
        ;
481 33
    }
482
483 33
    private function addInvalidationSection(ArrayNodeDefinition $rootNode)
484
    {
485
        $rules = $rootNode
486 33
            ->children()
487 33
                ->arrayNode('invalidation')
488 33
                    ->fixXmlConfig('rule')
489 33
                    ->addDefaultsIfNotSet()
490 33
                    ->children()
491 33
                        ->enumNode('enabled')
492 33
                            ->values(array(true, false, 'auto'))
493 33
                            ->defaultValue('auto')
494 33
                            ->info('Allows to disable the listener for invalidation. Enabled by default if the cache manager is configured. When disabled, the cache manager is no longer flushed automatically.')
495 33
                        ->end()
496 33
                        ->scalarNode('expression_language')
497 33
                            ->defaultNull()
498 33
                            ->info('Service name of a custom ExpressionLanugage to use.')
499 33
                        ->end()
500 33
                        ->arrayNode('rules')
501 33
                            ->info('Set what requests should invalidate which target routes.')
502 33
                            ->prototype('array')
503 33
                                ->fixXmlConfig('route')
504 33
                                ->children();
505
506 33
        $this->addMatch($rules);
507
        $rules
508 33
            ->arrayNode('routes')
509 33
                ->isRequired()
510 33
                ->requiresAtLeastOneElement()
511 33
                ->useAttributeAsKey('name')
512 33
                ->info('Target routes to invalidate when request is matched')
513 33
                ->prototype('array')
514 33
                    ->children()
515 33
                        ->booleanNode('ignore_extra_params')->defaultTrue()->end()
516 33
                    ->end()
517 33
                ->end()
518 33
            ->end();
519 33
    }
520
521
    /**
522
     * User context main section.
523
     *
524
     * @param ArrayNodeDefinition $rootNode
525
     */
526 33
    private function addUserContextListenerSection(ArrayNodeDefinition $rootNode)
527
    {
528
        $rootNode
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Symfony\Component\Config...\Builder\NodeDefinition as the method addDefaultsIfNotSet() does only exist in the following sub-classes of Symfony\Component\Config...\Builder\NodeDefinition: Symfony\Component\Config...der\ArrayNodeDefinition. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
529 33
            ->children()
530 33
                ->arrayNode('user_context')
531 33
                    ->info('Listener that returns the request for the user context hash as early as possible.')
532 33
                    ->addDefaultsIfNotSet()
533 33
                    ->canBeEnabled()
534 33
                    ->fixXmlConfig('user_identifier_header')
535 33
                    ->children()
536 33
                        ->arrayNode('match')
537 33
                            ->addDefaultsIfNotSet()
538 33
                            ->children()
539 33
                                ->scalarNode('matcher_service')
540 33
                                    ->defaultValue('fos_http_cache.user_context.request_matcher')
541 33
                                    ->info('Service id of a request matcher that tells whether the request is a context hash request.')
542 33
                                ->end()
543 33
                                ->scalarNode('accept')
544 33
                                    ->defaultValue('application/vnd.fos.user-context-hash')
545 33
                                    ->info('Specify the accept HTTP header used for context hash requests.')
546 33
                                ->end()
547 33
                                ->scalarNode('method')
548 33
                                    ->defaultNull()
549 33
                                    ->info('Specify the HTTP method used for context hash requests.')
550 33
                                ->end()
551 33
                            ->end()
552 33
                        ->end()
553 33
                        ->scalarNode('hash_cache_ttl')
554 33
                            ->defaultValue(0)
555 33
                            ->info('Cache the response for the hash for the specified number of seconds. Setting this to 0 will not cache those responses at all.')
556 33
                        ->end()
557 33
                        ->booleanNode('always_vary_on_context_hash')
558 33
                            ->defaultTrue()
559 33
                            ->info('Whether to always add the user context hash header name in the response Vary header.')
560 33
                        ->end()
561 33
                        ->arrayNode('user_identifier_headers')
562 33
                            ->prototype('scalar')->end()
563 33
                            ->defaultValue(array('Cookie', 'Authorization'))
564 33
                            ->info('List of headers that contains the unique identifier for the user in the hash request.')
565 33
                        ->end()
566 33
                        ->scalarNode('user_hash_header')
567 33
                            ->defaultValue('X-User-Context-Hash')
568 33
                            ->info('Name of the header that contains the hash information for the context.')
569 33
                        ->end()
570 33
                        ->booleanNode('role_provider')
571 33
                            ->defaultFalse()
572 33
                            ->info('Whether to enable a provider that automatically adds all roles of the current user to the context.')
573 33
                        ->end()
574 33
                        ->arrayNode('logout_handler')
575 33
                            ->addDefaultsIfNotSet()
576 33
                            ->canBeEnabled()
577 33
                            ->children()
578 33
                                ->enumNode('enabled')
579 33
                                    ->values(array(true, false, 'auto'))
580 33
                                    ->defaultValue('auto')
581 33
                                    ->info('Whether to enable the user context logout handler.')
582 33
                                ->end()
583 33
                            ->end()
584 33
                        ->end()
585 33
                    ->end()
586 33
                ->end()
587 33
            ->end()
588
        ;
589 33
    }
590
591 33
    private function addFlashMessageSection(ArrayNodeDefinition $rootNode)
592
    {
593
        $rootNode
594 33
            ->children()
595 33
                ->arrayNode('flash_message')
596 33
                    ->canBeUnset()
597 33
                    ->canBeEnabled()
598 33
                    ->info('Activate the flash message listener that puts flash messages into a cookie.')
599 33
                    ->children()
600 33
                        ->scalarNode('name')
601 33
                            ->defaultValue('flashes')
602 33
                            ->info('Name of the cookie to set for flashes.')
603 33
                        ->end()
604 33
                        ->scalarNode('path')
605 33
                            ->defaultValue('/')
606 33
                            ->info('Cookie path validity.')
607 33
                        ->end()
608 33
                        ->scalarNode('host')
609 33
                            ->defaultNull()
610 33
                            ->info('Cookie host name validity.')
611 33
                        ->end()
612 33
                        ->scalarNode('secure')
613 33
                            ->defaultFalse()
614 33
                            ->info('Whether the cookie should only be transmitted over a secure HTTPS connection from the client.')
615 33
                        ->end()
616 33
                    ->end()
617 33
                ->end()
618 33
            ->end();
619 33
    }
620
621 33
    private function addDebugSection(ArrayNodeDefinition $rootNode)
622
    {
623
        $rootNode
624 33
            ->children()
625 33
                ->arrayNode('debug')
626 33
                ->addDefaultsIfNotSet()
627 33
                ->canBeEnabled()
628 33
                ->children()
629 33
                    ->booleanNode('enabled')
630 33
                        ->defaultValue($this->debug)
631 33
                        ->info('Whether to send a debug header with the response to trigger a caching proxy to send debug information. If not set, defaults to kernel.debug.')
632 33
                    ->end()
633 33
                    ->scalarNode('header')
634 33
                        ->defaultValue('X-Cache-Debug')
635 33
                        ->info('The header to send if debug is true.')
636 33
                    ->end()
637 33
                ->end()
638 33
            ->end()
639 33
        ->end();
640 33
    }
641
}
642