Completed
Push — master ( ea729d...2dd925 )
by David
03:38 queued 47s
created

src/DependencyInjection/FOSHttpCacheExtension.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 FOS\HttpCache\ProxyClient\HttpDispatcher;
15
use FOS\HttpCache\ProxyClient\ProxyClient;
16
use FOS\HttpCache\ProxyClient\Varnish;
17
use FOS\HttpCache\SymfonyCache\KernelDispatcher;
18
use FOS\HttpCache\TagHeaderFormatter\MaxHeaderValueLengthFormatter;
19
use FOS\HttpCacheBundle\DependencyInjection\Compiler\HashGeneratorPass;
20
use FOS\HttpCacheBundle\Http\ResponseMatcher\ExpressionResponseMatcher;
21
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
22
use Symfony\Component\Config\FileLocator;
23
use Symfony\Component\Console\Application;
24
use Symfony\Component\DependencyInjection\ChildDefinition;
25
use Symfony\Component\DependencyInjection\ContainerBuilder;
26
use Symfony\Component\DependencyInjection\Definition;
27
use Symfony\Component\DependencyInjection\DefinitionDecorator;
28
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
29
use Symfony\Component\DependencyInjection\Reference;
30
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
31
use Symfony\Component\HttpKernel\Kernel;
32
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
33
34
/**
35
 * {@inheritdoc}
36
 */
