Skip to content

Commit e101865

Browse files
committed
Allow to configure plugins specifically for a client
1 parent 4408c9a commit e101865

File tree

10 files changed

+335
-106
lines changed

10 files changed

+335
-106
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
### Added
1111

12+
- You can now configure plugins on each client in `extra_plugins`. Plugins that you previously had to define your own services can be configured on the client.
1213
- Support for BatchClient
1314
- The stopwatch plugin in included by default when using profiling.
1415

DependencyInjection/Configuration.php

Lines changed: 179 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use Symfony\Component\Config\Definition\ArrayNode;
66
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
7+
use Symfony\Component\Config\Definition\Builder\NodeDefinition;
78
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
89
use Symfony\Component\Config\Definition\ConfigurationInterface;
910
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
@@ -190,6 +191,7 @@ private function configureClients(ArrayNodeDefinition $root)
190191
->prototype('scalar')->end()
191192
->end()
192193
->variableNode('config')->defaultValue([])->end()
194+
->append($this->createExtraPluginsNode())
193195
->end()
194196
->end();
195197
}
@@ -199,122 +201,206 @@ private function configureClients(ArrayNodeDefinition $root)
199201
*/
200202
private function configurePlugins(ArrayNodeDefinition $root)
201203
{
202-
$root->children()
203-
->arrayNode('plugins')
204+
$pluginsNode = $root
205+
->children()
206+
->arrayNode('plugins')
204207
->addDefaultsIfNotSet()
205-
->children()
206-
->append($this->addAuthenticationPluiginNode())
208+
;
209+
$this->configureSharedPluginNodes($pluginsNode);
210+
}
211+
212+
/**
213+
* Create configuration for the extra_plugins node inside the client.
214+
*
215+
* @return NodeDefinition Definition of the extra_plugins node in the client.
216+
*/
217+
private function createExtraPluginsNode()
218+
{
219+
$builder = new TreeBuilder();
220+
$node = $builder->root('extra_plugins');
221+
$node->validate()
222+
->always(function ($plugins) {
223+
if (!count($plugins['authentication'])) {
224+
unset($plugins['authentication']);
225+
}
226+
foreach ($plugins as $name => $definition) {
227+
if (!$definition['enabled']) {
228+
unset($plugins[$name]);
229+
}
230+
}
207231

208-
->arrayNode('cache')
232+
return $plugins;
233+
})
234+
;
235+
$this->configureSharedPluginNodes($node, true);
236+
$node
237+
->children()
238+
->arrayNode('add_host')
209239
->canBeEnabled()
210240
->addDefaultsIfNotSet()
211-
->children()
212-
->scalarNode('cache_pool')
213-
->info('This must be a service id to a service implementing Psr\Cache\CacheItemPoolInterface')
214-
->isRequired()
215-
->cannotBeEmpty()
216-
->end()
217-
->scalarNode('stream_factory')
218-
->info('This must be a service id to a service implementing Http\Message\StreamFactory')
219-
->defaultValue('httplug.stream_factory')
220-
->cannotBeEmpty()
221-
->end()
222-
->arrayNode('config')
223-
->addDefaultsIfNotSet()
224-
->children()
225-
->scalarNode('default_ttl')->defaultNull()->end()
226-
->scalarNode('respect_cache_headers')->defaultTrue()->end()
227-
->end()
228-
->end()
241+
->info('Configure the AddHostPlugin for this client.')
242+
->children()
243+
->scalarNode('host')
244+
->info('Host name including protocol and optionally the port number, e.g. https://api.local:8000')
245+
->isRequired()
246+
->cannotBeEmpty()
229247
->end()
230-
->end() // End cache plugin
231-
232-
->arrayNode('cookie')
233-
->canBeEnabled()
234-
->children()
235-
->scalarNode('cookie_jar')
236-
->info('This must be a service id to a service implementing Http\Message\CookieJar')
237-
->isRequired()
238-
->cannotBeEmpty()
239-
->end()
248+
->scalarNode('replace')
249+
->info('Whether to replace the host if request already specifies it')
250+
->defaultValue(false)
240251
->end()
241-
->end() // End cookie plugin
252+
->end()
253+
->end()
254+
->end()
255+
->end();
242256

243-
->arrayNode('decoder')
244-
->canBeDisabled()
245-
->addDefaultsIfNotSet()
246-
->children()
247-
->scalarNode('use_content_encoding')->defaultTrue()->end()
248-
->end()
249-
->end() // End decoder plugin
257+
return $node;
258+
}
250259

