View source
<?php
namespace Drupal\http_client_manager;
use Drupal\Core\Messenger\MessengerTrait;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\http_client_manager\Event\HttpClientEvents;
use Drupal\http_client_manager\Event\HttpClientHandlerStackEvent;
use Guzzle\Service\Loader\JsonLoader;
use Guzzle\Service\Loader\PhpLoader;
use Guzzle\Service\Loader\YamlLoader;
use GuzzleHttp\Client;
use GuzzleHttp\Command\Guzzle\Description;
use GuzzleHttp\Command\Guzzle\GuzzleClient;
use GuzzleHttp\HandlerStack;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
class HttpClient implements HttpClientInterface {
use StringTranslationTrait;
use MessengerTrait;
protected $serviceApi;
protected $description;
protected $apiHandler;
protected $api;
protected $apiSourceInfo;
protected $client;
protected $eventDispatcher;
protected $commands;
protected $fileLocator;
protected $fileLoader;
public function __construct($serviceApi, HttpServiceApiHandlerInterface $apiHandler, EventDispatcherInterface $event_dispatcher) {
$this->serviceApi = $serviceApi;
$this->apiHandler = $apiHandler;
$this->api = $this->apiHandler
->load($this->serviceApi);
$this->eventDispatcher = $event_dispatcher;
}
public function getApi() {
return $this->api;
}
protected function getApiSourceInfo() {
if (empty($this->apiSourceInfo)) {
$this
->setApiSourceInfo();
}
return $this->apiSourceInfo;
}
protected function setApiSourceInfo() {
$this->apiSourceInfo = pathinfo($this->api['source']);
}
protected function getClient() {
if (empty($this->client)) {
$this
->setupGuzzleClient();
}
return $this->client;
}
protected function getClientByCommand($commandName) {
$api = $this
->getApi();
if (empty($api['orig']) || empty($api['commands'])) {
return $this
->getClient();
}
$cmds = $api['commands'];
$config = $api['config'];
if (!empty($cmds['blacklist']) && in_array($commandName, $cmds['blacklist']) || !empty($cmds['whitelist']) && !in_array($commandName, $cmds['whitelist'])) {
$config = $api['orig']['config'];
$config['handler'] = $this
->getClientConfig()['handler'];
}
$this->client = $this
->createGuzzleClient($config);
return $this->client;
}
private function setupGuzzleClient() {
$config = $this
->getClientConfig();
$this->client = $this
->createGuzzleClient($config);
}
private function createGuzzleClient(array $config) {
$client = new Client($config);
return new GuzzleClient($client, $this
->loadServiceDescription($config));
}
public function getClientConfig() {
$api = $this
->getApi();
$config = !empty($api['config']) ? $api['config'] : [];
$config['handler'] = HandlerStack::create();
if (isset($config['debug']) && !is_bool($config['debug'])) {
if ($debug_file = fopen($config['debug'], FILE_APPEND)) {
$config['debug'] = $debug_file;
}
else {
$message = $this
->t('HTTP Client Manager was unable to write to debug log file: @file', [
'@file' => $config['debug'],
]);
$this
->messenger()
->addWarning($message);
$config['debug'] = FALSE;
}
}
$event = new HttpClientHandlerStackEvent($config['handler'], $this->serviceApi);
$this->eventDispatcher
->dispatch(HttpClientEvents::HANDLER_STACK, $event);
return $config;
}
protected function loadServiceDescription($config) {
$base_uri = $config['base_uri'];
if (empty($this->description[$base_uri])) {
$source = $this
->getApiSourceInfo();
$loader = $this
->getFileLoader();
$locator = $this
->getFileLocator();
$description = $loader
->load($locator
->locate($source['basename']));
$description['baseUrl'] = $base_uri;
$this->description[$base_uri] = new Description($description);
}
return $this->description[$base_uri];
}
protected function getFileLocator() {
if (empty($this->fileLocator)) {
$this
->initFileLocator();
}
return $this->fileLocator;
}
protected function initFileLocator() {
$source = $this
->getApiSourceInfo();
$this->fileLocator = new FileLocator($source['dirname']);
}
protected function getFileLoader() {
if (empty($this->fileLoader)) {
$this
->initFileLoader();
}
return $this->fileLoader;
}
protected function initFileLoader() {
$source = $this
->getApiSourceInfo();
$locator = $this
->getFileLocator();
switch ($source['extension']) {
case 'json':
$loader = new JsonLoader($locator);
break;
case 'yml':
$loader = new YamlLoader($locator);
break;
case 'php':
$loader = new PhpLoader($locator);
break;
default:
$allowed_extensions = [
'json',
'yml',
'php',
];
$message = sprintf('Invalid HTTP Services Api source provided: "%s". ', $source['filename']);
$message .= sprintf('File extension must be one of %s.', implode(', ', $allowed_extensions));
throw new \RuntimeException($message);
}
$this->fileLoader = $loader;
}
public function getCommands() {
if (!empty($this->commands)) {
return $this->commands;
}
$description = $this
->getClient()
->getDescription();
$command_names = array_keys($description
->getOperations());
$this->commands = [];
foreach ($command_names as $command_name) {
$this->commands[$command_name] = $description
->getOperation($command_name);
}
return $this->commands;
}
public function getCommand($commandName) {
if (!empty($this->commands[$commandName])) {
return $this->commands[$commandName];
}
return $this
->getClient()
->getDescription()
->getOperation($commandName);
}
public function call($commandName, array $params = []) {
$client = $this
->getClientByCommand($commandName);
$command = $client
->getCommand($commandName, $params);
return $client
->execute($command);
}
public function __call($name, array $arguments = []) {
$params = !empty($arguments[0]) ? $arguments[0] : [];
return $this
->call($name, $params);
}
}