View source
<?php
namespace Drupal\http_client_manager;
use Drupal\Component\Discovery\YamlDiscovery;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Extension\ModuleHandler;
use Drupal\Core\Site\Settings;
use Drupal\Core\StringTranslation\TranslationManager;
use Drupal\Core\Controller\ControllerResolver;
class HttpServiceApiHandler implements HttpServiceApiHandlerInterface {
const REQUIRED_PROPERTY = TRUE;
protected $root;
protected $moduleHandler;
protected $stringTranslation;
protected $controllerResolver;
protected $servicesApi;
protected $config;
public function __construct($root, ModuleHandler $module_handler, TranslationManager $string_translation, ControllerResolver $controller_resolver, ConfigFactoryInterface $config_factory) {
$this->root = $root;
$this->moduleHandler = $module_handler;
$this->stringTranslation = $string_translation;
$this->controllerResolver = $controller_resolver;
$this->config = $config_factory
->get('http_client_manager.settings');
$this->servicesApi = $this
->getServicesApi();
}
protected function getYamlDiscovery() {
if (!isset($this->yamlDiscovery)) {
$this->yamlDiscovery = new YamlDiscovery('http_services_api', $this->moduleHandler
->getModuleDirectories());
}
return $this->yamlDiscovery;
}
public function getServicesApi() {
if (empty($this->servicesApi)) {
$this
->buildServicesApiYaml();
}
return $this->servicesApi;
}
public function load($id) {
if (empty($this->servicesApi[$id])) {
$message = sprintf('Undefined Http Service Api id "%s"', $id);
throw new \InvalidArgumentException($message);
}
return $this->servicesApi[$id];
}
public function moduleProvidesApi($module_name) {
$servicesApi = $this
->getServicesApi();
foreach ($servicesApi as $serviceApi) {
if ($serviceApi['provider'] == $module_name) {
return TRUE;
}
}
return FALSE;
}
protected function buildServicesApiYaml() {
$this->servicesApi = [];
$items = $this
->getYamlDiscovery()
->findAll();
$extensions = [];
foreach ($items as $provider => $servicesApi) {
$module_path = $this->moduleHandler
->getModule($provider)
->getPath();
foreach ($servicesApi as $id => $serviceApi) {
if (!empty($serviceApi['parent'])) {
$serviceApi['id'] = $id;
$serviceApi['provider'] = $provider;
$serviceApi['source'] = $this->root . '/' . $module_path . '/' . $serviceApi['api_path'];
$extensions[] = $serviceApi;
continue;
}
$this
->overrideServiceApiDefinition($id, $serviceApi);
$this
->validateServiceApiDefinition($id, $serviceApi);
$default = [
'id' => $id,
'provider' => $provider,
'source' => $this->root . '/' . $module_path . '/' . $serviceApi['api_path'],
'config' => [],
];
$serviceApi = array_merge($default, $serviceApi);
if (!empty($serviceApi[$id]['orig'])) {
$serviceApi[$id]['orig'] = array_merge($default, $serviceApi[$id]['orig']);
}
$this->servicesApi[$id] = $serviceApi;
}
}
foreach ($extensions as $serviceApi) {
$id = $serviceApi['id'];
$parent = $this
->load($serviceApi['parent']);
$serviceApi = $serviceApi + $parent;
$serviceApi['parent_title'] = $parent['title'];
$this
->overrideServiceApiDefinition($id, $serviceApi);
$this
->validateServiceApiDefinition($id, $serviceApi);
$this->servicesApi[$id] = $serviceApi;
}
}
protected function overrideServiceApiDefinition($id, array &$serviceApi) {
if (!$this->config
->get('enable_overriding_service_definitions')) {
return;
}
$original = $serviceApi;
$overridden = FALSE;
$overridable_properties = self::getOverridableProperties();
$config_overrides = $this->config
->get('overrides');
if (!empty($config_overrides[$id])) {
$settings[$id] = array_intersect_key($config_overrides[$id], $overridable_properties);
$serviceApi = array_replace_recursive($serviceApi, $config_overrides[$id]);
$overridden = TRUE;
}
$settings = Settings::get('http_services_api', []);
if (!empty($settings[$id])) {
$settings[$id] = array_intersect_key($settings[$id], $overridable_properties);
$serviceApi = array_replace_recursive($serviceApi, $settings[$id]);
$overridden = TRUE;
}
if (!empty($serviceApi['commands'])) {
$serviceApi['orig'] = $original;
}
if ($overridden) {
$serviceApi['_original'] = $original;
}
}
public static function getOverridableProperties() {
return [
'title' => self::REQUIRED_PROPERTY,
'api_path' => self::REQUIRED_PROPERTY,
'config' => self::REQUIRED_PROPERTY,
'commands' => !self::REQUIRED_PROPERTY,
];
}
protected function validateServiceApiDefinition($id, array $serviceApi) {
foreach (self::getOverridableProperties() as $property => $isRequired) {
if ($isRequired && !isset($serviceApi[$property])) {
$message = sprintf('Missing required parameter "%s" in "%s" service api definition', $property, $id);
throw new \RuntimeException($message);
}
}
if (!empty($serviceApi['commands']['blacklist']) && !empty($serviceApi['commands']['whitelist'])) {
$message = sprintf('You cannot specify both "blacklist" and "whitelist" parameters in "%s" service api definition', $id);
throw new \RuntimeException($message);
}
}
protected function getModuleNames() {
$modules = [];
foreach (array_keys($this->moduleHandler
->getModuleList()) as $module) {
$modules[$module] = $this->moduleHandler
->getName($module);
}
asort($modules);
return $modules;
}
}