251-
->arrayNode('history')
252-
->canBeEnabled()
253-
->children()
254-
->scalarNode('journal')
255-
->info('This must be a service id to a service implementing Http\Client\Plugin\Journal')
256-
->isRequired()
257-
->cannotBeEmpty()
258-
->end()
259-
->end()
260-
->end() // End history plugin
260+
/**
261+
* @param ArrayNodeDefinition $pluginNode
262+
* @param bool $disableAll Some shared plugins are enabled by default. On the client, all are disabled by default.
263+
*/
264+
private function configureSharedPluginNodes(ArrayNodeDefinition $pluginNode, $disableAll = false)
265+
{
266+
$children = $pluginNode->children();
261267

262-
->arrayNode('logger')
263-
->canBeDisabled()
264-
->addDefaultsIfNotSet()
265-
->children()
266-
->scalarNode('logger')
267-
->info('This must be a service id to a service implementing Psr\Log\LoggerInterface')
268-
->defaultValue('logger')
269-
->cannotBeEmpty()
270-
->end()
271-
->scalarNode('formatter')
272-
->info('This must be a service id to a service implementing Http\Message\Formatter')
273-
->defaultNull()
274-
->end()
275-
->end()
276-
->end() // End logger plugin
268+
$children->append($this->createAuthenticationPluginNode());
277269

278-
->arrayNode('redirect')
279-
->canBeDisabled()
280-
->addDefaultsIfNotSet()
270+
$children->arrayNode('cache')
271+
->canBeEnabled()
272+
->addDefaultsIfNotSet()
273+
->children()
274+
->scalarNode('cache_pool')
275+
->info('This must be a service id to a service implementing Psr\Cache\CacheItemPoolInterface')
276+
->isRequired()
277+
->cannotBeEmpty()
278+
->end()
279+
->scalarNode('stream_factory')
280+
->info('This must be a service id to a service implementing Http\Message\StreamFactory')
281+
->defaultValue('httplug.stream_factory')
282+
->cannotBeEmpty()
283+
->end()
284+
->arrayNode('config')
285+
->addDefaultsIfNotSet()
281286
->children()
282-
->scalarNode('preserve_header')->defaultTrue()->end()
283-
->scalarNode('use_default_for_multiple')->defaultTrue()->end()
287+
->scalarNode('default_ttl')->defaultNull()->end()
288+
->scalarNode('respect_cache_headers')->defaultTrue()->end()
284289
->end()
285-
->end() // End redirect plugin
290+
->end()
291+
->end()
292+
->end();
293+
// End cache plugin
286294

287-
->arrayNode('retry')
288-
->canBeDisabled()
289-
->addDefaultsIfNotSet()
290-
->children()
291-
->scalarNode('retry')->defaultValue(1)->end()
292-
->end()
293-
->end() // End retry plugin
295+
$children->arrayNode('cookie')
296+
->canBeEnabled()
297+
->children()
298+
->scalarNode('cookie_jar')
299+
->info('This must be a service id to a service implementing Http\Message\CookieJar')
300+
->isRequired()
301+
->cannotBeEmpty()
302+
->end()
303+
->end()
304+
->end();
305+
// End cookie plugin
294306

295-
->arrayNode('stopwatch')
296-
->canBeDisabled()
297-
->addDefaultsIfNotSet()
298-
->children()
299-
->scalarNode('stopwatch')
300-
->info('This must be a service id to a service extending Symfony\Component\Stopwatch\Stopwatch')
301-
->defaultValue('debug.stopwatch')
302-
->cannotBeEmpty()
303-
->end()
304-
->end()
305-
->end() // End stopwatch plugin
307+
$decoder = $children->arrayNode('decoder');
308+
if ($disableAll) {
309+
$decoder->canBeEnabled();
310+
} else {
311+
$decoder->canBeDisabled();
312+
}
313+
$decoder->addDefaultsIfNotSet()
314+
->children()
315+
->scalarNode('use_content_encoding')->defaultTrue()->end()
316+
->end()
317+
->end();
318+
// End decoder plugin
319+
320+
$children->arrayNode('history')
321+
->canBeEnabled()
322+
->children()
323+
->scalarNode('journal')
324+
->info('This must be a service id to a service implementing Http\Client\Plugin\Journal')
325+
->isRequired()
326+
->cannotBeEmpty()
327+
->end()
328+
->end()
329+
->end();
330+
// End history plugin
331+
332+
$logger = $children->arrayNode('logger');
333+
if ($disableAll) {
334+
$logger->canBeEnabled();
335+
} else {
336+
$logger->canBeDisabled();
337+
}
338+
$logger->addDefaultsIfNotSet()
339+
->children()
340+
->scalarNode('logger')
341+
->info('This must be a service id to a service implementing Psr\Log\LoggerInterface')
342+
->defaultValue('logger')
343+
->cannotBeEmpty()
344+
->end()
345+
->scalarNode('formatter')
346+
->info('This must be a service id to a service implementing Http\Message\Formatter')
347+
->defaultNull()
348+
->end()
349+
->end()
350+
->end();
351+
// End logger plugin
352+
353+
$redirect = $children->arrayNode('redirect');
354+
if ($disableAll) {
355+
$redirect->canBeEnabled();
356+
} else {
357+
$redirect->canBeDisabled();
358+
}
359+
$redirect->addDefaultsIfNotSet()
360+
->children()
361+
->scalarNode('preserve_header')->defaultTrue()->end()
362+
->scalarNode('use_default_for_multiple')->defaultTrue()->end()
363+
->end()
364+
->end();
365+
// End redirect plugin
306366

367+
$retry = $children->arrayNode('retry');
368+
if ($disableAll) {
369+
$retry->canBeEnabled();
370+
} else {
371+
$retry->canBeDisabled();
372+
}
373+
$retry->addDefaultsIfNotSet()
374+
->children()
375+
->scalarNode('retry')->defaultValue(1)->end() // TODO: should be called retries for consistency with the class
376+
->end()
377+
->end();
378+
// End retry plugin
379+
380+
$stopwatch = $children->arrayNode('stopwatch');
381+
if ($disableAll) {
382+
$stopwatch->canBeEnabled();
383+
} else {
384+
$stopwatch->canBeDisabled();
385+
}
386+
$stopwatch->addDefaultsIfNotSet()
387+
->children()
388+
->scalarNode('stopwatch')
389+
->info('This must be a service id to a service extending Symfony\Component\Stopwatch\Stopwatch')
390+
->defaultValue('debug.stopwatch')
391+
->cannotBeEmpty()
307392
->end()
308393
->end()
309394
->end();
395+
// End stopwatch plugin
310396
}
311397

312398
/**
313-
* Add configuration for authentication plugin.
399+
* Create configuration for authentication plugin.
314400
*
315-
* @return ArrayNodeDefinition|\Symfony\Component\Config\Definition\Builder\NodeDefinition
401+
* @return NodeDefinition Definition for the authentication node in the plugins list.
316402
*/
317-
private function addAuthenticationPluiginNode()
403+
private function createAuthenticationPluginNode()
318404
{
319405
$builder = new TreeBuilder();
320406
$node = $builder->root('authentication');

0 commit comments

Comments
 (0)