Completed
Pull Request — master (#44)
by Tobias
46:21 queued 31:03
created

HttplugExtension::configureAuthentication()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 26
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

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