214 lines
5.5 KiB
PHP
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;
|
|
}
|
|
}
|