Completed
Push — master ( 9de1be...100987 )
by David
8s
created

Configuration::addDebugSection()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 20
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 18
CRAP Score 1

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 20
ccs 18
cts 18
cp 1
rs 9.4285
cc 1
eloc 18
nc 1
nop 1
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\TreeBuilder;
17
use Symfony\Component\Config\Definition\ConfigurationInterface;
18
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
19
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
20
21
/**
22
 * This class contains the configuration information for the bundle.
23
 *
24
 * This information is solely responsible for how the different configuration
25
 * sections are normalized, and merged.
26
 *
27
 * @author David de Boer <[email protected]>
28
 * @author David Buchmann <[email protected]>
29
 */
30
class Configuration implements ConfigurationInterface
31
{
32
    /**
33
     * @var bool
34
     */
35
    private $debug;
36
37
    /**
38
     * @param bool $debug Whether to use the debug mode
39
     */
40 32
    public function __construct($debug)
41
    {
42 32
        $this->debug = $debug;
43 32
    }
44
45
    /**
46
     * {@inheritdoc}
47
     */
48 32
    public function getConfigTreeBuilder()
49
    {
50 32
        $treeBuilder = new TreeBuilder();
51 32
        $rootNode = $treeBuilder->root('fos_http_cache');
52
53
        $rootNode
54 32
            ->validate()
55
                ->ifTrue(function ($v) {
56 30
                    return $v['cache_manager']['enabled']
57 30
                        && !isset($v['proxy_client'])
58 30
                        && !isset($v['cache_manager']['custom_proxy_client'])
59 30
                    ;
60 32
                })
61
                ->then(function ($v) {
62 7
                    if ('auto' === $v['cache_manager']['enabled']) {
63 6
                        $v['cache_manager']['enabled'] = false;
64
65 6
                        return $v;
66
                    }
67 1
                    throw new InvalidConfigurationException('You need to configure a proxy_client or specify a custom_proxy_client to use the cache_manager.');
68 32
                })
69 32
            ->end()
70 32
            ->validate()
71
                ->ifTrue(function ($v) {
72 29
                    return $v['tags']['enabled'] && !$v['cache_manager']['enabled'];
73 32
                })
74
                ->then(function ($v) {
75 8
                    if ('auto' === $v['tags']['enabled']) {
76 7
                        $v['tags']['enabled'] = false;
77
78 7
                        return $v;
79
                    }
80 1
                    throw new InvalidConfigurationException('You need to configure a proxy_client to get the cache_manager needed for tag handling.');
81 32
                })
82 32
            ->end()
83 32
            ->validate()
84
                ->ifTrue(function ($v) {
85 28
                    return $v['invalidation']['enabled'] && !$v['cache_manager']['enabled'];
86 32
                })
87
                ->then(function ($v) {
88 7
                    if ('auto' === $v['invalidation']['enabled']) {
89 6
                        $v['invalidation']['enabled'] = false;
90
91 6
                        return $v;
92
                    }
93 1
                    throw new InvalidConfigurationException('You need to configure a proxy_client to get the cache_manager needed for invalidation handling.');
94 32
                })
95 32
            ->end()
96 32
            ->validate()
97 View Code Duplication
                ->ifTrue(function ($v) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
98 27
                    return isset($v['test'])
99 27
                        && $v['test']['client']['varnish']['enabled']
100 27
                        && !isset($v['proxy_client']['varnish']);
101 32
                })
102 View Code Duplication
                ->then(function ($v) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
103
                    if ('auto' === $v['test']['client']['varnish']['enabled']) {
104
                        $v['test']['client']['varnish']['enabled'] = false;
105
106
                        return $v;
107
                    }
108
                    throw new InvalidConfigurationException('You need to configure the Varnish proxy_client to use the Varnish test client');
109 32
                })
110 32
            ->end()
111 32
            ->validate()
112 View Code Duplication
                ->ifTrue(function ($v) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
113 27
                    if (isset($v['test'])) {
114 1
                        return $v['test']['client']['nginx']['enabled'] && !isset($v['proxy_client']['nginx']);
115
                    }
116 32
                })
117 View Code Duplication
                ->then(function ($v) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
118 1
                    if ('auto' === $v['test']['client']['nginx']['enabled']) {
119 1
                        $v['test']['client']['nginx']['enabled'] = false;
120
121 1
                        return $v;
122
                    }
123
                    throw new InvalidConfigurationException('You need to configure the Nginx proxy_client to use the Nginx test client');
124 32
                })
