diff --git a/src/Container.php b/src/Container.php index 8efcc0d..8aa7b42 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 @@ -30,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; @@ -38,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) @@ -77,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(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 = $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 db121fd..5bed3fa 100644 --- a/src/Http/PluginClientBuilder.php +++ b/src/Http/PluginClientBuilder.php @@ -1,50 +1,75 @@ + */ final class PluginClientBuilder { - /** @var Plugin[] */ - private $plugins; + /** @var Plugin[][] List of plugins ordered by priority [priority => Plugin[]]). */ + private $plugins = []; + + /** @var array Array of options to give to the plugin client */ + private $options = []; /** @var ?PluginClient */ - private $client; + private $client = null; - 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->plugins[$priority][] = $plugin; $this->client = null; + + return $this; } - public function removePlugin(string $name): void + /** @param mixed $value */ + public function addOption(string $name, $value): self { - unset($this->plugins[$name]); + $this->options[$name] = $value; $this->client = null; + + 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]); + $this->client = null; - return $this->plugins[$name]; + return $this; } - public function createClient($client, array $options = []): PluginClient + public function createClient(ClientInterface $httpClient): PluginClient { - if (null === $this->client) { - $this->client = new PluginClient( - $client, - array_values($this->plugins), - $options - ); + static $client; + + if ($client === $httpClient && $this->client !== null) { + return $this->client; + } + + $client = $httpClient; + $plugins = $this->plugins; + + if (0 === count($plugins)) { + $plugins[] = []; } - return $this->client; + krsort($plugins); + $plugins = array_merge(...$plugins); + + 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.+?)"$/ */