You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

200 lines
5.0 KiB

<?php
namespace Github\HttpClient;
use Http\Client\Common\HttpMethodsClient;
use Http\Client\Common\Plugin;
use Http\Client\Common\Plugin\Cache\Generator\HeaderCacheKeyGenerator;
use Http\Client\Common\PluginClientFactory;
use Http\Client\HttpClient;
use Http\Discovery\HttpClientDiscovery;
use Http\Discovery\MessageFactoryDiscovery;
use Http\Discovery\StreamFactoryDiscovery;
use Http\Message\MessageFactory;
use Http\Message\RequestFactory;
use Http\Message\StreamFactory;
use Psr\Cache\CacheItemPoolInterface;
/**
* 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 HttpClient
*/
private $httpClient;
/**
* A HTTP client with all our plugins.
*
* @var HttpMethodsClient
*/
private $pluginClient;
/**
* @var MessageFactory
*/
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
*/
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;
}
}