125 32
            ->end()
126 32
            ->validate()
127 32
                ->ifTrue(
128
                    function ($v) {
129 27
                        return $v['user_context']['logout_handler']['enabled']
130 27
                            && !isset($v['proxy_client']);
131
                    }
132 32
                )
133
                ->then(function ($v) {
134 7
                    if ('auto' === $v['user_context']['logout_handler']['enabled']) {
135 7
                        $v['user_context']['logout_handler']['enabled'] = false;
136
137 7
                        return $v;
138
                    }
139
                    throw new InvalidConfigurationException('You need to configure a proxy_client for the logout_handler.');
140 32
                })
141
        ;
142
143 32
        $this->addCacheControlSection($rootNode);
144 32
        $this->addProxyClientSection($rootNode);
145 32
        $this->addCacheManagerSection($rootNode);
146 32
        $this->addTagSection($rootNode);
147 32
        $this->addInvalidationSection($rootNode);
148 32
        $this->addUserContextListenerSection($rootNode);
149 32
        $this->addFlashMessageSection($rootNode);
150 32
        $this->addTestSection($rootNode);
151 32
        $this->addDebugSection($rootNode);
152
153 32
        return $treeBuilder;
154
    }
155
156
    /**
157
     * Cache header control main section.
158
     *
159
     * @param ArrayNodeDefinition $rootNode
160
     */
161 32
    private function addCacheControlSection(ArrayNodeDefinition $rootNode)
162
    {
163
        $rules = $rootNode
164 32
            ->children()
165 32
                ->arrayNode('cache_control')
166 32
                    ->fixXmlConfig('rule')
167 32
                    ->children()
168 32
                        ->arrayNode('defaults')
169 32
                            ->addDefaultsIfNotSet()
170 32
                            ->children()
171 32
                                ->booleanNode('overwrite')
172 32
                                    ->info('Whether to overwrite existing cache headers')
173 32
                                    ->defaultFalse()
174 32
                                ->end()
175 32
                            ->end()
176 32
                        ->end()
177 32
                        ->arrayNode('rules')
178 32
                            ->prototype('array')
179 32
                                ->children();
180
181 32
        $this->addMatch($rules);
182
        $rules
183 32
            ->arrayNode('headers')
184 32
                ->isRequired()
185
                // todo validate there is some header defined
186 32
                ->children()
187 32
                    ->enumNode('overwrite')
188 32
                        ->info('Whether to overwrite cache headers for this rule, defaults to the cache_control.defaults.overwrite setting')
189 32
                        ->values(array('default', true, false))
190 32
                        ->defaultValue('default')
191 32
                    ->end()
192 32
                    ->arrayNode('cache_control')
193 32
                        ->info('Add the specified cache control directives.')
194 32
                        ->children()
195 32
                            ->scalarNode('max_age')->end()
196 32
                            ->scalarNode('s_maxage')->end()
197 32
                            ->booleanNode('private')->end()
198 32
                            ->booleanNode('public')->end()
199 32
                            ->booleanNode('must_revalidate')->end()
200 32
                            ->booleanNode('proxy_revalidate')->end()
201 32
                            ->booleanNode('no_transform')->end()
202 32
                            ->booleanNode('no_cache')->end()
203 32
                            ->scalarNode('stale_if_error')->end()
204 32
                            ->scalarNode('stale_while_revalidate')->end()
205 32
                        ->end()
206 32
                    ->end()
207 32
                    ->scalarNode('etag')
208 32
                        ->defaultValue(false)
209 32
                        ->info('Set a simple ETag which is just the md5 hash of the response body')
210 32
                    ->end()
211 32
                    ->scalarNode('last_modified')
212 32
                        ->validate()
213
                            ->ifTrue(function ($v) {
214 2
                                if (is_string($v)) {
215 2
                                    new \DateTime($v);
216 1
                                }
217
218 1
                                return false;
219 32
                            })
220 32
                            ->thenInvalid('') // this will never happen as new DateTime will throw an exception if $v is no date
221 32
                        ->end()
222 32
                        ->info('Set a default last modified timestamp if none is set yet. Value must be parseable by DateTime')
223 32
                    ->end()
224 32
                    ->scalarNode('reverse_proxy_ttl')
225 32
                        ->defaultNull()
226 32
                        ->info('Specify an X-Reverse-Proxy-TTL header with a time in seconds for a caching proxy under your control.')
227 32
                    ->end()
228 32
                    ->arrayNode('vary')
229
                        ->beforeNormalization()->ifString()->then(function ($v) {
230 2
                            return preg_split('/\s*,\s*/', $v);
231 32
                        })->end()
232 32
                        ->prototype('scalar')->end()
233 32
                        ->info('Define a list of additional headers on which the response varies.')
234 32
                    ->end()
235 32
                ->end()
236 32
            ->end()
237
        ;
238 32
    }
