diff --git a/ClientFactory/PluginClientFactory.php b/ClientFactory/PluginClientFactory.php
new file mode 100644
index 00000000..725d4a5d
--- /dev/null
+++ b/ClientFactory/PluginClientFactory.php
@@ -0,0 +1,25 @@
+
+ */
+class PluginClientFactory
+{
+ /**
+ * @param array $plugins
+ * @param ClientFactoryInterface $factory
+ * @param array $config
+ *
+ * @return PluginClient
+ */
+ static public function createPluginClient(array $plugins, ClientFactoryInterface $factory, array $config)
+ {
+ return new PluginClient($factory->createClient($config), $plugins);
+ }
+}
\ No newline at end of file
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index 54918b1a..c3684312 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -90,6 +90,10 @@ protected function configureClients(ArrayNodeDefinition $root)
->cannotBeEmpty()
->info('The service id of a factory to use when creating the adapter.')
->end()
+ ->arrayNode('plugins')
+ ->info('A list of service ids of plugins. The order is important.')
+ ->prototype('scalar')->end()
+ ->end()
->variableNode('config')->end()
->end()
->end();
diff --git a/DependencyInjection/HttplugExtension.php b/DependencyInjection/HttplugExtension.php
index cf3b8c4c..c664744a 100644
--- a/DependencyInjection/HttplugExtension.php
+++ b/DependencyInjection/HttplugExtension.php
@@ -25,6 +25,7 @@ public function load(array $configs, ContainerBuilder $container)
$loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('services.xml');
+ $loader->load('plugins.xml');
$loader->load('discovery.xml');
foreach ($config['classes'] as $service => $class) {
if (!empty($class)) {
@@ -36,8 +37,19 @@ public function load(array $configs, ContainerBuilder $container)
foreach ($config['main_alias'] as $type => $id) {
$container->setAlias(sprintf('httplug.%s', $type), $id);
}
+ $this->configureClients($container, $config);
- // Configure client services
+
+ }
+
+ /**
+ * Configure client services
+ *
+ * @param ContainerBuilder $container
+ * @param array $config
+ */
+ protected function configureClients(ContainerBuilder $container, array $config)
+ {
$first = isset($config['clients']['default']) ? 'default' : null;
foreach ($config['clients'] as $name => $arguments) {
if ($first === null) {
@@ -45,10 +57,22 @@ public function load(array $configs, ContainerBuilder $container)
}
$def = $container->register('httplug.client.'.$name, DummyClient::class);
- $def->setFactory([new Reference($arguments['factory']), 'createClient'])
- ->addArgument($arguments['config']);
+
+ if (empty($arguments['plugins'])) {
+ $def->setFactory([new Reference($arguments['factory']), 'createClient'])
+ ->addArgument($arguments['config']);
+ } else {
+ $def->setFactory('Http\HttplugBundle\ClientFactory\PluginClientFactory::createPluginClient')
+ ->addArgument(array_map(function($id) {
+ return new Reference($id);
+ }, $arguments['plugins']))
+ ->addArgument(new Reference($arguments['factory']))
+ ->addArgument($arguments['config']);
+ }
+
}
+ // Alias the first client to httplug.client.default
if ($first !== null) {
$container->setAlias('httplug.client.default', 'httplug.client.'.$first);
}
diff --git a/README.md b/README.md
index e436a159..d5bc83a1 100644
--- a/README.md
+++ b/README.md
@@ -43,19 +43,26 @@ For information how to write applications with the services provided by this bun
#### Custom services
-This bundle provides 3 services:
-* `httplug.client` a service that provides the `Http\Client\HttpClient`
-* `httplug.message_factory` a service that provides the `Http\Message\MessageFactory`
-* `httplug.uri_factory` a service that provides the `Http\Message\UriFactory`
-* `httplug.stream_factory` a service that provides the `Http\Message\StreamFactory`
+| Service id | Description |
+| ---------- | ----------- |
+| httplug.message_factory | Service* that provides the `Http\Message\MessageFactory`
+| httplug.uri_factory | Service* that provides the `Http\Message\UriFactory`
+| httplug.stream_factory | Service* that provides the `Http\Message\StreamFactory`
+| httplug.client.[name] | This is your Httpclient that you have configured. With the configuration below the name would be `acme_client`.
+| httplug.client | This is the first client configured or a client named `default`.
+| httplug.plugin.content_length
httplug.plugin.decoder
httplug.plugin.error
httplug.plugin.logger
httplug.plugin.redirect
httplug.plugin.retry | These are build in plugins that lives in the `php-http/plugins` package. These servcies are not public and may only be used when configure HttpClients or services.
-These services are always an alias to another service. You can specify your own service or leave the default, which is the same name with `.default` appended. The default services in turn use the service discovery mechanism to provide the best available implementation. You can specify a class for each of the default services to use instead of discovery, as long as those classes can be instantiated without arguments.
+\* *These services are always an alias to another service. You can specify your own service or leave the default, which is the same name with `.default` appended. The default services in turn use the service discovery mechanism to provide the best available implementation. You can specify a class for each of the default services to use instead of discovery, as long as those classes can be instantiated without arguments.*
If you need a more custom setup, define the services in your application configuration and specify your service in the `main_alias` section. For example, to add authentication headers, you could define a service that decorates the service `httplug.client.default` with a plugin that injects the authentication headers into the request and configure `httplug.main_alias.client` to the name of your service.
```yaml
httplug:
+ clients:
+ acme_client: # This is the name of the client
+ factory: 'httplug.factory.guzzle6'
+
main_alias:
client: httplug.client.default
message_factory: httplug.message_factory.default
@@ -80,8 +87,8 @@ httplug:
factory: 'httplug.factory.guzzle5'
config:
# These options are given to Guzzle without validation.
- base_url: 'http://google.se/'
defaults:
+ base_uri: 'http://google.se/'
verify_ssl: false
timeout: 4
headers:
@@ -89,7 +96,7 @@ httplug:
acme:
factory: 'httplug.factory.guzzle6'
config:
- base_url: 'http://google.se/'
+ base_uri: 'http://google.se/'
```
@@ -99,6 +106,28 @@ $httpClient = $this->container->get('httplug.client.my_guzzle5');
$httpClient = $this->container->get('httplug.client.acme');
```
+#### Plugins
+
+You can configure the clients with plugins.
+
+```yaml
+// services.yml
+acme_plugin:
+ class: Acme\Plugin\MyCustonPlugin
+ arguments: ["%api_key%"]
+```
+```yaml
+// config.yml
+httpug:
+ clients:
+ acme:
+ factory: 'httplug.factory.guzzle6'
+ plugins: ['acme_plugin' , 'httplug.plugin.logger']
+ config:
+ base_uri: 'http://google.se/'
+```
+
+
### Use for Reusable Bundles
Rather than code against specific HTTP clients, you want to use the Httplug `Client` interface. To avoid building your own infrastructure to define services for the client, simply `require: php-http/httplug-bundle` in your bundles `composer.json`. You SHOULD provide configuration for each of your services that needs an HTTP client to specify the service to use, defaulting to `httplug.client`. This way, the default case needs no additional configuration for your users.
diff --git a/Resources/config/plugins.xml b/Resources/config/plugins.xml
new file mode 100644
index 00000000..72f27834
--- /dev/null
+++ b/Resources/config/plugins.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+