Completed
Push — master ( 6b75eb...2904a3 )
by David
16:55
created

FOSHttpCacheExtension   D

Complexity

Total Complexity 94

Size/Duplication

Total Lines 585
Duplicated Lines 2.05 %

Coupling/Cohesion

Components 1
Dependencies 10

Test Coverage

Coverage 90.7%

Importance

Changes 0
Metric Value
wmc 94
c 0
b 0
f 0
lcom 1
cbo 10
dl 12
loc 585
ccs 273
cts 301
cp 0.907
rs 4.8717

24 Methods

Rating   Name   Duplication   Size   Complexity  
C loadCacheTagging() 0 30 7
A loadTagRules() 0 15 2
B loadProxyClient() 0 20 5
B createHttpDispatcherDefinition() 0 24 4
A loadVarnish() 0 16 3
A loadNginx() 0 8 1
A getConfiguration() 0 4 1
F load() 0 97 22
A loadCacheable() 0 15 2
A loadCacheControl() 0 14 3
A parseRuleMatcher() 0 20 2
B parseRequestMatcher() 0 27 4
B parseResponseMatcher() 12 24 5
B loadUserContext() 0 63 7
B loadSymfony() 0 25 3
A loadTest() 0 8 2
A loadProxyServer() 0 15 3
A loadVarnishProxyServer() 0 10 2
A loadNginxProxyServer() 0 10 2
A loadInvalidatorRules() 0 9 2
A validateUrl() 0 8 2
A prefixSchema() 0 8 2
B getDefaultProxyClient() 0 24 6
A createChildDefinition() 0 8 2

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like FOSHttpCacheExtension often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use FOSHttpCacheExtension, and based on these observations, apply Extract Interface, too.

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

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
617
    }
618
}
619