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

HttplugExtension::configurePluginByName()   C

Complexity

Conditions 13
Paths 14

Size

Total Lines 46
Code Lines 39

Duplication

Lines 18
Ratio 39.13 %

Code Coverage

Tests 0
CRAP Score 182

Importance

Changes 2
Bugs 0 Features 2
Metric Value
c 2
b 0
f 2
dl 18
loc 46
ccs 0
cts 0
cp 0
rs 5.1118
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\PluginClient;
7
use Http\HttplugBundle\ClientFactory\DummyClient;
8
use Http\Message\Authentication\BasicAuth;
9
use Http\Message\Authentication\Bearer;
10
use Http\Message\Authentication\Wsse;
11
use Symfony\Component\Config\FileLocator;
12
use Symfony\Component\DependencyInjection\ContainerBuilder;
13
use Symfony\Component\DependencyInjection\Definition;
14
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
15
use Symfony\Component\DependencyInjection\Reference;
16
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
17
18
/**
19
 * @author David Buchmann <[email protected]>
20
 * @author Tobias Nyholm <[email protected]>
21
 */
22
class HttplugExtension extends Extension
23
{
24
    /**
25
     * {@inheritdoc}
26
     */
27 3
    public function load(array $configs, ContainerBuilder $container)
28
    {
29 3
        $configuration = $this->getConfiguration($configs, $container);
30 3
        $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...
31
32 3
        $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
33
34 3
        $loader->load('services.xml');
35 3
        $loader->load('plugins.xml');
36
37 3
        $enabled = is_bool($config['toolbar']['enabled']) ? $config['toolbar']['enabled'] : $container->hasParameter('kernel.debug') && $container->getParameter('kernel.debug');
38 3
        if ($enabled) {
39
            $loader->load('data-collector.xml');
40
            $config['_inject_collector_plugin'] = true;
41
42
            if (!empty($config['toolbar']['formatter'])) {
43
                $container->getDefinition('httplug.collector.message_journal')
44
                    ->replaceArgument(0, new Reference($config['toolbar']['formatter']));
45
            }
46
        }
47
48 3
        foreach ($config['classes'] as $service => $class) {
49 3
            if (!empty($class)) {
50 1
                $container->register(sprintf('httplug.%s.default', $service), $class);
51 1
            }
52 3
        }
53
54 3
        foreach ($config['main_alias'] as $type => $id) {
55 3
            $container->setAlias(sprintf('httplug.%s', $type), $id);
56 3
        }
57
58 3
        $this->configurePlugins($container, $config['plugins']);
59 3
        $this->configureClients($container, $config);
60 3
    }
61
62
    /**
63
     * Configure client services.
64
     *
65
     * @param ContainerBuilder $container
66
     * @param array            $config
67
     */
68 3
    private function configureClients(ContainerBuilder $container, array $config)
69
    {
70 3
        $first = isset($config['clients']['default']) ? 'default' : null;
71 3
        foreach ($config['clients'] as $name => $arguments) {
72
            if ($first === null) {
73
                $first = $name;
74
            }
75
76
            if (isset($config['_inject_collector_plugin'])) {
77
                array_unshift($arguments['plugins'], 'httplug.collector.history_plugin');
78
            }
79
80
            $def = $container->register('httplug.client.'.$name, DummyClient::class);
81
82
            if (empty($arguments['plugins'])) {
83
                $def->setFactory([new Reference($arguments['factory']), 'createClient'])
84
                    ->addArgument($arguments['config']);
85
            } else {
86
                $def->setFactory('Http\HttplugBundle\ClientFactory\PluginClientFactory::createPluginClient')
87
                    ->addArgument(array_map(function ($id) {
88
                        return new Reference($id);
89
                    }, $arguments['plugins']))
90
                    ->addArgument(new Reference($arguments['factory']))
91
                    ->addArgument($arguments['config']);
92
            }
93 3
        }
94
95
        // If we have clients configured
96 3
        if ($first !== null) {
97
            if ($first !== 'default') {
98
                // Alias the first client to httplug.client.default
99
                $container->setAlias('httplug.client.default', 'httplug.client.'.$first);
100
            }
101 3
        } elseif (isset($config['_inject_collector_plugin'])) {
102
            // No client was configured. Make sure to inject history plugin to the auto discovery client.
103
            $container->register('httplug.client', PluginClient::class)
104
                ->addArgument(new Reference('httplug.client.default'))
105
                ->addArgument([new Reference('httplug.collector.history_plugin')]);
106
        }
107
    }
108
109
    /**
110
     * @param ContainerBuilder $container
111
     * @param array            $config
112
     */
113
    private function configurePlugins(ContainerBuilder $container, array $config)
114
    {
115
        if (!empty($config['authentication'])) {
116
            $this->configureAuthentication($container, $config['authentication']);
117
        }
118
        unset($config['authentication']);
119
120
        foreach ($config as $name => $pluginConfig) {
121
            $pluginId = 'httplug.plugin.'.$name;
122
123
            if ($pluginConfig['enabled']) {
124
                $def = $container->getDefinition($pluginId);
125
                $this->configurePluginByName($name, $def, $pluginConfig);
126
            } else {
127
                $container->removeDefinition($pluginId);
128
            }
129
        }
130
    }
131
132
    /**
133
     * @param string     $name
134
     * @param Definition $definition
135
     * @param array      $config
136
     */
137
    private function configurePluginByName($name, Definition $definition, array $config)
138
    {
139
        switch ($name) {
140 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...
141
                if (class_exists('Http\Client\Common\Plugin\CachePlugin')) {
142
                    $definition->setClass('Http\Client\Common\Plugin\CachePlugin');
143
                }
144
                $definition
145
                    ->replaceArgument(0, new Reference($config['cache_pool']))
146
                    ->replaceArgument(1, new Reference($config['stream_factory']))
147
                    ->replaceArgument(2, $config['config']);
148
                break;
149
            case 'cookie':
150
                $definition->replaceArgument(0, new Reference($config['cookie_jar']));
151
                break;
152
            case 'decoder':
153
                $definition->addArgument($config['use_content_encoding']);
154
                break;
155
            case 'history':
156
                $definition->replaceArgument(0, new Reference($config['journal']));
157
                break;
158 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...
159
                if (class_exists('Http\Client\Common\Plugin\LoggerPlugin')) {
160
                    $definition->setClass('Http\Client\Common\Plugin\LoggerPlugin');
161
                }
162
                $definition->replaceArgument(0, new Reference($config['logger']));
163
                if (!empty($config['formatter'])) {
164
                    $definition->replaceArgument(1, new Reference($config['formatter']));
165
                }
166
                break;
167
            case 'redirect':
168
                $definition
169
                    ->addArgument($config['preserve_header'])
170
                    ->addArgument($config['use_default_for_multiple']);
171
                break;
172
            case 'retry':
173
                $definition->addArgument($config['retry']);
174
                break;
175
            case 'stopwatch':
176
                if (class_exists('Http\Client\Common\Plugin\StopwatchPlugin')) {
177
                    $definition->setClass('Http\Client\Common\Plugin\StopwatchPlugin');
178
                }
179
                $definition->replaceArgument(0, new Reference($config['stopwatch']));
180
                break;
181
        }
182
    }
183
184
    /**
185
     * @param ContainerBuilder $container
186
     * @param array            $config
187
     */
188
    private function configureAuthentication(ContainerBuilder $container, array $config)
189
    {
190
        foreach ($config as $name => $values) {
191
            $authServiceKey = sprintf('httplug.plugin.authentication.%s.auth', $name);
192
            switch ($values['type']) {
193
                case 'bearer':
194
                    $container->register($authServiceKey, Bearer::class)
195
                        ->addArgument($values['token']);
196
                    break;
197
                case 'basic':
198
                    $container->register($authServiceKey, BasicAuth::class)
199
                        ->addArgument($values['username'])
200
                        ->addArgument($values['password']);
201
                    break;
202
                case 'wsse':
203
                    $container->register($authServiceKey, Wsse::class)
204
                        ->addArgument($values['username'])
205
                        ->addArgument($values['password']);
206
                    break;
207
                case 'service':
208
                    $authServiceKey = $values['service'];
209
                    break;
210
                default:
211
                    throw new \LogicException(sprintf('Unknown authentication type: "%s"', $values['type']));
212
            }
213
214
            $container->register('httplug.plugin.authentication.'.$name, AuthenticationPlugin::class)
215
                ->addArgument(new Reference($authServiceKey));
216
        }
217
    }
218
}
219