239
240
    /**
241
     * Shared configuration between cache control, tags and invalidation.
242
     *
243
     * @param NodeBuilder $rules
244
     */
245 32
    private function addMatch(NodeBuilder $rules)
246
    {
247
        $rules
248 32
            ->arrayNode('match')
249 32
                ->cannotBeOverwritten()
250 32
                ->isRequired()
251 32
                ->fixXmlConfig('method')
252 32
                ->fixXmlConfig('ip')
253 32
                ->fixXmlConfig('attribute')
254 32
                ->validate()
255
                    ->ifTrue(function ($v) {
256 9
                        return !empty($v['additional_cacheable_status']) && !empty($v['match_response']);
257 32
                    })
258 32
                    ->thenInvalid('You may not set both additional_cacheable_status and match_response.')
259 32
                ->end()
260 32
                ->validate()
261
                    ->ifTrue(function ($v) {
262 8
                        return !empty($v['match_response']) && !class_exists('Symfony\Component\ExpressionLanguage\ExpressionLanguage');
263 32
                    })
264 32
                    ->thenInvalid('Configured a match_response but ExpressionLanguage is not available')
265 32
                ->end()
266 32
                ->children()
267 32
                    ->scalarNode('path')
268 32
                        ->defaultNull()
269 32
                        ->info('Request path.')
270 32
                    ->end()
271 32
                    ->scalarNode('host')
272 32
                        ->defaultNull()
273 32
                        ->info('Request host name.')
274 32
                    ->end()
275 32
                    ->arrayNode('methods')
276
                        ->beforeNormalization()->ifString()->then(function ($v) {
277 3
                            return preg_split('/\s*,\s*/', $v);
278 32
                        })->end()
279 32
                        ->useAttributeAsKey('name')
280 32
                        ->prototype('scalar')->end()
281 32
                        ->info('Request HTTP methods.')
282 32
                    ->end()
283 32
                    ->arrayNode('ips')
284
                        ->beforeNormalization()->ifString()->then(function ($v) {
285 3
                            return preg_split('/\s*,\s*/', $v);
286 32
                        })->end()
287 32
                        ->useAttributeAsKey('name')
288 32
                        ->prototype('scalar')->end()
289 32
                        ->info('List of client IPs.')
290 32
                    ->end()
291 32
                    ->arrayNode('attributes')
292 32
                        ->useAttributeAsKey('name')
293 32
                        ->prototype('scalar')->end()
294 32
                        ->info('Regular expressions on request attributes.')
295 32
                    ->end()
296 32
                    ->arrayNode('additional_cacheable_status')
297 32
                        ->prototype('scalar')->end()
298 32
                        ->info('Additional response HTTP status codes that will match.')
299 32
                    ->end()
300 32
                    ->scalarNode('match_response')
301 32
                        ->defaultNull()
302 32
                        ->info('Expression to decide whether response should be matched. Replaces HTTP code check and additional_cacheable_status.')
303 32
                    ->end()
304 32
                ->end()
305 32
            ->end()
306
        ;
307 32
    }
308
309 32
    private function addProxyClientSection(ArrayNodeDefinition $rootNode)
