diff --git a/CHANGELOG.md b/CHANGELOG.md index e37bd31..bbd21e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ The change log describes what is "Added", "Removed", "Changed" or "Fixed" betwee # Version 2 +# 2.1.0 + +- Added PluginConfigurator + # 2.0.0 - 2024-09-16 - Increased min PHP version to 8.1 diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index 8456049..f9d0fdb 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -275,6 +275,22 @@ private function createClientPluginNode(): ArrayNodeDefinition ->end() ->end() ->end() + ->arrayNode('configurator') + ->canBeEnabled() + ->info('Configure a plugin with a configurator') + ->children() + ->scalarNode('id') + ->info('Service id of a plugin configurator') + ->isRequired() + ->cannotBeEmpty() + ->end() + ->arrayNode('config') + ->normalizeKeys(false) + ->prototype('variable') + ->end() + ->end() + ->end() + ->end() ->arrayNode('add_host') ->canBeEnabled() ->addDefaultsIfNotSet() diff --git a/src/DependencyInjection/HttplugExtension.php b/src/DependencyInjection/HttplugExtension.php index 2851922..d8c913c 100644 --- a/src/DependencyInjection/HttplugExtension.php +++ b/src/DependencyInjection/HttplugExtension.php @@ -16,6 +16,7 @@ use Http\Client\HttpAsyncClient; use Http\Client\Plugin\Vcr\RecordPlugin; use Http\Client\Plugin\Vcr\ReplayPlugin; +use Http\HttplugBundle\PluginConfigurator; use Http\Message\Authentication\BasicAuth; use Http\Message\Authentication\Bearer; use Http\Message\Authentication\Header; @@ -429,6 +430,18 @@ private function configureClient(ContainerBuilder $container, string $clientName case 'reference': $plugins[] = new Reference($pluginConfig['id']); break; + case 'configurator': + if (!is_a($pluginConfig['id'], PluginConfigurator::class, true)) { + throw new \LogicException(sprintf('The plugin "%s" is not a valid PluginConfigurator.', $pluginConfig['id'])); + } + + $config = $pluginConfig['id']::getConfigTreeBuilder()->buildTree()->finalize($pluginConfig['config']); + + $definition = new Definition(null, [$config]); + $definition->setFactory([new Reference($pluginConfig['id']), 'create']); + + $plugins[] = $definition; + break; case 'authentication': $plugins = array_merge( $plugins, diff --git a/src/PluginConfigurator.php b/src/PluginConfigurator.php new file mode 100644 index 0000000..ecad176 --- /dev/null +++ b/src/PluginConfigurator.php @@ -0,0 +1,20 @@ + $config + */ + public function create(array $config): Plugin; +} diff --git a/tests/Resources/CustomPlugin.php b/tests/Resources/CustomPlugin.php new file mode 100644 index 0000000..c5d639f --- /dev/null +++ b/tests/Resources/CustomPlugin.php @@ -0,0 +1,24 @@ +name = $name; + } + + public function handleRequest(RequestInterface $request, callable $next, callable $first): Promise + { + return $next($request); + } +} diff --git a/tests/Resources/CustomPluginConfigurator.php b/tests/Resources/CustomPluginConfigurator.php new file mode 100644 index 0000000..1d9fa32 --- /dev/null +++ b/tests/Resources/CustomPluginConfigurator.php @@ -0,0 +1,32 @@ +getRootNode(); + + $rootNode + ->children() + ->scalarNode('name') + ->isRequired() + ->cannotBeEmpty() + ->end() + ->end(); + + return $treeBuilder; + } + + public function create(array $config): CustomPlugin + { + return new CustomPlugin($config['name']); + } +} diff --git a/tests/Resources/Fixtures/config/full.php b/tests/Resources/Fixtures/config/full.php index b468f17..3c4c81b 100644 --- a/tests/Resources/Fixtures/config/full.php +++ b/tests/Resources/Fixtures/config/full.php @@ -2,6 +2,8 @@ declare(strict_types=1); +use Http\HttplugBundle\Tests\Resources\CustomPluginConfigurator; + $container->loadFromExtension('httplug', [ 'default_client_autowiring' => false, 'main_alias' => [ @@ -27,6 +29,14 @@ 'http_methods_client' => true, 'plugins' => [ 'httplug.plugin.redirect', + [ + 'configurator' => [ + 'id' => CustomPluginConfigurator::class, + 'config' => [ + 'name' => 'foo', + ], + ], + ], [ 'add_host' => [ 'host' => 'http://localhost', diff --git a/tests/Resources/Fixtures/config/full.xml b/tests/Resources/Fixtures/config/full.xml index d47867d..a233cde 100644 --- a/tests/Resources/Fixtures/config/full.xml +++ b/tests/Resources/Fixtures/config/full.xml @@ -22,6 +22,13 @@ httplug.plugin.redirect + + + + foo + + + diff --git a/tests/Resources/Fixtures/config/full.yml b/tests/Resources/Fixtures/config/full.yml index 7e05459..5d71166 100644 --- a/tests/Resources/Fixtures/config/full.yml +++ b/tests/Resources/Fixtures/config/full.yml @@ -21,6 +21,11 @@ httplug: http_methods_client: true plugins: - 'httplug.plugin.redirect' + - + configurator: + id: Http\HttplugBundle\Tests\Resources\CustomPluginConfigurator + config: + name: foo - add_host: host: http://localhost diff --git a/tests/Unit/DependencyInjection/ConfigurationTest.php b/tests/Unit/DependencyInjection/ConfigurationTest.php index b765450..6ba3d3a 100644 --- a/tests/Unit/DependencyInjection/ConfigurationTest.php +++ b/tests/Unit/DependencyInjection/ConfigurationTest.php @@ -7,6 +7,7 @@ use Http\Adapter\Guzzle7\Client; use Http\HttplugBundle\DependencyInjection\Configuration; use Http\HttplugBundle\DependencyInjection\HttplugExtension; +use Http\HttplugBundle\Tests\Resources\CustomPluginConfigurator; use Matthias\SymfonyDependencyInjectionTest\PhpUnit\AbstractExtensionConfigurationTestCase; use Nyholm\Psr7\Factory\Psr17Factory; use Symfony\Component\Config\Definition\ConfigurationInterface; @@ -155,6 +156,15 @@ public function testSupportsAllConfigFormats(): void 'id' => 'httplug.plugin.redirect', ], ], + [ + 'configurator' => [ + 'enabled' => true, + 'id' => CustomPluginConfigurator::class, + 'config' => [ + 'name' => 'foo', + ], + ], + ], [ 'add_host' => [ 'enabled' => true, diff --git a/tests/Unit/DependencyInjection/HttplugExtensionTest.php b/tests/Unit/DependencyInjection/HttplugExtensionTest.php index 8e10577..a1c51a2 100644 --- a/tests/Unit/DependencyInjection/HttplugExtensionTest.php +++ b/tests/Unit/DependencyInjection/HttplugExtensionTest.php @@ -7,8 +7,10 @@ use Http\Adapter\Guzzle7\Client; use Http\Client\Plugin\Vcr\Recorder\InMemoryRecorder; use Http\HttplugBundle\DependencyInjection\HttplugExtension; +use Http\HttplugBundle\Tests\Resources\CustomPluginConfigurator; use Matthias\SymfonyDependencyInjectionTest\PhpUnit\AbstractExtensionTestCase; use Psr\Http\Client\ClientInterface; +use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\Reference; /** @@ -203,6 +205,40 @@ public function testClientPlugins(): void $this->assertContainerBuilderHasService('httplug.client.mock'); } + public function testPluginConfiguratorConfig(): void + { + $config = [ + 'clients' => [ + 'acme' => [ + 'factory' => 'httplug.factory.curl', + 'plugins' => [ + [ + 'configurator' => [ + 'id' => CustomPluginConfigurator::class, + 'config' => [ + 'name' => 'foo', + ], + ], + ], + ], + ], + ], + ]; + + $this->load($config); + + $definition = new Definition(null, [ + ['name' => 'foo'], + ]); + $definition->setFactory([CustomPluginConfigurator::class, 'create']); + + $this->assertContainerBuilderHasService('httplug.client.acme'); + $this->assertContainerBuilderHasServiceDefinitionWithArgument('httplug.client.acme', 1, [ + $definition, + ]); + $this->assertContainerBuilderHasService('httplug.client.mock'); + } + public function testNoProfilingWhenNotInDebugMode(): void { $this->setParameter('kernel.debug', false);