Skip to content

Configure plugins #37

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 29, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
127 changes: 127 additions & 0 deletions DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
* sections are normalized, and merged.
*
* @author David Buchmann <mail@davidbu.ch>
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
*/
class Configuration implements ConfigurationInterface
{
Expand All @@ -27,6 +28,7 @@ public function getConfigTreeBuilder()
$rootNode = $treeBuilder->root('httplug');

$this->configureClients($rootNode);
$this->configurePlugins($rootNode);

$rootNode
->validate()
Expand Down Expand Up @@ -108,4 +110,129 @@ protected function configureClients(ArrayNodeDefinition $root)
->end()
->end();
}

/**
* @param ArrayNodeDefinition $root
*/
protected function configurePlugins(ArrayNodeDefinition $root)
{
$root->children()
->arrayNode('plugins')
->addDefaultsIfNotSet()
->children()

->arrayNode('authentication')
->canBeEnabled()
->children()
->scalarNode('authentication')
->info('This must be a service id to a service implementing Http\Message\Authentication')
->isRequired()
->cannotBeEmpty()
->end()
->end()
->end() // End authentication plugin

->arrayNode('cache')
->canBeEnabled()
->addDefaultsIfNotSet()
->children()
->scalarNode('cache_pool')
->info('This must be a service id to a service implementing Psr\Cache\CacheItemPoolInterface')
->isRequired()
->cannotBeEmpty()
->end()
->scalarNode('stream_factory')
->info('This must be a service id to a service implementing Http\Message\StreamFactory')
->defaultValue('httplug.stream_factory')
->cannotBeEmpty()
->end()
->arrayNode('config')
->addDefaultsIfNotSet()
->children()
->scalarNode('default_ttl')->defaultNull()->end()
->scalarNode('respect_cache_headers')->defaultTrue()->end()
->end()
->end()
->end()
->end() // End cache plugin

->arrayNode('cookie')
->canBeEnabled()
->children()
->scalarNode('cookie_jar')
->info('This must be a service id to a service implementing Http\Message\CookieJar')
->isRequired()
->cannotBeEmpty()
->end()
->end()
->end() // End cookie plugin

->arrayNode('decoder')
->canBeDisabled()
->addDefaultsIfNotSet()
->children()
->scalarNode('use_content_encoding')->defaultTrue()->end()
->end()
->end() // End decoder plugin

->arrayNode('history')
->canBeEnabled()
->children()
->scalarNode('journal')
->info('This must be a service id to a service implementing Http\Client\Plugin\Journal')
->isRequired()
->cannotBeEmpty()
->end()
->end()
->end() // End history plugin

->arrayNode('logger')
->canBeDisabled()
->addDefaultsIfNotSet()
->children()
->scalarNode('logger')
->info('This must be a service id to a service implementing Psr\Log\LoggerInterface')
->defaultValue('logger')
->cannotBeEmpty()
->end()
->scalarNode('formatter')
->info('This must be a service id to a service implementing Http\Message\Formatter')
->defaultNull()
->end()
->end()
->end() // End logger plugin

->arrayNode('redirect')
->canBeDisabled()
->addDefaultsIfNotSet()
->children()
->scalarNode('preserve_header')->defaultTrue()->end()
->scalarNode('use_default_for_multiple')->defaultTrue()->end()
->end()
->end() // End redirect plugin

->arrayNode('retry')
->canBeDisabled()
->addDefaultsIfNotSet()
->children()
->scalarNode('retry')->defaultValue(1)->end()
->end()
->end() // End retry plugin

->arrayNode('stopwatch')
->canBeDisabled()
->addDefaultsIfNotSet()
->children()
->scalarNode('stopwatch')
->info('This must be a service id to a service extending Symfony\Component\Stopwatch\Stopwatch')
->defaultValue('debug.stopwatch')
->cannotBeEmpty()
->end()
->end()
->end() // End stopwatch plugin

->end()
->end()
->end();
}
}
68 changes: 67 additions & 1 deletion DependencyInjection/HttplugExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@
use Http\HttplugBundle\ClientFactory\DummyClient;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;

/**
* @author David Buchmann <mail@davidbu.ch>
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
*/
class HttplugExtension extends Extension
{
Expand Down Expand Up @@ -50,6 +52,7 @@ public function load(array $configs, ContainerBuilder $container)
foreach ($config['main_alias'] as $type => $id) {
$container->setAlias(sprintf('httplug.%s', $type), $id);
}
$this->configurePlugins($container, $config['plugins']);
$this->configureClients($container, $config);
}

Expand All @@ -59,7 +62,7 @@ public function load(array $configs, ContainerBuilder $container)
* @param ContainerBuilder $container
* @param array $config
*/
protected function configureClients(ContainerBuilder $container, array $config)
private function configureClients(ContainerBuilder $container, array $config)
{
$first = isset($config['clients']['default']) ? 'default' : null;
foreach ($config['clients'] as $name => $arguments) {
Expand Down Expand Up @@ -96,4 +99,67 @@ protected function configureClients(ContainerBuilder $container, array $config)
->addArgument([new Reference('httplug.collector.history_plugin')]);
}
}