310
    {
311
        $rootNode
312 32
            ->children()
313 32
                ->arrayNode('proxy_client')
314 32
                    ->children()
315 32
                        ->enumNode('default')
316 32
                            ->values(array('varnish', 'nginx', 'symfony'))
317 32
                            ->info('If you configure more than one proxy client, specify which client is the default.')
318 32
                        ->end()
319 32
                        ->arrayNode('varnish')
320 32
                            ->fixXmlConfig('server')
321 32
                            ->children()
322 32
                                ->arrayNode('servers')
323
                                    ->beforeNormalization()->ifString()->then(function ($v) {
324 3
                                        return preg_split('/\s*,\s*/', $v);
325 32
                                    })->end()
326 32
                                    ->useAttributeAsKey('name')
327 32
                                    ->isRequired()
328 32
                                    ->requiresAtLeastOneElement()
329 32
                                    ->prototype('scalar')->end()
330 32
                                    ->info('Addresses of the hosts Varnish is running on. May be hostname or ip, and with :port if not the default port 80.')
331 32
                                ->end()
332 32
                                ->scalarNode('base_url')
333 32
                                    ->defaultNull()
334 32
                                    ->info('Default host name and optional path for path based invalidation.')
335 32
                                ->end()
336 32
                                ->scalarNode('guzzle_client')
337 32
                                    ->defaultNull()
338 32
                                    ->info('Guzzle service to use for customizing the requests.')
339 32
                                ->end()
340 32
                            ->end()
341 32
                        ->end()
342
343 32
                        ->arrayNode('nginx')
344 32
                            ->fixXmlConfig('server')
345 32
                            ->children()
346 32
                                ->arrayNode('servers')
347
                                    ->beforeNormalization()->ifString()->then(function ($v) {
348 2
                                        return preg_split('/\s*,\s*/', $v);
349 32
                                    })->end()
350 32
                                    ->useAttributeAsKey('name')
351 32
                                    ->isRequired()
352 32
                                    ->requiresAtLeastOneElement()
353 32
                                    ->prototype('scalar')->end()
354 32
                                    ->info('Addresses of the hosts Nginx is running on. May be hostname or ip, and with :port if not the default port 80.')
355 32
                                ->end()
356 32
                                ->scalarNode('base_url')
357 32
                                    ->defaultNull()
358 32
                                    ->info('Default host name and optional path for path based invalidation.')
359 32
                                ->end()
360 32
                                ->scalarNode('guzzle_client')
361 32
                                    ->defaultNull()
362 32
                                    ->info('Guzzle service to use for customizing the requests.')
363 32
                                ->end()
364 32
                                ->scalarNode('purge_location')
365 32
                                    ->defaultValue('')
366 32
                                    ->info('Path to trigger the purge on Nginx for different location purge.')
367 32
                                ->end()
368 32
                            ->end()
369 32
                        ->end()
370
371 32
                        ->arrayNode('symfony')
372 32
                            ->fixXmlConfig('server')
373 32
                            ->children()
374 32
                                ->arrayNode('servers')
375
                                    ->beforeNormalization()->ifString()->then(function ($v) {
376 1
                                        return preg_split('/\s*,\s*/', $v);
377 32
                                    })->end()
378 32
                                    ->useAttributeAsKey('name')
379 32
                                    ->isRequired()
380 32
                                    ->requiresAtLeastOneElement()
381 32
                                    ->prototype('scalar')->end()
382 32
                                    ->info('Addresses of the hosts Symfony HttpCache is running on. May be hostname or ip, and with :port if not the default port 80.')
383 32
                                ->end()
384 32
                                ->scalarNode('base_url')
385 32
                                    ->defaultNull()
386 32
                                    ->info('Default host name and optional path for path based invalidation.')
387 32
                                ->end()
388 32
                                ->scalarNode('guzzle_client')
389 32
                                    ->defaultNull()
390 32
                                    ->info('Guzzle service to use for customizing the requests.')
391 32
                                ->end()
392 32
                            ->end()
393 32
                        ->end()
394
395 32
                    ->end()
396 32
                ->end()
397 32
            ->end();
398 32
    }
399
400 32
    private function addTestSection(ArrayNodeDefinition $rootNode)