37
class FOSHttpCacheExtension extends Extension
38
{
39
    /**
40
     * {@inheritdoc}
41
     */
42 36
    public function getConfiguration(array $config, ContainerBuilder $container)
43
    {
44 36
        return new Configuration($container->getParameter('kernel.debug'));
45
    }
46
47
    /**
48
     * {@inheritdoc}
49
     */
50 36
    public function load(array $configs, ContainerBuilder $container)
51
    {
52 36
        $configuration = $this->getConfiguration($configs, $container);
53 36
        $config = $this->processConfiguration($configuration, $configs);
0 ignored issues
show
It seems like $configuration defined by $this->getConfiguration($configs, $container) on line 52 can be null; however, Symfony\Component\Depend...:processConfiguration() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
54
55 36
        $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
56 36
        $loader->load('matcher.xml');
57
58 36
        if ($config['debug']['enabled'] || (!empty($config['cache_control']))) {
59 7
            $debugHeader = $config['debug']['enabled'] ? $config['debug']['header'] : false;
60 7
            $container->setParameter('fos_http_cache.debug_header', $debugHeader);
61 7
            $loader->load('cache_control_listener.xml');
62
        }
63
64 36
        $this->loadCacheable($container, $config['cacheable']);
65
66 36
        if (!empty($config['cache_control'])) {
67 7
            $this->loadCacheControl($container, $config['cache_control']);
68
        }
69
70 35
        if (isset($config['proxy_client'])) {
71 26
            $this->loadProxyClient($container, $loader, $config['proxy_client']);
72
        }
73
74 34
        if (isset($config['test'])) {
75 2
            $this->loadTest($container, $loader, $config['test']);
76
        }
77
78 34
        if ($config['cache_manager']['enabled']) {
79 26
            if (array_key_exists('custom_proxy_client', $config['cache_manager'])) {
80
                // overwrite the previously set alias, if a proxy client was also configured
81 1
                $container->setAlias(
82 1
                    'fos_http_cache.default_proxy_client',
83 1
                    $config['cache_manager']['custom_proxy_client']
84
                );
85
            }
86 26
            if ('auto' === $config['cache_manager']['generate_url_type']) {
87 26
                if (array_key_exists('custom_proxy_client', $config['cache_manager'])) {
88 1
                    $generateUrlType = UrlGeneratorInterface::ABSOLUTE_URL;
89
                } else {
90 25
                    $defaultClient = $this->getDefaultProxyClient($config['proxy_client']);
91 25
                    if ('noop' !== $defaultClient
92 25
                        && array_key_exists('base_url', $config['proxy_client'][$defaultClient])) {
93
                        $generateUrlType = UrlGeneratorInterface::ABSOLUTE_PATH;
94
                    } else {
95 26
                        $generateUrlType = UrlGeneratorInterface::ABSOLUTE_URL;
96
                    }
97
                }
98
            } else {
99
                $generateUrlType = $config['cache_manager']['generate_url_type'];
100
            }
101 26
            $container->setParameter('fos_http_cache.cache_manager.generate_url_type', $generateUrlType);
102 26
            $loader->load('cache_manager.xml');
103 26
            if (class_exists(Application::class)) {
104 26
                $loader->load('cache_manager_commands.xml');
105
            }
106
        }
107
108 34
        if ($config['tags']['enabled']) {
109 26
            $this->loadCacheTagging(
110 26
                $container,
111 26
                $loader,
112 26
                $config['tags'],
113 26
                array_key_exists('proxy_client', $config)
114 25
                    ? $this->getDefaultProxyClient($config['proxy_client'])
115 26
                    : 'custom'
116
            );
117
        } else {
118 8
            $container->setParameter('fos_http_cache.compiler_pass.tag_annotations', false);
119
        }
120
121 33
        if ($config['invalidation']['enabled']) {
122 25
            $loader->load('invalidation_listener.xml');
123
124 25
            if (!empty($config['invalidation']['expression_language'])) {
125
                $container->setAlias(
126
                    'fos_http_cache.invalidation.expression_language',
127
                    $config['invalidation']['expression_language']
128
                );
129
            }
130
131 25
            if (!empty($config['invalidation']['rules'])) {
132 3
                $this->loadInvalidatorRules($container, $config['invalidation']['rules']);
133
            }
134
        }
135
136 33
        if ($config['user_context']['enabled']) {
137 6
            $this->loadUserContext($container, $loader, $config['user_context']);
138
        }
139
140 33
        if (!empty($config['flash_message']) && $config['flash_message']['enabled']) {
141 3
            unset($config['flash_message']['enabled']);
142 3
            $container->setParameter('fos_http_cache.event_listener.flash_message.options', $config['flash_message']);
143
144 3
            $loader->load('flash_message.xml');
145
        }
146 33
    }
147
148 36
    private function loadCacheable(ContainerBuilder $container, array $config)
149
    {
150 36
        $definition = $container->getDefinition('fos_http_cache.response_matcher.cacheable');
151
152
        // Change CacheableResponseMatcher to ExpressionResponseMatcher
153 36
        if ($config['response']['expression']) {
154
            $definition->setClass(ExpressionResponseMatcher::class)
155
                ->setArguments([$config['response']['expression']]);
156
        } else {
157 36
            $container->setParameter(
158 36
                'fos_http_cache.cacheable.response.additional_status',
159 36
                $config['response']['additional_status']
160
            );
161
        }
162 36
    }
163
164
    /**
165
     * @param ContainerBuilder $container
166
     * @param array            $config
167
     *
168
     * @throws InvalidConfigurationException
169
     */
170 7
    private function loadCacheControl(ContainerBuilder $container, array $config)
171
    {
172 7
        $controlDefinition = $container->getDefinition('fos_http_cache.event_listener.cache_control');
173
174 7
        foreach ($config['rules'] as $rule) {
175 7
            $ruleMatcher = $this->parseRuleMatcher($container, $rule['match']);
176
177 7
            if ('default' === $rule['headers']['overwrite']) {
178 7
                $rule['headers']['overwrite'] = $config['defaults']['overwrite'];
179
            }
180
181 7
            $controlDefinition->addMethodCall('addRule', [$ruleMatcher, $rule['headers']]);
182
        }
183 6
    }
184
185
    /**
186
     * Parse one cache control rule match configuration.
187
     *
188
     * @param ContainerBuilder $container
189
     * @param array            $match     Request and response match criteria
190
     *
191
     * @return Reference pointing to a rule matcher service
192
     */
193 7
    private function parseRuleMatcher(ContainerBuilder $container, array $match)
194
    {
195 7
        $requestMatcher = $this->parseRequestMatcher($container, $match);
196 7
        $responseMatcher = $this->parseResponseMatcher($container, $match);
197
198 7
        $signature = serialize([(string) $requestMatcher, (string) $responseMatcher]);
199 7
        $id = 'fos_http_cache.cache_control.rule_matcher.'.md5($signature);
200
201 7
        if ($container->hasDefinition($id)) {
202 1
            throw new InvalidConfigurationException('Duplicate match criteria. Would be hidden by a previous rule. match: '.json_encode($match));
203
        }
204
205
        $container
206 7
            ->setDefinition($id, $this->createChildDefinition('fos_http_cache.rule_matcher'))
207 7
            ->replaceArgument(0, $requestMatcher)
208 7
            ->replaceArgument(1, $responseMatcher)
209
        ;
210
211 7
        return new Reference($id);
212
    }
213
214
    /**
215
     * Used for cache control, tag and invalidation rules.
216
     *
217
     * @param ContainerBuilder $container
218
     * @param array            $match
219
     *
220
     * @return Reference to the request matcher
221
     */
222 9
    private function parseRequestMatcher(ContainerBuilder $container, array $match)
223
    {
224 9
        $match['ips'] = (empty($match['ips'])) ? null : $match['ips'];
225
226
        $arguments = [
227 9
            $match['path'],
228 9
            $match['host'],
229 9
            $match['methods'],
230 9
            $match['ips'],
231 9
            $match['attributes'],
232
        ];
233 9
        $serialized = serialize($arguments);
234 9
        $id = 'fos_http_cache.request_matcher.'.md5($serialized).sha1($serialized);
235
236 9
        if (!$container->hasDefinition($id)) {
237
            $container
238 9
                ->setDefinition($id, $this->createChildDefinition('fos_http_cache.request_matcher'))
239 9
                ->setArguments($arguments)
240
            ;
241
242 9
            if (!empty($match['query_string'])) {
243
                $container->getDefinition($id)->addMethodCall('setQueryString', [$match['query_string']]);
244
            }
245
        }
246
247 9
        return new Reference($id);
248
    }
249
250
    /**
251
     * Used only for cache control rules.
252
     *
253
     * @param ContainerBuilder $container
254
     * @param array            $config
255
     *
256
     * @return Reference to the correct response matcher service
257
     */
258 7
    private function parseResponseMatcher(ContainerBuilder $container, array $config)
259
    {
260 7
        if (!empty($config['additional_response_status'])) {
261 1
            $id = 'fos_http_cache.cache_control.expression.'.md5(serialize($config['additional_response_status']));
262 1
            if (!$container->hasDefinition($id)) {
263
                $container
264 1
                    ->setDefinition($id, $this->createChildDefinition('fos_http_cache.response_matcher.cache_control.cacheable_response'))
265 1
                    ->setArguments([$config['additional_response_status']])
266
                ;
267
            }
268 6
        } elseif (!empty($config['match_response'])) {
269 2
            $id = 'fos_http_cache.cache_control.match_response.'.md5($config['match_response']);
270 2
            if (!$container->hasDefinition($id)) {
271
                $container
272 2
                    ->setDefinition($id, $this->createChildDefinition('fos_http_cache.response_matcher.cache_control.expression'))
273 2
                    ->replaceArgument(0, $config['match_response'])
274
                ;
275
            }
276
        } else {
277 4
            $id = 'fos_http_cache.response_matcher.cacheable';
278
        }
279
280 7
        return new Reference($id);
281
    }
282
283 6
    private function loadUserContext(ContainerBuilder $container, XmlFileLoader $loader, array $config)
284
    {
285 6
        $configuredUserIdentifierHeaders = array_map('strtolower', $config['user_identifier_headers']);
286 6
        $completeUserIdentifierHeaders = $configuredUserIdentifierHeaders;
287 6
        if (false !== $config['session_name_prefix'] && !in_array('cookie', $completeUserIdentifierHeaders)) {
288
            $completeUserIdentifierHeaders[] = 'cookie';
289
        }
290
291 6
        $loader->load('user_context.xml');
292
293 6
        $container->getDefinition('fos_http_cache.user_context.request_matcher')
294 6
            ->replaceArgument(0, $config['match']['accept'])
295 6
            ->replaceArgument(1, $config['match']['method']);
296
297 6
        $container->setParameter('fos_http_cache.event_listener.user_context.options', [
298 6
            'user_identifier_headers' => $completeUserIdentifierHeaders,
299 6
            'user_hash_header' => $config['user_hash_header'],
300 6
            'ttl' => $config['hash_cache_ttl'],
301 6
            'add_vary_on_hash' => $config['always_vary_on_context_hash'],
302
        ]);
303
304 6
        $container->getDefinition('fos_http_cache.event_listener.user_context')
305 6
            ->replaceArgument(0, new Reference($config['match']['matcher_service']))
306
        ;
307
308
        $options = [
309 6
            'user_identifier_headers' => $configuredUserIdentifierHeaders,
310 6
            'session_name_prefix' => $config['session_name_prefix'],
311
        ];
312 6
        $container->getDefinition('fos_http_cache.user_context.anonymous_request_matcher')
313 6
            ->replaceArgument(0, $options);
314
315 6
        if ($config['logout_handler']['enabled']) {
316 5
            $container->getDefinition('fos_http_cache.user_context_invalidator')
317 5
                ->replaceArgument(1, $completeUserIdentifierHeaders)
318 5
                ->replaceArgument(2, $config['match']['accept']);
319
320 5
            $container->setAlias('security.logout.handler.session', 'fos_http_cache.user_context.session_logout_handler');
321
        } else {
322 1
            $container->removeDefinition('fos_http_cache.user_context.logout_handler');
323 1
            $container->removeDefinition('fos_http_cache.user_context.session_logout_handler');
324 1
            $container->removeDefinition('fos_http_cache.user_context_invalidator');
325
        }
326
327 6
        if ($config['role_provider']) {
328 4
            $container->getDefinition('fos_http_cache.user_context.role_provider')
329 4
                ->addTag(HashGeneratorPass::TAG_NAME)
330 4
                ->setAbstract(false);
331
        }
332
333
        // Only decorate default SessionListener for Symfony 3.4 - 4.0
334
        // For Symfony 4.1+, the UserContextListener sets the header that tells
335
        // the SessionListener to leave the cache-control header unchanged.
336 6
        if (version_compare(Kernel::VERSION, '3.4', '>=')
337 6
            && version_compare(Kernel::VERSION, '4.1', '<')
338
        ) {
339
            $container->getDefinition('fos_http_cache.user_context.session_listener')
340
                ->setArgument(1, strtolower($config['user_hash_header']))
341
                ->setArgument(2, $completeUserIdentifierHeaders);
342
        } else {
343 6
            $container->removeDefinition('fos_http_cache.user_context.session_listener');
344
        }
345 6
    }
346
347 26
    private function loadProxyClient(ContainerBuilder $container, XmlFileLoader $loader, array $config)
348
    {
349 26
        if (isset($config['varnish'])) {
350 21
            $this->loadVarnish($container, $loader, $config['varnish']);
351
        }
352 25
        if (isset($config['nginx'])) {
353 2
            $this->loadNginx($container, $loader, $config['nginx']);
354
        }
355 25
        if (isset($config['symfony'])) {
356 2
            $this->loadSymfony($container, $loader, $config['symfony']);
357
        }
358 25
        if (isset($config['noop'])) {
359 1
            $loader->load('noop.xml');
360
        }
361
362 25
        $container->setAlias(
363 25
            'fos_http_cache.default_proxy_client',
364 25
            'fos_http_cache.proxy_client.'.$this->getDefaultProxyClient($config)
365
        );
366 25
        $container->setAlias(
367 25
            ProxyClient::class,
368 25
            'fos_http_cache.default_proxy_client'
369
        );
370 25
    }
371
372
    /**
373
     * Define the http dispatcher service for the proxy client $name.
374
     *
375
     * @param ContainerBuilder $container
376
     * @param array            $config
377
     * @param string           $serviceName
378
     */
379 24
    private function createHttpDispatcherDefinition(ContainerBuilder $container, array $config, $serviceName)
380
    {
381 24
        foreach ($config['servers'] as $url) {
382 24
            $this->validateUrl($url, 'Not a valid Varnish server address: "%s"');
383
        }
384 24
        if (!empty($config['base_url'])) {
385 24
            $baseUrl = $this->prefixSchema($config['base_url']);
386 24
            $this->validateUrl($baseUrl, 'Not a valid base path: "%s"');
387
        } else {
388
            $baseUrl = null;
389
        }
390 23
        $httpClient = null;
391 23
        if ($config['http_client']) {
392 1
            $httpClient = new Reference($config['http_client']);
393
        }
394
395 23
        $definition = new Definition(HttpDispatcher::class, [
396 23
            $config['servers'],
397 23
            $baseUrl,
398 23
            $httpClient,
399
        ]);
400
401 23
        $container->setDefinition($serviceName, $definition);
402 23
    }
403
404 21
    private function loadVarnish(ContainerBuilder $container, XmlFileLoader $loader, array $config)
405
    {
406 21
        $this->createHttpDispatcherDefinition($container, $config['http'], 'fos_http_cache.proxy_client.varnish.http_dispatcher');
407
        $options = [
408 20
            'tag_mode' => $config['tag_mode'],
409 20
            'tags_header' => $config['tags_header'],
410
        ];
411
412 20
        if (!empty($config['header_length'])) {
413
            $options['header_length'] = $config['header_length'];
414
        }
415 20
        if (!empty($config['default_ban_headers'])) {
416
            $options['default_ban_headers'] = $config['default_ban_headers'];
417
        }
418 20
        $container->setParameter('fos_http_cache.proxy_client.varnish.options', $options);
419
420 20
        $loader->load('varnish.xml');
421 20
    }
422
423 2
    private function loadNginx(ContainerBuilder $container, XmlFileLoader $loader, array $config)
424
    {
425 2
        $this->createHttpDispatcherDefinition($container, $config['http'], 'fos_http_cache.proxy_client.nginx.http_dispatcher');
426 2
        $container->setParameter('fos_http_cache.proxy_client.nginx.options', [
427 2
            'purge_location' => $config['purge_location'],
428
        ]);
429 2
        $loader->load('nginx.xml');
430 2
    }
431
432 2
    private function loadSymfony(ContainerBuilder $container, XmlFileLoader $loader, array $config)
433
    {
434 2
        $serviceName = 'fos_http_cache.proxy_client.symfony.http_dispatcher';
435
436 2
        if ($config['use_kernel_dispatcher']) {
437 1
            $definition = new Definition(KernelDispatcher::class, [
438 1
                new Reference('kernel'),
439
            ]);
440 1
            $container->setDefinition($serviceName, $definition);
441
        } else {
442 1
            $this->createHttpDispatcherDefinition($container, $config['http'], $serviceName);
443
        }
444
445
        $options = [
446 2
            'tags_header' => $config['tags_header'],
447 2
            'tags_method' => $config['tags_method'],
448 2
            'purge_method' => $config['purge_method'],
449
        ];
450 2
        if (!empty($config['header_length'])) {
451
            $options['header_length'] = $config['header_length'];
452
        }
453 2
        $container->setParameter('fos_http_cache.proxy_client.symfony.options', $options);
454
455 2
        $loader->load('symfony.xml');
456 2
    }
457
458
    /**
459
     * @param ContainerBuilder $container
460
     * @param XmlFileLoader    $loader
461
     * @param array            $config    Configuration section for the tags node
462
     * @param string           $client    Name of the client used with the cache manager,
463
     *                                    "custom" when a custom client is used
464
     */
465 26
    private function loadCacheTagging(ContainerBuilder $container, XmlFileLoader $loader, array $config, $client)
466
    {
467 26
        if ('auto' === $config['enabled'] && !in_array($client, ['varnish', 'symfony'])) {
468 3
            $container->setParameter('fos_http_cache.compiler_pass.tag_annotations', false);
469
470 3
            return;
471
        }
472 23
        if (!in_array($client, ['varnish', 'symfony', 'custom', 'noop'])) {
473 1
            throw new InvalidConfigurationException(sprintf('You can not enable cache tagging with the %s client', $client));
474
        }
475
476 22
        $container->setParameter('fos_http_cache.compiler_pass.tag_annotations', true);
477 22
        $container->setParameter('fos_http_cache.tag_handler.response_header', $config['response_header']);
478 22
        $container->setParameter('fos_http_cache.tag_handler.separator', $config['separator']);
479 22
        $container->setParameter('fos_http_cache.tag_handler.strict', $config['strict']);
480
481 22
        $loader->load('cache_tagging.xml');
482 22
        if (class_exists(Application::class)) {
483 22
            $loader->load('cache_tagging_commands.xml');
484
        }
485
486 22
        if (!empty($config['expression_language'])) {
487
            $container->setAlias(
488
                'fos_http_cache.tag_handler.expression_language',
489
                $config['expression_language']
490
            );
491
        }
492
493 22
        if (!empty($config['rules'])) {
494 3
            $this->loadTagRules($container, $config['rules']);
495
        }
496
497 22
        if (null !== $config['max_header_value_length']) {
498 1
            $container->register('fos_http_cache.tag_handler.max_header_value_length_header_formatter', MaxHeaderValueLengthFormatter::class)
499 1
                ->setDecoratedService('fos_http_cache.tag_handler.header_formatter')
500 1
                ->addArgument(new Reference('fos_http_cache.tag_handler.max_header_value_length_header_formatter.inner'))
501 1
                ->addArgument((int) $config['max_header_value_length']);
502
        }
503 22
    }
504
505 2
    private function loadTest(ContainerBuilder $container, XmlFileLoader $loader, array $config)
506
    {
507 2
        $container->setParameter('fos_http_cache.test.cache_header', $config['cache_header']);
508
509 2
        if ($config['proxy_server']) {
510 2
            $this->loadProxyServer($container, $loader, $config['proxy_server']);
511
        }
512 2
    }
513
514 2
    private function loadProxyServer(ContainerBuilder $container, XmlFileLoader $loader, array $config)
515
    {
516 2
        if (isset($config['varnish'])) {
517 2
            $this->loadVarnishProxyServer($container, $loader, $config['varnish']);
518
        }
519
520 2
        if (isset($config['nginx'])) {
521
            $this->loadNginxProxyServer($container, $loader, $config['nginx']);
522
        }
523
524 2
        $container->setAlias(
525 2
            'fos_http_cache.test.default_proxy_server',
526 2
            'fos_http_cache.test.proxy_server.'.$this->getDefaultProxyClient($config)
527
        );
528 2
    }
529
530 2
    private function loadVarnishProxyServer(ContainerBuilder $container, XmlFileLoader $loader, $config)
531
    {
532 2
        $loader->load('varnish_proxy.xml');
533 2
        foreach ($config as $key => $value) {
534 2
            $container->setParameter(
535 2
                'fos_http_cache.test.proxy_server.varnish.'.$key,
536 2
                $value
537
            );
538
        }
539 2
    }
540
541
    private function loadNginxProxyServer(ContainerBuilder $container, XmlFileLoader $loader, $config)
542
    {
543
        $loader->load('nginx_proxy.xml');
544
        foreach ($config as $key => $value) {
545
            $container->setParameter(
546
                'fos_http_cache.test.proxy_server.nginx.'.$key,
547
                $value
548
            );
549
        }
550
    }
551
552 3
    private function loadTagRules(ContainerBuilder $container, array $config)
553
    {
554 3
        $tagDefinition = $container->getDefinition('fos_http_cache.event_listener.tag');
555
556 3
        foreach ($config as $rule) {
557 3
            $ruleMatcher = $this->parseRequestMatcher($container, $rule['match']);
558
559
            $tags = [
560 3
                'tags' => $rule['tags'],
561 3
                'expressions' => $rule['tag_expressions'],
562
            ];
563
564 3
            $tagDefinition->addMethodCall('addRule', [$ruleMatcher, $tags]);
565
        }
566 3
    }
567
568 3
    private function loadInvalidatorRules(ContainerBuilder $container, array $config)
569
    {
570 3
        $tagDefinition = $container->getDefinition('fos_http_cache.event_listener.invalidation');
571
572 3
        foreach ($config as $rule) {
573 3
            $ruleMatcher = $this->parseRequestMatcher($container, $rule['match']);
574 3
            $tagDefinition->addMethodCall('addRule', [$ruleMatcher, $rule['routes']]);
575
        }
576 3
    }
577
578 24
    private function validateUrl($url, $msg)
579
    {
580 24
        $prefixed = $this->prefixSchema($url);
581
582 24
        if (!$parts = parse_url($prefixed)) {
583 1
            throw new InvalidConfigurationException(sprintf($msg, $url));
584
        }
585 24
    }
586
587 24
    private function prefixSchema($url)
588
    {
589 24
        if (false === strpos($url, '://')) {
590 24
            $url = sprintf('%s://%s', 'http', $url);
591
        }
592
593 24
        return $url;
594
    }
595
596 25
    private function getDefaultProxyClient(array $config)
597
    {
598 25
        if (isset($config['default'])) {
599
            return $config['default'];
600
        }
601
602 25
        if (isset($config['varnish'])) {
603 20
            return 'varnish';
604
        }
605
606 5
        if (isset($config['nginx'])) {
607 2
            return 'nginx';
608
        }
609
610 3
        if (isset($config['symfony'])) {
611 2
            return 'symfony';
612
        }
613
614 1
        if (isset($config['noop'])) {
615 1
            return 'noop';
616
        }
617
618
        throw new InvalidConfigurationException('No proxy client configured');
619
    }
620
621
    /**
622
     * Build the child definition with fallback for Symfony versions < 3.3.
623
     *
624
     * @param string $id Id of the service to extend
625
     *
626
     * @return ChildDefinition|DefinitionDecorator
627
     */
628 9
    private function createChildDefinition($id)
629
    {
630 9
        if (class_exists(ChildDefinition::class)) {
631 9
            return new ChildDefinition($id);
632
        }
633
634
        return new DefinitionDecorator($id);
635
    }
636
}
637