Completed
Pull Request — master (#44)
by Tobias
31:57
created

HttplugExtension::configureClients()   C

Complexity

Conditions 8
Paths 54

Size

Total Lines 37
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 5
Bugs 1 Features 4
Metric Value
c 5
b 1
f 4
dl 0
loc 37
rs 5.3846
cc 8
eloc 24
nc 54
nop 2
1
<?php
2
3
namespace Http\HttplugBundle\DependencyInjection;
4
5
use Http\Client\Plugin\AuthenticationPlugin;
6
use Http\Client\Plugin\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\DefinitionDecorator;
15
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
16
use Symfony\Component\DependencyInjection\Reference;
17
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
18
19
/**
20
 * @author David Buchmann <[email protected]>
21
 * @author Tobias Nyholm <[email protected]>
22
 */
23
class HttplugExtension extends Extension
24
{
25
    /**
26
     * {@inheritdoc}
27
     */
28
    public function load(array $configs, ContainerBuilder $container)
29
    {
30
        $configuration = $this->getConfiguration($configs, $container);
31
        $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...
32
33
        $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
34
35
        $loader->load('services.xml');
36
        $loader->load('plugins.xml');
37
        $loader->load('discovery.xml');
38
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
        }
49
50
        foreach ($config['classes'] as $service => $class) {
51
            if (!empty($class)) {
52
                $container->removeDefinition(sprintf('httplug.%s.default', $service));
53
                $container->register(sprintf('httplug.%s.default', $service), $class);
54
            }
55
        }
56
57
        foreach ($config['main_alias'] as $type => $id) {
58
            $container->setAlias(sprintf('httplug.%s', $type), $id);
59
        }
60
        $this->configurePlugins($container, $config['plugins']);
61
        $this->configureClients($container, $config);
62
    }
63
64
    /**
65
     * Configure client services.
66
     *
67
     * @param ContainerBuilder $container
68
     * @param array            $config
69
     */
70
    private function configureClients(ContainerBuilder $container, array $config)
71
    {
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
            $def = $container->register('httplug.client.'.$name, DummyClient::class);
83
84
            if (empty($arguments['plugins'])) {
85
                $def->setFactory([new Reference($arguments['factory']), 'createClient'])
86
                    ->addArgument($arguments['config']);
87
            } else {
88
                $def->setFactory('Http\HttplugBundle\ClientFactory\PluginClientFactory::createPluginClient')
89
                    ->addArgument(array_map(function ($id) {
90
                        return new Reference($id);
91
                    }, $arguments['plugins']))
92
                    ->addArgument(new Reference($arguments['factory']))
93
                    ->addArgument($arguments['config']);
94
            }
95
        }
96
97
        // Alias the first client to httplug.client.default
98
        if ($first !== null) {
99
            $container->setAlias('httplug.client.default', 'httplug.client.'.$first);
100
        } elseif (isset($config['_inject_collector_plugin'])) {
101
            // No client was configured. Make sure to inject history plugin to the auto discovery client.
102
            $container->register('httplug.client', PluginClient::class)
103
                ->addArgument(new Reference('httplug.client.default'))
104
                ->addArgument([new Reference('httplug.collector.history_plugin')]);
105
        }
106
    }
107
108
    /**
109
     * @param ContainerBuilder $container
110
     * @param array            $config
111
     */
112
    private function configurePlugins(ContainerBuilder $container, array $config)
113
    {
114
        if (!empty($config['authentication'])) {
115
            $this->configureAuthentication($container, $config['authentication']);
116
        }
117
        unset($config['authentication']);
118
119
        foreach ($config as $name => $pluginConfig) {
120
            $pluginId = 'httplug.plugin.'.$name;
121
            if ($pluginConfig['enabled']) {
122
                $def = $container->getDefinition($pluginId);
123
                $this->configurePluginByName($name, $def, $pluginConfig);
124
            } else {
125
                $container->removeDefinition($pluginId);
126
            }
127
        }
128
    }
129
130
    /**
131
     * @param string     $name
132
     * @param Definition $definition
133
     * @param array      $config
134
     */
135
    private function configurePluginByName($name, Definition $definition, array $config)
136
    {
137
        switch ($name) {
138
            case 'cache':
139
                $definition
140
                    ->replaceArgument(0, new Reference($config['cache_pool']))
141
                    ->replaceArgument(1, new Reference($config['stream_factory']))
142
                    ->replaceArgument(2, $config['config']);
143
                break;
144
            case 'cookie':
145
                $definition->replaceArgument(0, new Reference($config['cookie_jar']));
146
                break;
147
            case 'decoder':
148
                $definition->addArgument($config['use_content_encoding']);
149
                break;
150
            case 'history':
151
                $definition->replaceArgument(0, new Reference($config['journal']));
152
                break;
153
            case 'logger':
154
                $definition->replaceArgument(0, new Reference($config['logger']));
155
                if (!empty($config['formatter'])) {
156
                    $definition->replaceArgument(1, new Reference($config['formatter']));
157
                }
158
                break;
159
            case 'redirect':
160
                $definition
161
                    ->addArgument($config['preserve_header'])
162
                    ->addArgument($config['use_default_for_multiple']);
163
                break;
164
            case 'retry':
165
                $definition->addArgument($config['retry']);
166
                break;
167
            case 'stopwatch':
168
                $definition->replaceArgument(0, new Reference($config['stopwatch']));
169
                break;
170
        }
171
    }
172
173
    /**
174
     * @param ContainerBuilder $container
175
     * @param Definition $parent
0 ignored issues
show
Bug introduced by
There is no parameter named $parent. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
176
     * @param array $config
177
     */
178
    private function configureAuthentication(ContainerBuilder $container, array $config)
179
    {
180
        foreach ($config as $name => $values) {
181
            $authServiceKey = sprintf('httplug.plugin.authentication.%s.auth', $name);
182
            if ($values['type'] === 'bearer') {
183
                $this->validateAuthenticationConfiguration($values, 'bearer', $name, ['token']);
184
                $container->register($authServiceKey, Bearer::class)
185
                    ->addArgument($values['token']);
186
            } elseif($values['type'] === 'basic') {
187
                $this->validateAuthenticationConfiguration($values, 'bearer', $name, ['username', 'password']);
188
                $container->register($authServiceKey, BasicAuth::class)
189
                    ->addArgument($values['username'])
190
                    ->addArgument($values['password']);
191
            } elseif ($values['type'] === 'wsse') {
192
                $this->validateAuthenticationConfiguration($values, 'bearer', $name, ['username', 'password']);
193
                $container->register($authServiceKey, Wsse::class)
194
                    ->addArgument($values['username'])
195
                    ->addArgument($values['password']);
196
            } else {
197
                throw new \LogicException(sprintf('Unknown authentication type: "%s"', $values['type']));
198
            }
199
200
            $container->register('httplug.plugin.authentication.'.$name, AuthenticationPlugin::class)
201
                ->addArgument(new Reference($authServiceKey));
202
        }
203
    }
204
205
    /**
206
     * Throw a Logic error with a descriptive error if some configuration is missing.
207
     *
208
     * @param array $config
209
     * @param string $authType
210
     * @param string $type
211
     * @param array $names
212
     */
213
    private function validateAuthenticationConfiguration(array $config, $type, $authType, array $names)
214
    {
215
        foreach ($names as $name) {
216
            if (empty($config[$name])) {
217
                throw new \LogicException(sprintf('When using %s ahtnetication you must configure a value for "httplug.plugins.authentication.%s.%s".', $type, $authType, $name));
218
            }
219
        }
220
    }
221
}
222