401
    {
402
        $rootNode
403 32
            ->children()
404 32
                ->arrayNode('test')
405 32
                    ->children()
406 32
                        ->scalarNode('cache_header')
407 32
                            ->defaultValue('X-Cache')
408 32
                            ->info('HTTP cache hit/miss header')
409 32
                        ->end()
410 32
                        ->arrayNode('proxy_server')
411 32
                            ->info('Configure how caching proxy will be run in your tests')
412 32
                            ->children()
413 32
                                ->enumNode('default')
414 32
                                    ->values(array('varnish', 'nginx'))
415 32
                                    ->info('If you configure more than one proxy server, specify which client is the default.')
416 32
                                ->end()
417 32
                                ->arrayNode('varnish')
418 32
                                    ->children()
419 32
                                        ->scalarNode('config_file')->isRequired()->end()
420 32
                                        ->scalarNode('binary')->defaultValue('varnishd')->end()
421 32
                                        ->integerNode('port')->defaultValue(6181)->end()
422 32
                                        ->scalarNode('ip')->defaultValue('127.0.0.1')->end()
423 32
                                    ->end()
424 32
                                ->end()
425 32
                                ->arrayNode('nginx')
426 32
                                    ->children()
427 32
                                        ->scalarNode('config_file')->isRequired()->end()
428 32
                                        ->scalarNode('binary')->defaultValue('nginx')->end()
429 32
                                        ->integerNode('port')->defaultValue(8080)->end()
430 32
                                        ->scalarNode('ip')->defaultValue('127.0.0.1')->end()
431 32
                                    ->end()
432 32
                                ->end()
433 32
                            ->end()
434 32
                        ->end()
435 32
                        ->arrayNode('client')
436 32
                            ->addDefaultsIfNotSet()
437 32
                            ->children()
438 32
                                ->enumNode('default')
439 32
                                    ->values(array('varnish', 'nginx'))
440 32
                                    ->info('If you configure more than one proxy client, specify which client is the default.')
441 32
                                ->end()
442 32
                                ->arrayNode('varnish')
443 32
                                    ->addDefaultsIfNotSet()
444 32
                                    ->canBeEnabled()
445 32
                                    ->children()
446 32
                                        ->enumNode('enabled')
447 32
                                            ->values(array(true, false, 'auto'))
448 32
                                            ->defaultValue('auto')
449 32
                                            ->info('Whether to enable the Varnish test client.')
450 32
                                        ->end()
451 32
                                    ->end()
452 32
                                ->end()
453 32
                                ->arrayNode('nginx')
454 32
                                    ->addDefaultsIfNotSet()
455 32
                                    ->canBeEnabled()
456 32
                                    ->children()
457 32
                                        ->enumNode('enabled')
458 32
                                            ->values(array(true, false, 'auto'))
459 32
                                            ->defaultValue('auto')
460 32
                                            ->info('Whether to enable the Nginx test client.')
461 32
                                        ->end()
462 32
                                    ->end()
463 32
                                ->end()
464 32
                            ->end()
465 32
                        ->end()
466 32
                    ->end()
467 32
                ->end()
468 32
            ->end();
469 32
    }
470
471
    /**
472
     * Cache manager main section.
473
     *
474
     * @param ArrayNodeDefinition $rootNode
475
     */
476 32
    private function addCacheManagerSection(ArrayNodeDefinition $rootNode)
477
    {
478
        $rootNode
479 32
            ->children()
480 32
                ->arrayNode('cache_manager')
481 32
                    ->addDefaultsIfNotSet()
482 32
                    ->beforeNormalization()
483 32
                        ->ifArray()
484
                        ->then(function ($v) {
485 5
                            $v['enabled'] = isset($v['enabled']) ? $v['enabled'] : true;
486
487 5
                            return $v;
488 32
                        })
489 32
                    ->end()
490 32
                    ->info('Configure the cache manager. Needs a proxy_client to be configured.')
491 32
                    ->children()
492 32
                        ->enumNode('enabled')
493 32
                            ->values(array(true, false, 'auto'))
494 32
                            ->defaultValue('auto')
495 32
                            ->info('Allows to disable the invalidation manager. Enabled by default if you configure a proxy client.')
496 32
                        ->end()
497 32
                        ->scalarNode('custom_proxy_client')
498 32
                            ->info('Service name of a custom proxy client to use. If you configure a proxy client, that client will be used by default.')
499 32
                        ->end()
500 32
                        ->enumNode('generate_url_type')
501 32
                            ->values(array(
502 32
                                'auto',
503 32
                                UrlGeneratorInterface::ABSOLUTE_PATH,
504 32
                                UrlGeneratorInterface::ABSOLUTE_URL,
505 32
                                UrlGeneratorInterface::NETWORK_PATH,
506 32
                                UrlGeneratorInterface::RELATIVE_PATH,
507 32
                            ))
508 32
                            ->defaultValue('auto')
509 32
                            ->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.')
510 32
                        ->end()
511 32
                    ->end()
512
        ;
513 32
    }
514
515 32
    private function addTagSection(ArrayNodeDefinition $rootNode)
