wishthis/vendor/knplabs/github-api/lib/Github/HttpClient/Builder.php
2022-01-21 09:23:52 +01:00

214 lines
5.5 KiB
PHP

<?php
namespace Github\HttpClient;
use Http\Client\Common\HttpMethodsClient;
use Http\Client\Common\HttpMethodsClientInterface;
use Http\Client\Common\Plugin;
use Http\Client\Common\Plugin\Cache\Generator\HeaderCacheKeyGenerator;
use Http\Client\Common\PluginClientFactory;
use Http\Discovery\Psr17FactoryDiscovery;
use Http\Discovery\Psr18ClientDiscovery;
use Psr\Cache\CacheItemPoolInterface;
use Psr\Http\Client\ClientInterface;
use Psr\Http\Message\RequestFactoryInterface;
use Psr\Http\Message\StreamFactoryInterface;
/**
* A builder that builds the API client.
* This will allow you to fluently add and remove plugins.
*
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
*/
class Builder
{
/**
* The object that sends HTTP messages.
*
* @var ClientInterface
*/
private $httpClient;
/**
* A HTTP client with all our plugins.
*
* @var HttpMethodsClientInterface
*/
private $pluginClient;
/**
* @var RequestFactoryInterface
*/
private $requestFactory;
/**
* @var StreamFactoryInterface
*/
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 ClientInterface|null $httpClient
* @param RequestFactoryInterface|null $requestFactory
* @param StreamFactoryInterface|null $streamFactory
*/
public function __construct(
ClientInterface $httpClient = null,
RequestFactoryInterface $requestFactory = null,
StreamFactoryInterface $streamFactory = null
) {
$this->httpClient = $httpClient ?? Psr18ClientDiscovery::find();
$this->requestFactory = $requestFactory ?? Psr17FactoryDiscovery::findRequestFactory();
$this->streamFactory = $streamFactory ?? Psr17FactoryDiscovery::findStreamFactory();
}
/**
* @return HttpMethodsClientInterface
*/
public function getHttpClient(): HttpMethodsClientInterface
{
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,
$this->streamFactory
);
}
return $this->pluginClient;
}
/**
* Add a new plugin to the end of the plugin chain.
*
* @param Plugin $plugin
*
* @return void
*/
public function addPlugin(Plugin $plugin): void
{
$this->plugins[] = $plugin;
$this->httpClientModified = true;
}
/**
* Remove a plugin by its fully qualified class name (FQCN).
*
* @param string $fqcn
*
* @return void
*/
public function removePlugin(string $fqcn): void
{
foreach ($this->plugins as $idx => $plugin) {
if ($plugin instanceof $fqcn) {
unset($this->plugins[$idx]);
$this->httpClientModified = true;
}
}
}
/**
* Clears used headers.
*
* @return void
*/
public function clearHeaders(): void
{
$this->headers = [];
$this->removePlugin(Plugin\HeaderAppendPlugin::class);
$this->addPlugin(new Plugin\HeaderAppendPlugin($this->headers));
}
/**
* @param array $headers
*
* @return void
*/
public function addHeaders(array $headers): void
{
$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
*
* @return void
*/
public function addHeaderValue(string $header, string $headerValue): void
{
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
*
* @return void
*/
public function addCache(CacheItemPoolInterface $cachePool, array $config = []): void
{
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.
*
* @return void
*/
public function removeCache(): void
{
$this->cachePlugin = null;
$this->httpClientModified = true;
}
}