Completed
Pull Request — master (#72)
by Márk
07:07
created

HttplugExtension::configurePluginByName()   C

Complexity

Conditions 13
Paths 14

Size

Total Lines 49
Code Lines 39

Duplication

Lines 20
Ratio 40.82 %

Code Coverage

Tests 0
CRAP Score 182

Importance

Changes 2
Bugs 0 Features 1
Metric Value
c 2
b 0
f 1
dl 20
loc 49
ccs 0
cts 0
cp 0
rs 5.1401
cc 13
eloc 39
nc 14
nop 3
crap 182

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Http\HttplugBundle\DependencyInjection;
4
5
use Http\Client\Common\Plugin\AuthenticationPlugin;
6
use Http\Client\Common\Plugin\CachePlugin;
7
use Http\Client\Common\Plugin\LoggerPlugin;
8
use Http\Client\Common\Plugin\StopwatchPlugin;
9
use Http\Client\Common\PluginClient;
10
use Http\HttplugBundle\ClientFactory\DummyClient;
11
use Http\Message\Authentication\BasicAuth;
12
use Http\Message\Authentication\Bearer;
13
use Http\Message\Authentication\Wsse;
14
use Symfony\Component\Config\FileLocator;
15
use Symfony\Component\DependencyInjection\ContainerBuilder;
16
use Symfony\Component\DependencyInjection\Definition;
17
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
18
use Symfony\Component\DependencyInjection\Reference;
19
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
20
21
/**
22
 * @author David Buchmann <[email protected]>
23
 * @author Tobias Nyholm <[email protected]>
24
 */
25
class HttplugExtension extends Extension
26
{
27 3
    /**
28
     * {@inheritdoc}
29 3
     */
30 3
    public function load(array $configs, ContainerBuilder $container)
31
    {
32 3
        $configuration = $this->getConfiguration($configs, $container);
33
        $config = $this->processConfiguration($configuration, $configs);
0 ignored issues
show
Documentation introduced by
$configuration is of type object|null, but the function expects a object<Symfony\Component...ConfigurationInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
34 3
35 3
        $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
36
37 3
        $loader->load('services.xml');
38 3
        $loader->load('plugins.xml');
39
40
        $enabled = is_bool($config['toolbar']['enabled']) ? $config['toolbar']['enabled'] : $container->hasParameter('kernel.debug') && $container->getParameter('kernel.debug');
41
        if ($enabled) {
42
            $loader->load('data-collector.xml');
43
            $config['_inject_collector_plugin'] = true;
44
45
            if (!empty($config['toolbar']['formatter'])) {
46
                $container->getDefinition('httplug.collector.message_journal')
47
                    ->replaceArgument(0, new Reference($config['toolbar']['formatter']));
48 3
            }
49 3
        }
50 1
51 1
        foreach ($config['classes'] as $service => $class) {
52 3
            if (!empty($class)) {
53
                $container->register(sprintf('httplug.%s.default', $service), $class);
54 3
            }
55 3
        }
56 3
57
        foreach ($config['main_alias'] as $type => $id) {
58 3
            $container->setAlias(sprintf('httplug.%s', $type), $id);
59 3
        }
60 3
61
        $this->configurePlugins($container, $config['plugins']);
62
        $this->configureClients($container, $config);
63
    }
64
65
    /**
66
     * Configure client services.
67
     *
68 3
     * @param ContainerBuilder $container
69
     * @param array            $config
70 3
     */
71 3
    private function configureClients(ContainerBuilder $container, array $config)
72
    {
73
        $first = isset($config['clients']['default']) ? 'default' : null;
74
        foreach ($config['clients'] as $name => $arguments) {
75
            if ($first === null) {
76
                $first = $name;
77
            }
78
79
            if (isset($config['_inject_collector_plugin'])) {
80
                array_unshift($arguments['plugins'], 'httplug.collector.history_plugin');
81
            }
82
83
            $def = $container->register('httplug.client.'.$name, DummyClient::class);
84
85
            if (empty($arguments['plugins'])) {
86
                $def->setFactory([new Reference($arguments['factory']), 'createClient'])
87
                    ->addArgument($arguments['config']);
88
            } else {
89
                $def->setFactory('Http\HttplugBundle\ClientFactory\PluginClientFactory::createPluginClient')
90
                    ->addArgument(array_map(function ($id) {
91
                        return new Reference($id);
92
                    }, $arguments['plugins']))
93 3
                    ->addArgument(new Reference($arguments['factory']))
94
                    ->addArgument($arguments['config']);
95
            }
96 3
        }
97
98
        // If we have clients configured
99
        if ($first !== null) {
100
            if ($first !== 'default') {
101 3
                // Alias the first client to httplug.client.default
102
                $container->setAlias('httplug.client.default', 'httplug.client.'.$first);
103
            }
104
        } elseif (isset($config['_inject_collector_plugin'])) {
105
            // No client was configured. Make sure to inject history plugin to the auto discovery client.
106
            $container->register('httplug.client', PluginClient::class)
107
                ->addArgument(new Reference('httplug.client.default'))
108
                ->addArgument([new Reference('httplug.collector.history_plugin')]);
109
        }
110
    }
111
112
    /**
113
     * @param ContainerBuilder $container
114
     * @param array            $config
115
     */
116
    private function configurePlugins(ContainerBuilder $container, array $config)
117
    {
118
        if (!empty($config['authentication'])) {
119
            $this->configureAuthentication($container, $config['authentication']);
120
        }
121
        unset($config['authentication']);
122
123
        foreach ($config as $name => $pluginConfig) {
124
            $pluginId = 'httplug.plugin.'.$name;
125
126
            if ($pluginConfig['enabled']) {
127
                $def = $container->getDefinition($pluginId);
128
                $this->configurePluginByName($name, $def, $pluginConfig);
129
            } else {
130
                $container->removeDefinition($pluginId);
131
            }
132
        }
133
    }
134
135
    /**
136
     * @param string     $name
137
     * @param Definition $definition
138
     * @param array      $config
139
     */
140
    private function configurePluginByName($name, Definition $definition, array $config)
141
    {
142
        switch ($name) {
143 View Code Duplication
            case 'cache':
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...
144
                // To preserve BC, we check the existence of the new plugin class and use it if available
145
                if (class_exists(CachePlugin::class)) {
146
                    $definition->setClass(CachePlugin::class);
147
                }
148
                $definition
149
                    ->replaceArgument(0, new Reference($config['cache_pool']))
150
                    ->replaceArgument(1, new Reference($config['stream_factory']))
151
                    ->replaceArgument(2, $config['config']);
152
                break;
153
            case 'cookie':
154
                $definition->replaceArgument(0, new Reference($config['cookie_jar']));
155
                break;
156
            case 'decoder':
157
                $definition->addArgument($config['use_content_encoding']);
158
                break;
159
            case 'history':
160
                $definition->replaceArgument(0, new Reference($config['journal']));
161
                break;
162 View Code Duplication
            case 'logger':
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...
163
                // To preserve BC, we check the existence of the new plugin class and use it if available
164
                if (class_exists(LoggerPlugin::class)) {
165
                    $definition->setClass(LoggerPlugin::class);
166
                }
167
                $definition->replaceArgument(0, new Reference($config['logger']));
168
                if (!empty($config['formatter'])) {
169
                    $definition->replaceArgument(1, new Reference($config['formatter']));
170
                }
171
                break;
172
            case 'redirect':
173
                $definition
174
                    ->addArgument($config['preserve_header'])
175
                    ->addArgument($config['use_default_for_multiple']);
176
                break;
177
            case 'retry':
178
                $definition->addArgument($config['retry']);
179
                break;
180
            case 'stopwatch':
181
                // To preserve BC, we check the existence of the new plugin class and use it if available
182
                if (class_exists(StopwatchPlugin::class)) {
183
                    $definition->setClass(StopwatchPlugin::class);
184
                }
185
                $definition->replaceArgument(0, new Reference($config['stopwatch']));
186
                break;
187
        }
188
    }
189
190
    /**
191
     * @param ContainerBuilder $container
192
     * @param array            $config
193
     */
194
    private function configureAuthentication(ContainerBuilder $container, array $config)
195
    {
196
        foreach ($config as $name => $values) {
197
            $authServiceKey = sprintf('httplug.plugin.authentication.%s.auth', $name);
198
            switch ($values['type']) {
199
                case 'bearer':
200
                    $container->register($authServiceKey, Bearer::class)
201
                        ->addArgument($values['token']);
202
                    break;
203
                case 'basic':
204
                    $container->register($authServiceKey, BasicAuth::class)
205
                        ->addArgument($values['username'])
206
                        ->addArgument($values['password']);
207
                    break;
208
                case 'wsse':
209
                    $container->register($authServiceKey, Wsse::class)
210
                        ->addArgument($values['username'])
211
                        ->addArgument($values['password']);
212
                    break;
213
                case 'service':
214
                    $authServiceKey = $values['service'];
215
                    break;
216
                default:
217
                    throw new \LogicException(sprintf('Unknown authentication type: "%s"', $values['type']));
218
            }
219
220
            $container->register('httplug.plugin.authentication.'.$name, AuthenticationPlugin::class)
221
                ->addArgument(new Reference($authServiceKey));
222
        }
223
    }
224
}
225