acquia_dam-1.0.0-rc1/src/Client/AcquiaDamClientFactory.php
src/Client/AcquiaDamClientFactory.php
<?php namespace Drupal\acquia_dam\Client; use Drupal\acquia_dam\AcquiadamAuthService; use Drupal\Component\Datetime\TimeInterface; use Drupal\Core\Cache\CacheBackendInterface; use Drupal\Core\Config\ConfigFactoryInterface; use Drupal\Core\Extension\ModuleExtensionList; use Drupal\Core\Logger\LoggerChannelInterface; use Drupal\Core\Session\AccountProxyInterface; use GuzzleHttp\HandlerStack; use GuzzleHttp\Middleware; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; /** * Instantiates an Acquia DAM Client object. */ class AcquiaDamClientFactory { /** * The handler stack. * * @var \GuzzleHttp\HandlerStack */ protected $stack; /** * The module extension list. * * @var \Drupal\Core\Extension\ModuleExtensionList */ protected $moduleList; /** * The cache backend. * * @var \Drupal\Core\Cache\CacheBackendInterface */ private $cacheBackend; /** * DAM auth service. * * @var \Drupal\acquia_dam\AcquiadamAuthService */ protected $authService; /** * Current user. * * @var \Drupal\Core\Session\AccountProxyInterface */ protected $currentUser; /** * Acquia DAM logger channel. * * @var \Drupal\Core\Logger\LoggerChannelInterface */ protected $damLoggerChannel; /** * The time service. * * @var \Drupal\Component\Datetime\TimeInterface */ protected $time; /** * Config factory. * * @var \Drupal\Core\Config\ConfigFactoryInterface */ protected $configFactory; /** * AcquiaDamClientFactory constructor. * * @param \GuzzleHttp\HandlerStack $stack * Handler stack. * @param \Drupal\Core\Extension\ModuleExtensionList $module_list * Module list service. * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend * Cache backend. * @param \Drupal\acquia_dam\AcquiadamAuthService $authService * User data service. * @param \Drupal\Core\Session\AccountProxyInterface $currentUser * Current user. * @param \Drupal\Core\Logger\LoggerChannelInterface $loggerChannel * Acquia DAM logger channel. * @param \Drupal\Component\Datetime\TimeInterface $time * The time service. * @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory * Config factory. */ public function __construct(HandlerStack $stack, ModuleExtensionList $module_list, CacheBackendInterface $cache_backend, AcquiadamAuthService $authService, AccountProxyInterface $currentUser, LoggerChannelInterface $loggerChannel, TimeInterface $time, ConfigFactoryInterface $configFactory) { $this->stack = $stack; $this->moduleList = $module_list; $this->cacheBackend = $cache_backend; $this->authService = $authService; $this->currentUser = $currentUser; $this->damLoggerChannel = $loggerChannel; $this->time = $time; $this->configFactory = $configFactory; } /** * Returns a AcquiaDamClient instance using site token. * * @return \Drupal\acquia_dam\Client\AcquiaDamClient * DAM client. */ public function getSiteClient(): AcquiaDamClient { return $this->getClient(TRUE); } /** * Returns a AcquiaDamClient instance using the current user token. * * @return \Drupal\acquia_dam\Client\AcquiaDamClient * DAM client. */ public function getUserClient(): AcquiaDamClient { return $this->getClient(FALSE); } /** * Returns a AcquiaDamClient instance. * * @param bool $is_site_client * Parameter which tells to get a site or a user client. * * @return \Drupal\acquia_dam\Client\AcquiaDamClient * Client instance. */ protected function getClient(bool $is_site_client): AcquiaDamClient { $acquia_dam_config = $this->configFactory->get('acquia_dam.settings'); $stack = clone $this->stack; // Middleware to attach Authorization header with access token. $stack->after('prepare_body', Middleware::mapRequest(function (RequestInterface $request) use ($is_site_client) { $access_token = $this->getClientAccessToken($is_site_client); if (isset($access_token)) { return $request->withHeader('Authorization', 'Bearer ' . $access_token); } return $request; })); // Middleware to handle refresh tokens if access token was not accepted. if ($this->authService->isUsingRefreshToken()) { $stack->after('prepare_body', function (callable $next) use ($is_site_client) { return function (RequestInterface $request, array $options = []) use ($next, $is_site_client) { $access_token = $this->getClientAccessToken($is_site_client); if (!isset($access_token)) { return $next($request, $options); } if (!isset($options['retries'])) { $options['retries'] = 0; } return $next($request, $options)->then( function ($value) use ($next, $request, $options, $is_site_client) { if ($options['retries'] > 0) { return $value; } if (!$value instanceof ResponseInterface) { return $value; } if ($value->getStatusCode() !== 401) { return $value; } // Only pass user id if we want to refresh the user access token. $user_id = $is_site_client ? NULL : $this->currentUser->id(); $refresh_token = $is_site_client ? $this->authService->getRefreshToken() : $this->authService->getUserRefreshToken($user_id); $this->authService->refreshAccessToken($refresh_token, $user_id); return $next($request, $options); }, ); }; }); } $config = [ 'base_uri' => 'https://api.widencollective.com', 'client-user-agent' => $this->getClientUserAgent(), 'headers' => [ 'Content-Type' => 'application/json', ], 'handler' => $stack, ]; return new AcquiaDamClient($this->cacheBackend, $this->time, $acquia_dam_config, $config, $this->damLoggerChannel); } /** * Returns Client's user agent. * * @return string * User Agent. */ protected function getClientUserAgent(): string { // Find out the module version in use. $module_info = $this->moduleList->getExtensionInfo('acquia_dam'); $module_version = $module_info['version'] ?? '0.0.0'; $drupal_version = \Drupal::VERSION; return 'AcquiaDam/' . $drupal_version . '-' . $module_version; } /** * Returns access token. * * @param bool $is_site_client * Token for site or user. * * @return string|null * Token. * * @throws \Exception * Throws exception if it cannot get an access token. */ protected function getClientAccessToken(bool $is_site_client): ?string { return $is_site_client ? $this->authService->getSiteToken() : $this->authService->getUserAccessToken($this->currentUser->id()); } }