Completed
Push — master ( 1f2c49...ea4d71 )
by David
9s
created

DependencyInjection/Configuration.php (1 issue)

Labels
Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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
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