Completed
Push — master ( b17853...f56531 )
by David
09:10
created

HttplugExtension::configureClient()   B

Complexity

Conditions 4
Paths 8

Size

Total Lines 41
Code Lines 25

Duplication

Lines 12
Ratio 29.27 %

Code Coverage

Tests 0
CRAP Score 20

Importance

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