*/ class Builder { /** * The object that sends HTTP messages. * * @var HttpClient */ private $httpClient; /** * A HTTP client with all our plugins. * * @var HttpMethodsClient */ private $pluginClient; /** * @var RequestFactory */ private $requestFactory; /** * @var StreamFactory */ private $streamFactory; /** * True if we should create a new Plugin client at next request. * * @var bool */ private $httpClientModified = true; /** * @var Plugin[] */ private $plugins = []; /** * This plugin is special treated because it has to be the very last plugin. * * @var Plugin\CachePlugin|null */ private $cachePlugin; /** * Http headers. * * @var array */ private $headers = []; /** * @param HttpClient $httpClient * @param RequestFactory $requestFactory * @param StreamFactory $streamFactory */ public function __construct( HttpClient $httpClient = null, RequestFactory $requestFactory = null, StreamFactory $streamFactory = null ) { $this->httpClient = $httpClient ?: HttpClientDiscovery::find(); $this->requestFactory = $requestFactory ?: MessageFactoryDiscovery::find(); $this->streamFactory = $streamFactory ?: StreamFactoryDiscovery::find(); } /** * @return HttpMethodsClient */ public function getHttpClient() { if ($this->httpClientModified) { $this->httpClientModified = false; $plugins = $this->plugins; if ($this->cachePlugin) { $plugins[] = $this->cachePlugin; } $this->pluginClient = new HttpMethodsClient( (new PluginClientFactory())->createClient($this->httpClient, $plugins), $this->requestFactory ); } return $this->pluginClient; } /** * Add a new plugin to the end of the plugin chain. * * @param Plugin $plugin */ public function addPlugin(Plugin $plugin) { $this->plugins[] = $plugin; $this->httpClientModified = true; } /** * Remove a plugin by its fully qualified class name (FQCN). * * @param string $fqcn */ public function removePlugin($fqcn) { foreach ($this->plugins as $idx => $plugin) { if ($plugin instanceof $fqcn) { unset($this->plugins[$idx]); $this->httpClientModified = true; } } } /** * Clears used headers. */ public function clearHeaders() { $this->headers = []; $this->removePlugin(Plugin\HeaderAppendPlugin::class); $this->addPlugin(new Plugin\HeaderAppendPlugin($this->headers)); } /** * @param array $headers */ public function addHeaders(array $headers) { $this->headers = array_merge($this->headers, $headers); $this->removePlugin(Plugin\HeaderAppendPlugin::class); $this->addPlugin(new Plugin\HeaderAppendPlugin($this->headers)); } /** * @param string $header * @param string $headerValue */ public function addHeaderValue($header, $headerValue) { if (!isset($this->headers[$header])) { $this->headers[$header] = $headerValue; } else { $this->headers[$header] = array_merge((array) $this->headers[$header], [$headerValue]); } $this->removePlugin(Plugin\HeaderAppendPlugin::class); $this->addPlugin(new Plugin\HeaderAppendPlugin($this->headers)); } /** * Add a cache plugin to cache responses locally. * * @param CacheItemPoolInterface $cachePool * @param array $config */ public function addCache(CacheItemPoolInterface $cachePool, array $config = []) { if (!isset($config['cache_key_generator'])) { $config['cache_key_generator'] = new HeaderCacheKeyGenerator(['Authorization', 'Cookie', 'Accept', 'Content-type']); } $this->cachePlugin = Plugin\CachePlugin::clientCache($cachePool, $this->streamFactory, $config); $this->httpClientModified = true; } /** * Remove the cache plugin. */ public function removeCache() { $this->cachePlugin = null; $this->httpClientModified = true; } }