516
    {
517
        $rules = $rootNode
518 32
            ->children()
519 32
                ->arrayNode('tags')
520 32
                    ->addDefaultsIfNotSet()
521 32
                    ->fixXmlConfig('rule')
522 32
                    ->children()
523 32
                        ->enumNode('enabled')
524 32
                            ->values(array(true, false, 'auto'))
525 32
                            ->defaultValue('auto')
526 32
                            ->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.')
527 32
                        ->end()
528 32
                        ->scalarNode('expression_language')
529 32
                            ->defaultNull()
530 32
                            ->info('Service name of a custom ExpressionLanugage to use.')
531 32
                        ->end()
532 32
                        ->scalarNode('header')
533 32
                            ->defaultValue('X-Cache-Tags')
534 32
                            ->info('HTTP header that contains cache tags')
535 32
                        ->end()
536 32
                        ->arrayNode('rules')
537 32
                            ->prototype('array')
538 32
                                ->fixXmlConfig('tag')
539 32
                                ->fixXmlConfig('tag_expression')
540 32
                                ->validate()
541 32
                                    ->ifTrue(function ($v) {
542 3
                                        return !empty($v['tag_expressions']) && !class_exists('Symfony\Component\ExpressionLanguage\ExpressionLanguage');
543 32
                                    })
544 32
                                    ->thenInvalid('Configured a tag_expression but ExpressionLanugage is not available')
545 32
                                ->end()
546 32
                                ->children();
547
548 32
        $this->addMatch($rules);
549
550
        $rules
551 32
            ->arrayNode('tags')
552 32
                ->prototype('scalar')
553 32
                ->info('Tags to add to the response on safe requests, to invalidate on unsafe requests')
554 32
            ->end()->end()
555 32
            ->arrayNode('tag_expressions')
556 32
                ->prototype('scalar')
557 32
                ->info('Tags to add to the response on safe requests, to invalidate on unsafe requests')
558 32
            ->end()
559
        ;
560 32
    }
561
562 32
    private function addInvalidationSection(ArrayNodeDefinition $rootNode)
563
    {
564
        $rules = $rootNode
565 32
            ->children()
566 32
                ->arrayNode('invalidation')
567 32
                    ->fixXmlConfig('rule')
568 32
                    ->addDefaultsIfNotSet()
569 32
                    ->children()
570 32
                        ->enumNode('enabled')
571 32
                            ->values(array(true, false, 'auto'))
572 32
                            ->defaultValue('auto')
573 32
                            ->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.')
574 32
                        ->end()
575 32
                        ->scalarNode('expression_language')
576 32
                            ->defaultNull()
577 32
                            ->info('Service name of a custom ExpressionLanugage to use.')
578 32
                        ->end()
579 32
                        ->arrayNode('rules')
580 32
                            ->info('Set what requests should invalidate which target routes.')
581 32
                            ->prototype('array')
582 32
                                ->fixXmlConfig('route')
583 32
                                ->children();
584
585 32
        $this->addMatch($rules);
586
        $rules
587 32
            ->arrayNode('routes')
588 32
                ->isRequired()
589 32
                ->requiresAtLeastOneElement()
590 32
                ->useAttributeAsKey('name')
591 32
                ->info('Target routes to invalidate when request is matched')
592 32
                ->prototype('array')
593 32
                    ->children()
594 32
                        ->booleanNode('ignore_extra_params')->defaultTrue()->end()
595 32
                    ->end()
596 32
                ->end()
597 32
            ->end();
598 32
    }
599
600
    /**
601
     * User context main section.
602
     *
603
     * @param ArrayNodeDefinition $rootNode
604
     */
605 32
    private function addUserContextListenerSection(ArrayNodeDefinition $rootNode)
