1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Http\HttplugBundle\DependencyInjection; |
4
|
|
|
|
5
|
|
|
use Http\Client\Common\BatchClient; |
6
|
|
|
use Http\Client\Common\FlexibleHttpClient; |
7
|
|
|
use Http\Client\Common\HttpMethodsClient; |
8
|
|
|
use Http\Client\Common\Plugin\AuthenticationPlugin; |
9
|
|
|
use Http\Discovery\HttpAsyncClientDiscovery; |
10
|
|
|
use Http\Discovery\HttpClientDiscovery; |
11
|
|
|
use Http\HttplugBundle\ClientFactory\DummyClient; |
12
|
|
|
use Http\HttplugBundle\ClientFactory\PluginClientFactory; |
13
|
|
|
use Http\HttplugBundle\Collector\ProfileClientFactory; |
14
|
|
|
use Http\HttplugBundle\Collector\ProfilePlugin; |
15
|
|
|
use Http\Message\Authentication\BasicAuth; |
16
|
|
|
use Http\Message\Authentication\Bearer; |
17
|
|
|
use Http\Message\Authentication\Wsse; |
18
|
|
|
use Psr\Http\Message\UriInterface; |
19
|
|
|
use Symfony\Component\Config\FileLocator; |
20
|
|
|
use Symfony\Component\DependencyInjection\ChildDefinition; |
21
|
|
|
use Symfony\Component\DependencyInjection\ContainerBuilder; |
22
|
|
|
use Symfony\Component\DependencyInjection\Definition; |
23
|
|
|
use Symfony\Component\DependencyInjection\DefinitionDecorator; |
24
|
|
|
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; |
25
|
|
|
use Symfony\Component\DependencyInjection\Reference; |
26
|
|
|
use Symfony\Component\HttpKernel\DependencyInjection\Extension; |
27
|
|
|
|
28
|
|
|
/** |
29
|
|
|
* @author David Buchmann <[email protected]> |
30
|
|
|
* @author Tobias Nyholm <[email protected]> |
31
|
|
|
*/ |
32
|
|
|
class HttplugExtension extends Extension |
33
|
|
|
{ |
34
|
|
|
/** |
35
|
|
|
* {@inheritdoc} |
36
|
|
|
*/ |
37
|
10 |
|
public function load(array $configs, ContainerBuilder $container) |
38
|
|
|
{ |
39
|
10 |
|
$configuration = $this->getConfiguration($configs, $container); |
40
|
10 |
|
$config = $this->processConfiguration($configuration, $configs); |
41
|
|
|
|
42
|
10 |
|
$loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); |
43
|
|
|
|
44
|
10 |
|
$loader->load('services.xml'); |
45
|
10 |
|
$loader->load('plugins.xml'); |
46
|
|
|
|
47
|
|
|
// Register default services |
48
|
10 |
|
foreach ($config['classes'] as $service => $class) { |
49
|
10 |
|
if (!empty($class)) { |
50
|
1 |
|
$container->register(sprintf('httplug.%s.default', $service), $class); |
51
|
1 |
|
} |
52
|
10 |
|
} |
53
|
|
|
|
54
|
|
|
// Set main aliases |
55
|
10 |
|
foreach ($config['main_alias'] as $type => $id) { |
56
|
10 |
|
$container->setAlias(sprintf('httplug.%s', $type), $id); |
57
|
10 |
|
} |
58
|
|
|
|
59
|
|
|
// Configure toolbar |
60
|
10 |
|
$profilingEnabled = $this->isConfigEnabled($container, $config['profiling']); |
61
|
10 |
|
if ($profilingEnabled) { |
62
|
7 |
|
$loader->load('data-collector.xml'); |
63
|
|
|
|
64
|
7 |
|
if (!empty($config['profiling']['formatter'])) { |
65
|
|
|
// Add custom formatter |
66
|
|
|
$container |
67
|
1 |
|
->getDefinition('httplug.collector.formatter') |
68
|
1 |
|
->replaceArgument(0, new Reference($config['profiling']['formatter'])) |
69
|
|
|
; |
70
|
1 |
|
} |
71
|
|
|
|
72
|
|
|
$container |
73
|
7 |
|
->getDefinition('httplug.formatter.full_http_message') |
74
|
7 |
|
->addArgument($config['profiling']['captured_body_length']) |
75
|
|
|
; |
76
|
7 |
|
} |
77
|
|
|
|
78
|
10 |
|
$this->configureClients($container, $config, $profilingEnabled); |
79
|
10 |
|
$this->configurePlugins($container, $config['plugins']); // must be after clients, as clients.X.plugins might use plugins as templates that will be removed |
80
|
10 |
|
$this->configureAutoDiscoveryClients($container, $config); |
81
|
10 |
|
} |
82
|
|
|
|
83
|
|
|
/** |
84
|
|
|
* Configure client services. |
85
|
|
|
* |
86
|
|
|
* @param ContainerBuilder $container |
87
|
|
|
* @param array $config |
88
|
|
|
* @param bool $profiling |
89
|
|
|
*/ |
90
|
10 |
|
private function configureClients(ContainerBuilder $container, array $config, $profiling) |
91
|
|
|
{ |
92
|
10 |
|
$first = null; |
93
|
10 |
|
$clients = []; |
94
|
|
|
|
95
|
10 |
|
foreach ($config['clients'] as $name => $arguments) { |
96
|
6 |
|
if ($first === null) { |
97
|
|
|
// Save the name of the first configured client. |
98
|
6 |
|
$first = $name; |
99
|
6 |
|
} |
100
|
|
|
|
101
|
6 |
|
$this->configureClient($container, $name, $arguments, $this->isConfigEnabled($container, $config['profiling'])); |
102
|
6 |
|
$clients[] = $name; |
103
|
10 |
|
} |
104
|
|
|
|
105
|
|
|
// If we have clients configured |
106
|
10 |
|
if ($first !== null) { |
107
|
|
|
// If we do not have a client named 'default' |
108
|
6 |
|
if (!isset($config['clients']['default'])) { |
109
|
|
|
// Alias the first client to httplug.client.default |
110
|
6 |
|
$container->setAlias('httplug.client.default', 'httplug.client.'.$first); |
111
|
6 |
|
} |
112
|
6 |
|
} |
113
|
|
|
|
114
|
10 |
|
if ($profiling) { |
115
|
7 |
|
$container->getDefinition('httplug.collector.collector') |
116
|
7 |
|
->setArguments([$clients]) |
117
|
|
|
; |
118
|
7 |
|
} |
119
|
10 |
|
} |
120
|
|
|
|
121
|
|
|
/** |
122
|
|
|
* Configure all Httplug plugins or remove their service definition. |
123
|
|
|
* |
124
|
|
|
* @param ContainerBuilder $container |
125
|
|
|
* @param array $config |
126
|
|
|
*/ |
127
|
10 |
|
private function configurePlugins(ContainerBuilder $container, array $config) |
128
|
|
|
{ |
129
|
10 |
|
if (!empty($config['authentication'])) { |
130
|
|
|
$this->configureAuthentication($container, $config['authentication']); |
131
|
|
|
} |
132
|
10 |
|
unset($config['authentication']); |
133
|
|
|
|
134
|
10 |
|
foreach ($config as $name => $pluginConfig) { |
135
|
10 |
|
$pluginId = 'httplug.plugin.'.$name; |
136
|
|
|
|
137
|
10 |
|
if ($this->isConfigEnabled($container, $pluginConfig)) { |
138
|
10 |
|
$def = $container->getDefinition($pluginId); |
139
|
10 |
|
$this->configurePluginByName($name, $def, $pluginConfig, $container, $pluginId); |
140
|
10 |
|
} else { |
141
|
10 |
|
$container->removeDefinition($pluginId); |
142
|
|
|
} |
143
|
10 |
|
} |
144
|
10 |
|
} |
145
|
|
|
|
146
|
|
|
/** |
147
|
|
|
* @param string $name |
148
|
|
|
* @param Definition $definition |
149
|
|
|
* @param array $config |
150
|
|
|
* @param ContainerBuilder $container In case we need to add additional services for this plugin |
151
|
|
|
* @param string $serviceId Service id of the plugin, in case we need to add additional services for this plugin. |
152
|
|
|
*/ |
153
|
10 |
|
private function configurePluginByName($name, Definition $definition, array $config, ContainerBuilder $container, $serviceId) |
154
|
|
|
{ |
155
|
|
|
switch ($name) { |
156
|
10 |
|
case 'cache': |
157
|
|
|
$definition |
158
|
|
|
->replaceArgument(0, new Reference($config['cache_pool'])) |
159
|
|
|
->replaceArgument(1, new Reference($config['stream_factory'])) |
160
|
|
|
->replaceArgument(2, $config['config']); |
161
|
|
|
break; |
162
|
10 |
|
case 'cookie': |
163
|
|
|
$definition->replaceArgument(0, new Reference($config['cookie_jar'])); |
164
|
|
|
break; |
165
|
10 |
|
case 'decoder': |
166
|
10 |
|
$definition->addArgument([ |
167
|
10 |
|
'use_content_encoding' => $config['use_content_encoding'], |
168
|
10 |
|
]); |
169
|
10 |
|
break; |
170
|
10 |
|
case 'history': |
171
|
|
|
$definition->replaceArgument(0, new Reference($config['journal'])); |
172
|
|
|
break; |
173
|
10 |
|
case 'logger': |
174
|
10 |
|
$definition->replaceArgument(0, new Reference($config['logger'])); |
175
|
10 |
|
if (!empty($config['formatter'])) { |
176
|
|
|
$definition->replaceArgument(1, new Reference($config['formatter'])); |
177
|
|
|
} |
178
|
10 |
|
break; |
179
|
10 |
|
case 'redirect': |
180
|
10 |
|
$definition->addArgument([ |
181
|
10 |
|
'preserve_header' => $config['preserve_header'], |
182
|
10 |
|
'use_default_for_multiple' => $config['use_default_for_multiple'], |
183
|
10 |
|
]); |
184
|
10 |
|
break; |
185
|
10 |
|
case 'retry': |
186
|
10 |
|
$definition->addArgument([ |
187
|
10 |
|
'retries' => $config['retry'], |
188
|
10 |
|
]); |
189
|
10 |
|
break; |
190
|
10 |
|
case 'stopwatch': |
191
|
10 |
|
$definition->replaceArgument(0, new Reference($config['stopwatch'])); |
192
|
10 |
|
break; |
193
|
|
|
|
194
|
|
|
/* client specific plugins */ |
195
|
|
|
|
196
|
3 |
|
case 'add_host': |
197
|
3 |
|
$uriService = $serviceId.'.host_uri'; |
198
|
3 |
|
$this->createUri($container, $uriService, $config['host']); |
199
|
3 |
|
$definition->replaceArgument(0, new Reference($uriService)); |
200
|
3 |
|
$definition->replaceArgument(1, [ |
201
|
3 |
|
'replace' => $config['replace'], |
202
|
3 |
|
]); |
203
|
3 |
|
break; |
204
|
1 |
|
case 'header_append': |
205
|
1 |
|
case 'header_defaults': |
206
|
1 |
|
case 'header_set': |
207
|
1 |
|
case 'header_remove': |
208
|
1 |
|
$definition->replaceArgument(0, $config['headers']); |
209
|
1 |
|
break; |
210
|
|
|
|
211
|
|
|
default: |
212
|
|
|
throw new \InvalidArgumentException(sprintf('Internal exception: Plugin %s is not handled', $name)); |
213
|
|
|
} |
214
|
10 |
|
} |
215
|
|
|
|
216
|
|
|
/** |
217
|
|
|
* @param ContainerBuilder $container |
218
|
|
|
* @param array $config |
219
|
|
|
* |
220
|
|
|
* @return array List of service ids for the authentication plugins. |
221
|
|
|
*/ |
222
|
3 |
|
private function configureAuthentication(ContainerBuilder $container, array $config, $servicePrefix = 'httplug.plugin.authentication') |
223
|
|
|
{ |
224
|
3 |
|
$pluginServices = []; |
225
|
|
|
|
226
|
3 |
|
foreach ($config as $name => $values) { |
227
|
3 |
|
$authServiceKey = sprintf($servicePrefix.'.%s.auth', $name); |
228
|
3 |
|
switch ($values['type']) { |
229
|
3 |
|
case 'bearer': |
230
|
|
|
$container->register($authServiceKey, Bearer::class) |
231
|
|
|
->addArgument($values['token']); |
232
|
|
|
break; |
233
|
|
|
case 'basic': |
234
|
|
|
$container->register($authServiceKey, BasicAuth::class) |
235
|
|
|
->addArgument($values['username']) |
236
|
|
|
->addArgument($values['password']); |
237
|
|
|
break; |
238
|
|
|
case 'wsse': |
239
|
|
|
$container->register($authServiceKey, Wsse::class) |
240
|
|
|
->addArgument($values['username']) |
241
|
|
|
->addArgument($values['password']); |
242
|
|
|
break; |
243
|
|
|
case 'service': |
244
|
|
|
$authServiceKey = $values['service']; |
245
|
|
|
break; |
246
|
|
|
default: |
247
|
|
|
throw new \LogicException(sprintf('Unknown authentication type: "%s"', $values['type'])); |
248
|
|
|
} |
249
|
|
|
|
250
|
|
|
$pluginServiceKey = $servicePrefix.'.'.$name; |
251
|
|
|
$container->register($pluginServiceKey, AuthenticationPlugin::class) |
252
|
|
|
->addArgument(new Reference($authServiceKey)) |
253
|
|
|
; |
254
|
|
|
$pluginServices[] = $pluginServiceKey; |
255
|
|
|
} |
256
|
|
|
|
257
|
|
|
return $pluginServices; |
258
|
|
|
} |
259
|
|
|
|
260
|
|
|
/** |
261
|
|
|
* @param ContainerBuilder $container |
262
|
|
|
* @param string $clientName |
263
|
|
|
* @param array $arguments |
264
|
|
|
* @param bool $profiling |
265
|
|
|
*/ |
266
|
|
|
private function configureClient(ContainerBuilder $container, $clientName, array $arguments, $profiling) |
267
|
|
|
{ |
268
|
|
|
$serviceId = 'httplug.client.'.$clientName; |
269
|
|
|
|
270
|
|
|
$plugins = []; |
271
|
|
|
foreach ($arguments['plugins'] as $plugin) { |
272
|
|
|
list($pluginName, $pluginConfig) = each($plugin); |
273
|
|
|
if ('reference' === $pluginName) { |
274
|
|
|
$plugins[] = $pluginConfig['id']; |
275
|
|
|
} elseif ('authentication' === $pluginName) { |
276
|
|
|
$plugins = array_merge($plugins, $this->configureAuthentication($container, $pluginConfig, $serviceId.'.authentication')); |
277
|
|
|
} else { |
278
|
|
|
$plugins[] = $this->configurePlugin($container, $serviceId, $pluginName, $pluginConfig); |
279
|
|
|
} |
280
|
|
|
} |
281
|
|
|
|
282
|
|
|
$pluginClientOptions = []; |
283
|
|
|
if ($profiling) { |
284
|
|
|
//Decorate each plugin with a ProfilePlugin instance. |
285
|
|
|
foreach ($plugins as $pluginServiceId) { |
286
|
|
|
$this->decoratePluginWithProfilePlugin($container, $pluginServiceId); |
287
|
|
|
} |
288
|
|
|
|
289
|
|
|
// To profile the requests, add a StackPlugin as first plugin in the chain. |
290
|
|
|
$stackPluginId = $this->configureStackPlugin($container, $clientName, $serviceId); |
291
|
|
|
array_unshift($plugins, $stackPluginId); |
292
|
|
|
} |
293
|
|
|
|
294
|
|
|
$container |
295
|
|
|
->register($serviceId, DummyClient::class) |
296
|
|
|
->setFactory([PluginClientFactory::class, 'createPluginClient']) |
297
|
|
|
->addArgument( |
298
|
|
|
array_map( |
299
|
|
|
function ($id) { |
300
|
|
|
return new Reference($id); |
301
|
|
|
}, |
302
|
|
|
$plugins |
303
|
|
|
) |
304
|
|
|
) |
305
|
|
|
->addArgument(new Reference($arguments['factory'])) |
306
|
|
|
->addArgument($arguments['config']) |
307
|
|
|
->addArgument($pluginClientOptions) |
308
|
|
|
; |
309
|
|
|
|
310
|
|
|
/* |
311
|
|
|
* Decorate the client with clients from client-common |
312
|
|
|
*/ |
313
|
|
View Code Duplication |
if ($arguments['flexible_client']) { |
|
|
|
|
314
|
|
|
$container |
315
|
|
|
->register($serviceId.'.flexible', FlexibleHttpClient::class) |
316
|
|
|
->addArgument(new Reference($serviceId.'.flexible.inner')) |
317
|
|
|
->setPublic(false) |
318
|
|
|
->setDecoratedService($serviceId) |
319
|
|
|
; |
320
|
|
|
} |
321
|
|
|
|
322
|
|
View Code Duplication |
if ($arguments['http_methods_client']) { |
|
|
|
|
323
|
|
|
$container |
324
|
|
|
->register($serviceId.'.http_methods', HttpMethodsClient::class) |
325
|
|
|
->setArguments([new Reference($serviceId.'.http_methods.inner'), new Reference('httplug.message_factory')]) |
326
|
|
|
->setPublic(false) |
327
|
|
|
->setDecoratedService($serviceId) |
328
|
|
|
; |
329
|
|
|
} |
330
|
|
|
|
331
|
|
View Code Duplication |
if ($arguments['batch_client']) { |
|
|
|
|
332
|
|
|
$container |
333
|
|
|
->register($serviceId.'.batch_client', BatchClient::class) |
334
|
|
|
->setArguments([new Reference($serviceId.'.batch_client.inner')]) |
335
|
|
|
->setPublic(false) |
336
|
|
|
->setDecoratedService($serviceId) |
337
|
|
|
; |
338
|
|
|
} |
339
|
|
|
} |
340
|
|
|
|
341
|
|
|
/** |
342
|
|
|
* Create a URI object with the default URI factory. |
343
|
|
|
* |
344
|
|
|
* @param ContainerBuilder $container |
345
|
|
|
* @param string $serviceId Name of the private service to create |
346
|
|
|
* @param string $uri String representation of the URI |
347
|
|
|
*/ |
348
|
|
|
private function createUri(ContainerBuilder $container, $serviceId, $uri) |
349
|
|
|
{ |
350
|
|
|
$container |
351
|
|
|
->register($serviceId, UriInterface::class) |
352
|
|
|
->setPublic(false) |
353
|
|
|
->setFactory([new Reference('httplug.uri_factory'), 'createUri']) |
354
|
|
|
->addArgument($uri) |
355
|
|
|
; |
356
|
|
|
} |
357
|
|
|
|
358
|
|
|
/** |
359
|
|
|
* Make the user can select what client is used for auto discovery. If none is provided, a service will be created |
360
|
|
|
* by finding a client using auto discovery. |
361
|
|
|
* |
362
|
|
|
* @param ContainerBuilder $container |
363
|
|
|
* @param array $config |
364
|
|
|
*/ |
365
|
|
|
private function configureAutoDiscoveryClients(ContainerBuilder $container, array $config) |
366
|
|
|
{ |
367
|
|
|
$httpClient = $config['discovery']['client']; |
368
|
|
|
|
369
|
|
View Code Duplication |
if (!empty($httpClient)) { |
|
|
|
|
370
|
|
|
if ($httpClient === 'auto') { |
371
|
|
|
$httpClient = $this->registerAutoDiscoverableClient( |
372
|
|
|
$container, |
373
|
|
|
'auto_discovered_client', |
374
|
|
|
$this->configureAutoDiscoveryFactory( |
375
|
|
|
$container, |
376
|
|
|
HttpClientDiscovery::class, |
377
|
|
|
'auto_discovered_client', |
378
|
|
|
$config |
379
|
|
|
), |
380
|
|
|
$this->isConfigEnabled($container, $config['profiling']) |
381
|
|
|
); |
382
|
|
|
} |
383
|
|
|
|
384
|
|
|
$httpClient = new Reference($httpClient); |
385
|
|
|
} |
386
|
|
|
|
387
|
|
|
$asyncHttpClient = $config['discovery']['async_client']; |
388
|
|
|
|
389
|
|
View Code Duplication |
if (!empty($asyncHttpClient)) { |
|
|
|
|
390
|
|
|
if ($asyncHttpClient === 'auto') { |
391
|
|
|
$asyncHttpClient = $this->registerAutoDiscoverableClient( |
392
|
|
|
$container, |
393
|
|
|
'auto_discovered_async', |
394
|
|
|
$this->configureAutoDiscoveryFactory( |
395
|
|
|
$container, |
396
|
|
|
HttpAsyncClientDiscovery::class, |
397
|
|
|
'auto_discovered_async', |
398
|
|
|
$config |
399
|
|
|
), |
400
|
|
|
$this->isConfigEnabled($container, $config['profiling']) |
401
|
|
|
); |
402
|
|
|
} |
403
|
|
|
|
404
|
|
|
$asyncHttpClient = new Reference($asyncHttpClient); |
405
|
|
|
} |
406
|
|
|
|
407
|
|
|
if (null === $httpClient && null === $asyncHttpClient) { |
408
|
|
|
$container->removeDefinition('httplug.strategy'); |
409
|
|
|
|
410
|
|
|
return; |
411
|
|
|
} |
412
|
|
|
|
413
|
|
|
$container |
414
|
|
|
->getDefinition('httplug.strategy') |
415
|
|
|
->addArgument($httpClient) |
416
|
|
|
->addArgument($asyncHttpClient) |
417
|
|
|
; |
418
|
|
|
} |
419
|
|
|
|
420
|
|
|
/** |
421
|
|
|
* Find a client with auto discovery and return a service Reference to it. |
422
|
|
|
* |
423
|
|
|
* @param ContainerBuilder $container |
424
|
|
|
* @param string $name |
425
|
|
|
* @param Reference|callable $factory |
426
|
|
|
* @param bool $profiling |
427
|
|
|
* |
428
|
|
|
* @return string service id |
429
|
|
|
*/ |
430
|
|
|
private function registerAutoDiscoverableClient(ContainerBuilder $container, $name, $factory, $profiling) |
431
|
|
|
{ |
432
|
|
|
$serviceId = 'httplug.auto_discovery.'.$name; |
433
|
|
|
|
434
|
|
|
$plugins = []; |
435
|
|
|
if ($profiling) { |
436
|
|
|
// To profile the requests, add a StackPlugin as first plugin in the chain. |
437
|
|
|
$plugins[] = $this->configureStackPlugin($container, $name, $serviceId); |
438
|
|
|
} |
439
|
|
|
|
440
|
|
|
$container |
441
|
|
|
->register($serviceId, DummyClient::class) |
442
|
|
|
->setFactory([PluginClientFactory::class, 'createPluginClient']) |
443
|
|
|
->setArguments([ |
444
|
|
|
array_map( |
445
|
|
|
function ($id) { |
446
|
|
|
return new Reference($id); |
447
|
|
|
}, |
448
|
|
|
$plugins |
449
|
|
|
), |
450
|
|
|
$factory, |
451
|
|
|
[], |
452
|
|
|
]) |
453
|
|
|
; |
454
|
|
|
|
455
|
|
|
if ($profiling) { |
456
|
|
|
$collector = $container->getDefinition('httplug.collector.collector'); |
457
|
|
|
$collector->replaceArgument(0, array_merge($collector->getArgument(0), [$name])); |
458
|
|
|
} |
459
|
|
|
|
460
|
|
|
return $serviceId; |
461
|
|
|
} |
462
|
|
|
|
463
|
|
|
/** |
464
|
|
|
* {@inheritdoc} |
465
|
|
|
*/ |
466
|
|
|
public function getConfiguration(array $config, ContainerBuilder $container) |
467
|
|
|
{ |
468
|
|
|
return new Configuration($container->getParameter('kernel.debug')); |
469
|
|
|
} |
470
|
|
|
|
471
|
|
|
/** |
472
|
|
|
* Configure a plugin using the parent definition from plugins.xml. |
473
|
|
|
* |
474
|
|
|
* @param ContainerBuilder $container |
475
|
|
|
* @param string $serviceId |
476
|
|
|
* @param string $pluginName |
477
|
|
|
* @param array $pluginConfig |
478
|
|
|
* |
479
|
|
|
* @return string configured service id |
480
|
|
|
*/ |
481
|
|
|
private function configurePlugin(ContainerBuilder $container, $serviceId, $pluginName, array $pluginConfig) |
482
|
|
|
{ |
483
|
|
|
$pluginServiceId = $serviceId.'.plugin.'.$pluginName; |
484
|
|
|
|
485
|
|
|
$definition = class_exists(ChildDefinition::class) |
486
|
|
|
? new ChildDefinition('httplug.plugin.'.$pluginName) |
487
|
|
|
: new DefinitionDecorator('httplug.plugin.'.$pluginName); |
488
|
|
|
|
489
|
|
|
$this->configurePluginByName($pluginName, $definition, $pluginConfig, $container, $pluginServiceId); |
490
|
|
|
$container->setDefinition($pluginServiceId, $definition); |
491
|
|
|
|
492
|
|
|
return $pluginServiceId; |
493
|
|
|
} |
494
|
|
|
|
495
|
|
|
/** |
496
|
|
|
* Decorate the plugin service with a ProfilePlugin service. |
497
|
|
|
* |
498
|
|
|
* @param ContainerBuilder $container |
499
|
|
|
* @param string $pluginServiceId |
500
|
|
|
*/ |
501
|
|
|
private function decoratePluginWithProfilePlugin(ContainerBuilder $container, $pluginServiceId) |
502
|
|
|
{ |
503
|
|
|
$container->register($pluginServiceId.'.debug', ProfilePlugin::class) |
504
|
|
|
->setDecoratedService($pluginServiceId) |
505
|
|
|
->setArguments([ |
506
|
|
|
new Reference($pluginServiceId.'.debug.inner'), |
507
|
|
|
new Reference('httplug.collector.collector'), |
508
|
|
|
new Reference('httplug.collector.formatter'), |
509
|
|
|
$pluginServiceId, |
510
|
|
|
]) |
511
|
|
|
->setPublic(false); |
512
|
|
|
} |
513
|
|
|
|
514
|
|
|
/** |
515
|
|
|
* Configure a StackPlugin for a client. |
516
|
|
|
* |
517
|
|
|
* @param ContainerBuilder $container |
518
|
|
|
* @param string $clientName Client name to display in the profiler. |
519
|
|
|
* @param string $serviceId Client service id. Used as base for the StackPlugin service id. |
520
|
|
|
* |
521
|
|
|
* @return string configured StackPlugin service id |
522
|
|
|
*/ |
523
|
|
|
private function configureStackPlugin(ContainerBuilder $container, $clientName, $serviceId) |
524
|
|
|
{ |
525
|
|
|
$pluginServiceId = $serviceId.'.plugin.stack'; |
526
|
|
|
|
527
|
|
|
$definition = class_exists(ChildDefinition::class) |
528
|
|
|
? new ChildDefinition('httplug.plugin.stack') |
529
|
|
|
: new DefinitionDecorator('httplug.plugin.stack'); |
530
|
|
|
|
531
|
|
|
$definition->addArgument($clientName); |
532
|
|
|
$container->setDefinition($pluginServiceId, $definition); |
533
|
|
|
|
534
|
|
|
return $pluginServiceId; |
535
|
|
|
} |
536
|
|
|
|
537
|
|
|
/** |
538
|
|
|
* Configure the discovery factory when profiling is enabled to get client decorated with a ProfileClient. |
539
|
|
|
* |
540
|
|
|
* @param ContainerBuilder $container |
541
|
|
|
* @param string $discovery |
542
|
|
|
* @param string $name |
543
|
|
|
* @param array $config |
544
|
|
|
* |
545
|
|
|
* @return callable|Reference |
546
|
|
|
*/ |
547
|
|
|
private function configureAutoDiscoveryFactory(ContainerBuilder $container, $discovery, $name, array $config) |
548
|
|
|
{ |
549
|
|
|
$factory = [$discovery, 'find']; |
550
|
|
|
if ($this->isConfigEnabled($container, $config['profiling'])) { |
551
|
|
|
$factoryServiceId = 'httplug.auto_discovery.'.$name.'.factory'; |
552
|
|
|
$container->register($factoryServiceId, ProfileClientFactory::class) |
553
|
|
|
->setPublic(false) |
554
|
|
|
->setArguments([ |
555
|
|
|
$factory, |
556
|
|
|
new Reference('httplug.collector.collector'), |
557
|
|
|
new Reference('httplug.collector.formatter'), |
558
|
|
|
new Reference('debug.stopwatch'), |
559
|
|
|
]); |
560
|
|
|
$factory = new Reference($factoryServiceId); |
561
|
|
|
} |
562
|
|
|
|
563
|
|
|
return $factory; |
564
|
|
|
} |
565
|
|
|
} |
566
|
|
|
|
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.