/**
* @param ContainerBuilder $container
* @param array $config
*/
private function configurePlugins(ContainerBuilder $container, array $config)
{
foreach ($config as $name => $pluginConfig) {
$pluginId = 'httplug.plugin.'.$name;
if ($pluginConfig['enabled']) {
$def = $container->getDefinition($pluginId);
$this->configurePluginByName($name, $def, $pluginConfig);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or configurePlugin$name() and split the code below into a method per case?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was considering that approach. Switch statements are code smell but dynamic functions like that is worse. Also, you cant type hint dynamic functions in PHP7

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

okay. lets keep this then. its very internal either way so no big deal.

} else {
$container->removeDefinition($pluginId);
}
}
}

/**
* @param string $name
* @param Definition $definition
* @param array $config
*/
private function configurePluginByName($name, Definition $definition, array $config)
{
switch ($name) {
case 'authentication':
$definition->replaceArgument(0, new Reference($config['authentication']));
break;
case 'cache':
$definition
->replaceArgument(0, new Reference($config['cache_pool']))
->replaceArgument(1, new Reference($config['stream_factory']))
->replaceArgument(2, $config['config']);
break;
case 'cookie':
$definition->replaceArgument(0, new Reference($config['cookie_jar']));
break;
case 'decoder':
$definition->addArgument($config['use_content_encoding']);
break;
case 'history':
$definition->replaceArgument(0, new Reference($config['journal']));
break;
case 'logger':
$definition->replaceArgument(0, new Reference($config['logger']));
if (!empty($config['formatter'])) {
$definition->replaceArgument(1, new Reference($config['formatter']));
}
break;
case 'redirect':
$definition
->addArgument($config['preserve_header'])
->addArgument($config['use_default_for_multiple']);
break;
case 'retry':
$definition->addArgument($config['retry']);
break;
case 'stopwatch':
$definition->replaceArgument(0, new Reference($config['stopwatch']));
break;
}
}
}
1 change: 1 addition & 0 deletions HttplugBundle.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

/**
* @author David Buchmann <mail@davidbu.ch>
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
*/
class HttplugBundle extends Bundle
{
Expand Down
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ For information how to write applications with the services provided by this bun
| 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 <br> httplug.plugin.decoder<br> httplug.plugin.error<br> httplug.plugin.logger<br> httplug.plugin.redirect<br> httplug.plugin.retry | These are built in plugins that live in the `php-http/plugins` package. These servcies are not public and may only be used when configure HttpClients or services.
| httplug.plugin.content_length <br> httplug.plugin.decoder<br> httplug.plugin.error<br> httplug.plugin.logger<br> httplug.plugin.redirect<br> httplug.plugin.retry<br> httplug.plugin.stopwatch | These are plugins that are enabled by default. These services are not public and may only be used when configure HttpClients or other services.
| httplug.plugin.authentication <br> httplug.plugin.cache<br> httplug.plugin.cookie<br> httplug.plugin.history | These are plugins that are disabled by default. They need to be configured before they can be used. These services are not public and may only be used when configure HttpClients or other 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.*

Expand Down Expand Up @@ -122,10 +123,13 @@ acme_plugin:
```yaml
// config.yml
httpug:
plugins:
cache:
cache_pool: 'my_cache_pool'
clients:
acme:
factory: 'httplug.factory.guzzle6'
plugins: ['acme_plugin' , 'httplug.plugin.logger']
plugins: ['acme_plugin', 'httplug.plugin.cache', ''httplug.plugin.retry']
config:
base_uri: 'http://google.se/'
```
Expand Down
20 changes: 19 additions & 1 deletion Resources/config/plugins.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,31 @@
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">

<services>
<service id="httplug.plugin.authentication" class="Http\Client\Plugin\AuthenticationPlugin" public="false">
<argument />
</service>
<service id="httplug.plugin.cache" class="Http\Client\Plugin\CachePlugin" public="false">
<argument />
<argument />
<argument />
</service>
<service id="httplug.plugin.content_length" class="Http\Client\Plugin\ContentLengthPlugin" public="false" />
<service id="httplug.plugin.cookie" class="Http\Client\Plugin\CookiePlugin" public="false">
<argument />
</service>
<service id="httplug.plugin.decoder" class="Http\Client\Plugin\DecoderPlugin" public="false" />
<service id="httplug.plugin.error" class="Http\Client\Plugin\ErrorPlugin" public="false" />
<service id="httplug.plugin.history" class="Http\Client\Plugin\HistoryPlugin" public="false">
<argument />
</service>
<service id="httplug.plugin.logger" class="Http\Client\Plugin\LoggerPlugin" public="false">
<argument type="service" id="logger"/>
<argument />
<argument>null</argument>
</service>
<service id="httplug.plugin.redirect" class="Http\Client\Plugin\RedirectPlugin" public="false" />
<service id="httplug.plugin.retry" class="Http\Client\Plugin\RetryPlugin" public="false" />
<service id="httplug.plugin.stopwatch" class="Http\Client\Plugin\StopwatchPlugin" public="false">
<argument />
</service>
</services>
</container>
Loading