606
    {
607
        $rootNode
608 32
            ->children()
609 32
                ->arrayNode('user_context')
610 32
                    ->info('Listener that returns the request for the user context hash as early as possible.')
611 32
                    ->addDefaultsIfNotSet()
612 32
                    ->canBeEnabled()
613 32
                    ->fixXmlConfig('user_identifier_header')
614 32
                    ->children()
615 32
                        ->arrayNode('match')
616 32
                            ->addDefaultsIfNotSet()
617 32
                            ->children()
618 32
                                ->scalarNode('matcher_service')
619 32
                                    ->defaultValue('fos_http_cache.user_context.request_matcher')
620 32
                                    ->info('Service id of a request matcher that tells whether the request is a context hash request.')
621 32
                                ->end()
622 32
                                ->scalarNode('accept')
623 32
                                    ->defaultValue('application/vnd.fos.user-context-hash')
624 32
                                    ->info('Specify the accept HTTP header used for context hash requests.')
625 32
                                ->end()
626 32
                                ->scalarNode('method')
627 32
                                    ->defaultNull()
628 32
                                    ->info('Specify the HTTP method used for context hash requests.')
629 32
                                ->end()
630 32
                            ->end()
631 32
                        ->end()
632 32
                        ->scalarNode('hash_cache_ttl')
633 32
                            ->defaultValue(0)
634 32
                            ->info('Cache the response for the hash for the specified number of seconds. Setting this to 0 will not cache those responses at all.')
635 32
                        ->end()
636 32
                        ->booleanNode('always_vary_on_context_hash')
637 32
                            ->defaultTrue()
638 32
                            ->info('Whether to always add the user context hash header name in the response Vary header.')
639 32
                        ->end()
640 32
                        ->arrayNode('user_identifier_headers')
641 32
                            ->prototype('scalar')->end()
642 32
                            ->defaultValue(array('Cookie', 'Authorization'))
643 32
                            ->info('List of headers that contains the unique identifier for the user in the hash request.')
644 32
                        ->end()
645 32
                        ->scalarNode('user_hash_header')
646 32
                            ->defaultValue('X-User-Context-Hash')
647 32
                            ->info('Name of the header that contains the hash information for the context.')
648 32
                        ->end()
649 32
                        ->booleanNode('role_provider')
650 32
                            ->defaultFalse()
651 32
                            ->info('Whether to enable a provider that automatically adds all roles of the current user to the context.')
652 32
                        ->end()
653 32
                        ->arrayNode('logout_handler')
654 32
                            ->addDefaultsIfNotSet()
655 32
                            ->canBeEnabled()
656 32
                            ->children()
657 32
                                ->enumNode('enabled')
658 32
                                    ->values(array(true, false, 'auto'))
659 32
                                    ->defaultValue('auto')
660 32
                                    ->info('Whether to enable the user context logout handler.')
661 32
                                ->end()
662 32
                            ->end()
663 32
                        ->end()
664 32
                    ->end()
665 32
                ->end()
666 32
            ->end()
667
        ;
668 32
    }
669
670 32
    private function addFlashMessageSection(ArrayNodeDefinition $rootNode)
671
    {
672
        $rootNode
673 32
            ->children()
674 32
                ->arrayNode('flash_message')
675 32
                    ->canBeUnset()
676 32
                    ->canBeEnabled()
677 32
                    ->info('Activate the flash message listener that puts flash messages into a cookie.')
678 32
                    ->children()
679 32
                        ->scalarNode('name')
680 32
                            ->defaultValue('flashes')
681 32
                            ->info('Name of the cookie to set for flashes.')
682 32
                        ->end()
683 32
                        ->scalarNode('path')
684 32
                            ->defaultValue('/')
685 32
                            ->info('Cookie path validity.')
686 32
                        ->end()
687 32
                        ->scalarNode('host')
688 32
                            ->defaultNull()
689 32
                            ->info('Cookie host name validity.')
690 32
                        ->end()
691 32
                        ->scalarNode('secure')
692 32
                            ->defaultFalse()
693 32
                            ->info('Whether the cookie should only be transmitted over a secure HTTPS connection from the client.')
694 32
                        ->end()
695 32
                    ->end()
696 32
                ->end()
697 32
            ->end();
698 32
    }
699
700 32
    private function addDebugSection(ArrayNodeDefinition $rootNode)
701
    {
702
        $rootNode
703 32
            ->children()
704 32
                ->arrayNode('debug')
705 32
                ->addDefaultsIfNotSet()
706 32
                ->canBeEnabled()
707 32
                ->children()
708 32
                    ->booleanNode('enabled')
709 32
                        ->defaultValue($this->debug)
710 32
                        ->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.')
711 32
                    ->end()
712 32
                    ->scalarNode('header')
713 32
                        ->defaultValue('X-Cache-Debug')
714 32
                        ->info('The header to send if debug is true.')
715 32
                    ->end()
716 32
                ->end()
717 32
            ->end()
718 32
        ->end();
719 32
    }
720
}
721