From 636e9d8cd2cbe913bc55a7c956dcfe5c35a8809b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Baptiste=20Clavi=C3=A9?= Date: Wed, 5 Feb 2020 11:48:34 +0100 Subject: [PATCH 1/2] Port the new PluginClientBuilder into Behapi MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit By yours, truly. 😂 Waiting for a proper release from client-common though. --- src/Container.php | 8 ++--- src/Http/PluginClientBuilder.php | 62 +++++++++++++++++++------------- 2 files changed, 40 insertions(+), 30 deletions(-) diff --git a/src/Container.php b/src/Container.php index 8efcc0d..86cac71 100644 --- a/src/Container.php +++ b/src/Container.php @@ -17,9 +17,7 @@ use Psr\Http\Message\RequestFactoryInterface; use Psr\Http\Message\StreamFactoryInterface; -use function bin2hex; use function in_array; -use function random_bytes; use function array_key_exists; final class Container implements ContainerInterface @@ -78,9 +76,9 @@ private function getPluginClientBuilder(): PluginClientBuilder assert($this->services[HttpHistory::class] instanceof HttpHistory); // use randomized strings so that these cannot be removed (safety) - $builder->addPlugin(bin2hex(random_bytes(10)), new ContentLengthPlugin); - $builder->addPlugin(bin2hex(random_bytes(10)), new BaseUriPlugin($baseUri)); - $builder->addPlugin(bin2hex(random_bytes(10)), new HistoryPlugin($this->services[HttpHistory::class])); + $builder->addPlugin(new ContentLengthPlugin); + $builder->addPlugin(new BaseUriPlugin($baseUri)); + $builder->addPlugin(new HistoryPlugin($this->services[HttpHistory::class])); return $builder; } diff --git a/src/Http/PluginClientBuilder.php b/src/Http/PluginClientBuilder.php index db121fd..2158333 100644 --- a/src/Http/PluginClientBuilder.php +++ b/src/Http/PluginClientBuilder.php @@ -1,50 +1,62 @@ + */ final class PluginClientBuilder { - /** @var Plugin[] */ - private $plugins; + /** @var Plugin[][] List of plugins ordered by priority [priority => Plugin[]]). */ + private $plugins = []; - /** @var ?PluginClient */ - private $client; + /** @var array Array of options to give to the plugin client */ + private $options = []; - public function addPlugin(string $name, Plugin $plugin): void + /** @param int $priority Priority of the plugin. The higher comes first. */ + public function addPlugin(Plugin $plugin, int $priority = 0): self { - $this->plugins[$name] = $plugin; - $this->client = null; + $this->plugins[$priority][] = $plugin; + + return $this; } - public function removePlugin(string $name): void + /** @param mixed $value */ + public function setOption(string $name, $value): self { - unset($this->plugins[$name]); - $this->client = null; + $this->options[$name] = $value; + + return $this; } - public function getPlugin(string $name): Plugin + public function removeOption(string $name): self { - if (!isset($this->plugins[$name])) { - throw new PluginNotFound($name); - } + unset($this->options[$name]); - return $this->plugins[$name]; + return $this; } - public function createClient($client, array $options = []): PluginClient + public function createClient(ClientInterface $client): PluginClient { - if (null === $this->client) { - $this->client = new PluginClient( - $client, - array_values($this->plugins), - $options - ); + $plugins = $this->plugins; + + if (0 === count($plugins)) { + $plugins[] = []; } - return $this->client; + krsort($plugins); + $plugins = array_merge(...$plugins); + + return new PluginClient( + $client, + array_values($plugins), + $this->options + ); } } From f53b4c9365a2a7005af09d5d6334dc2a4f5b9579 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Baptiste=20Clavi=C3=A9?= Date: Wed, 5 Feb 2020 14:39:16 +0100 Subject: [PATCH 2/2] Add cache capabilities to PluginClientBuilder --- src/Container.php | 23 +++++++++++------------ src/Http/PluginClientBuilder.php | 21 +++++++++++++++++---- src/Http/RequestContext.php | 4 ++-- 3 files changed, 30 insertions(+), 18 deletions(-) diff --git a/src/Container.php b/src/Container.php index 86cac71..8aa7b42 100644 --- a/src/Container.php +++ b/src/Container.php @@ -28,6 +28,13 @@ final class Container implements ContainerInterface /** @var string BaseURL for api requests */ private $baseUrl; + private const SERVICES = [ + HttpHistory::class, + PluginClientBuilder::class, + StreamFactoryInterface::class, + RequestFactoryInterface::class, + ]; + public function __construct(HttpHistory $history, string $baseUrl) { $this->baseUrl = $baseUrl; @@ -36,14 +43,7 @@ public function __construct(HttpHistory $history, string $baseUrl) public function has($id) { - static $services = [ - HttpHistory::class, - PluginClientBuilder::class, - StreamFactoryInterface::class, - RequestFactoryInterface::class, - ]; - - return in_array($id, $services, true); + return in_array($id, self::SERVICES, true); } public function get($id) @@ -75,10 +75,9 @@ private function getPluginClientBuilder(): PluginClientBuilder assert($this->services[HttpHistory::class] instanceof HttpHistory); - // use randomized strings so that these cannot be removed (safety) - $builder->addPlugin(new ContentLengthPlugin); - $builder->addPlugin(new BaseUriPlugin($baseUri)); - $builder->addPlugin(new HistoryPlugin($this->services[HttpHistory::class])); + $builder = $builder->addPlugin(new ContentLengthPlugin); + $builder = $builder->addPlugin(new BaseUriPlugin($baseUri)); + $builder = $builder->addPlugin(new HistoryPlugin($this->services[HttpHistory::class])); return $builder; } diff --git a/src/Http/PluginClientBuilder.php b/src/Http/PluginClientBuilder.php index 2158333..5bed3fa 100644 --- a/src/Http/PluginClientBuilder.php +++ b/src/Http/PluginClientBuilder.php @@ -19,18 +19,23 @@ final class PluginClientBuilder /** @var array Array of options to give to the plugin client */ private $options = []; + /** @var ?PluginClient */ + private $client = null; + /** @param int $priority Priority of the plugin. The higher comes first. */ public function addPlugin(Plugin $plugin, int $priority = 0): self { $this->plugins[$priority][] = $plugin; + $this->client = null; return $this; } /** @param mixed $value */ - public function setOption(string $name, $value): self + public function addOption(string $name, $value): self { $this->options[$name] = $value; + $this->client = null; return $this; } @@ -38,12 +43,20 @@ public function setOption(string $name, $value): self public function removeOption(string $name): self { unset($this->options[$name]); + $this->client = null; return $this; } - public function createClient(ClientInterface $client): PluginClient + public function createClient(ClientInterface $httpClient): PluginClient { + static $client; + + if ($client === $httpClient && $this->client !== null) { + return $this->client; + } + + $client = $httpClient; $plugins = $this->plugins; if (0 === count($plugins)) { @@ -53,8 +66,8 @@ public function createClient(ClientInterface $client): PluginClient krsort($plugins); $plugins = array_merge(...$plugins); - return new PluginClient( - $client, + return $this->client = new PluginClient( + $httpClient, array_values($plugins), $this->options ); diff --git a/src/Http/RequestContext.php b/src/Http/RequestContext.php index d36d667..c6c927f 100644 --- a/src/Http/RequestContext.php +++ b/src/Http/RequestContext.php @@ -11,7 +11,7 @@ use Behat\Behat\Context\Context; use Behat\Gherkin\Node\TableNode; -use Http\Discovery\HttpClientDiscovery; +use Http\Discovery\Psr18ClientDiscovery; use function trim; use function is_array; @@ -43,7 +43,7 @@ public function __construct(PluginClientBuilder $builder, StreamFactoryInterface $this->streamFactory = $streamFactory; $this->requestFactory = $requestFactory; - $this->client = HttpClientDiscovery::find(); + $this->client = Psr18ClientDiscovery::find(); } /** @When /^I create a "(?PGET|POST|PATCH|PUT|DELETE|OPTIONS|HEAD)" request to "(?P.+?)"$/ */