From 190d59b38932f17a96d2a54747579d58bb08719d Mon Sep 17 00:00:00 2001 From: Tobias Nyholm Date: Tue, 5 Jan 2016 13:47:26 +0100 Subject: [PATCH] Added plugin feature --- ClientFactory/PluginClientFactory.php | 25 +++++++++++++ DependencyInjection/Configuration.php | 4 +++ DependencyInjection/HttplugExtension.php | 30 ++++++++++++++-- README.md | 45 +++++++++++++++++++----- Resources/config/plugins.xml | 17 +++++++++ 5 files changed, 110 insertions(+), 11 deletions(-) create mode 100644 ClientFactory/PluginClientFactory.php create mode 100644 Resources/config/plugins.xml 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 @@ + + + + + + + + + + + + + + +