acquia_perz-4.0.0-rc1/src/ClientFactory.php

src/ClientFactory.php
<?php

namespace Drupal\acquia_perz;

use Acquia\Hmac\Exception\KeyNotFoundException;
use Acquia\Hmac\KeyInterface;
use Acquia\Hmac\KeyLoader;
use Acquia\Hmac\RequestAuthenticator;
use Acquia\Hmac\ResponseSigner;
use Acquia\PerzApiPhp\ObjectFactory;
use Acquia\PerzApiPhp\PerzApiPhpClient;
use Drupal\acquia_connector\Subscription;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Extension\ModuleExtensionList;
use Drupal\Core\Logger\LoggerChannelFactoryInterface;
use Drupal\Core\State\StateInterface;
use Psr\Http\Message\ResponseInterface;
use Symfony\Bridge\PsrHttpMessage\HttpFoundationFactoryInterface;
use Symfony\Bridge\PsrHttpMessage\HttpMessageFactoryInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\HttpKernelInterface;

/**
 * Instantiates an Acquia PerzPhp Client object.
 *
 * @see \Acquia\PerzApiPhp
 */
class ClientFactory {

  /**
   * The state service.
   *
   * @var \Drupal\Core\State\StateInterface
   */
  protected $state;

  /**
   * The config factory service.
   *
   * @var \Drupal\Core\Config\ConfigFactoryInterface
   */
  protected $configFactory;

  /**
   * Logger Factory.
   *
   * @var \Drupal\Core\Logger\LoggerChannelFactoryInterface
   */
  protected $loggerFactory;

  /**
   * The module extension list.
   *
   * @var \Drupal\Core\Extension\ModuleExtensionList
   */
  protected $moduleList;

  /**
   * The HTTP kernel service.
   *
   * @var \Symfony\Component\HttpKernel\HttpKernelInterface
   */
  protected $httpKernel;

  /**
   * Acquia Perz subscription data.
   *
   * @var array
   */
  protected $subscription = [];

  /**
   * The PSR-7 converter.
   *
   * @var \Symfony\Bridge\PsrHttpMessage\HttpMessageFactoryInterface
   */
  protected $httpMessageFactory;

  /**
   * The httpFoundation factory.
   *
   * @var \Symfony\Bridge\PsrHttpMessage\HttpFoundationFactoryInterface
   */
  protected $httpFoundationFactory;

  /**
   * ClientManagerFactory constructor.
   *
   * @param \Drupal\Core\State\StateInterface $state
   *   The state store.
   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
   *   The Config Factory.
   * @param \Drupal\Core\Logger\LoggerChannelFactoryInterface $logger_factory
   *   The logger factory.
   * @param \Drupal\Core\Extension\ModuleExtensionList $module_list
   *   The module extension list.
   * @param \Symfony\Component\HttpKernel\HttpKernelInterface $http_kernel
   *   The wrapped HTTP kernel.
   * @param \Symfony\Bridge\PsrHttpMessage\HttpMessageFactoryInterface $http_message_factory
   *   The PSR-7 converter.
   * @param \Symfony\Bridge\PsrHttpMessage\HttpFoundationFactoryInterface $http_foundation_factory
   *   The httpFoundation factory.
   * @param \Drupal\acquia_connector\Subscription $subscription
   *   Acquia Subscription.
   */
  public function __construct(StateInterface $state, ConfigFactoryInterface $config_factory, LoggerChannelFactoryInterface $logger_factory, ModuleExtensionList $module_list, HttpKernelInterface $http_kernel, HttpMessageFactoryInterface $http_message_factory, HttpFoundationFactoryInterface $http_foundation_factory, Subscription $subscription) {
    $this->state = $state;
    $this->configFactory = $config_factory;
    $this->loggerFactory = $logger_factory;
    $this->moduleList = $module_list;
    $this->httpKernel = $http_kernel;
    $this->httpMessageFactory = $http_message_factory;
    $this->httpFoundationFactory = $http_foundation_factory;
    $subscription_data = $subscription->getSubscription();
    if (isset($subscription_data['acquia_perz'])) {
      $this->subscription = $subscription_data['acquia_perz'];
    }
  }

  /**
   * Get PerzApiPhpClient.
   *
   * @return \Acquia\PerzApiPhp\PerzApiPhpClient|bool
   *   The PerzApiPhp Client
   */
  public function getClient(array $config = []): PerzApiPhpClient|bool {
    if (empty($this->subscription)) {
      throw new \Exception('Invalid Acquia Personalization Subscription.');
    }

    $base_uri = $config['base_url'] ?? $this->subscription['endpoint'];
    $client_user_agent = $config['client-user-agent'] ?? $this->getClientUserAgent();

    $key = ObjectFactory::getAuthenticationKey($this->subscription['api_key'], $this->subscription['secret_key']);
    $middleware = ObjectFactory::getHmacAuthMiddleware($key);
    $config = [
      'client-user-agent' => $client_user_agent,
      'base_url' => $base_uri,
    ];
    return new PerzApiPhpClient($middleware, $config);
  }

  /**
   * Get entities from Personalisation.
   *
   * @param array $data
   *   An array of Entity data.
   *   $data = [
   *     'account_id' => (string) Acquia Account ID. Required.
   *     'origin' => (string) Site hash. Required.
   *     'environment' => (string) Site environment. Required.
   *     'language' => (string) Entity Language. Optional.
   *     'view_mode' => (string) View mode of Entity. Optional.
   *     'q' => (string) Keywords to search. Optional.
   *     'content_type' => (string) Type of the Entity. Oprional.
   *     'tags' =>  (string) Tags to search, Optional.
   *     'all_tags' => (string) All tags to search. Optional.
   *     'date_start' => (datetime) Start date of Entity update. Optional.
   *     'date_end' => (datetime) End date of Entity update. Optional.
   *     'rows' => (integer) Number of rows in result. Default 10. Optional.
   *     'start' => (integer) Page start index. Default 0. Optional.
   *     'sort' => (string) Sort by field. Default modified. Optional.
   *     'sort_order' => (string) Sort order. Default desc. Optional.
   *     'site_hash' => (string) Site hash. Optional.
   *   ].
   *
   * @return mixed
   *   Response.
   *
   * @throws \GuzzleHttp\Exception\GuzzleException
   *   Guzzle Exception.
   */
  public function getEntities(array $data): mixed {
    $client = $this->getClient();
    $response = $client->getEntities($data);
    return json_decode($response->getBody()->getContents());
  }

  /**
   * Push entity to Personalization.
   *
   * @param array $data
   *   An array of Entity data.
   *   $data = [
   *     'account_id' => (string) Acquia Account ID. Required.
   *     'origin' => (string) Site hash. Required.
   *     'environment' => (string) Site environment. Required.
   *     'domain' => (string) Domain of the site. Required.
   *     'op' => (string) View mode of the entity. Required.
   *     'entity_type_id' => (string) Entity Type,
   *     'entity_uuid' => (string) Entity uuid,
   *     'site_hash' => (string) Site hash. Optional.
   *   ].
   *
   * @return \Psr\Http\Message\ResponseInterface|null
   *   Response.
   *
   * @throws \GuzzleHttp\Exception\GuzzleException
   *   Guzzle Exception.
   */
  public function pushEntity(array $data): ResponseInterface|null {
    $client = $this->getClient();
    return $client->pushEntity($data);
  }

  /**
   * Put entity to Personalization.
   *
   * @param array $data
   *   An array of Entity data.
   *   $data = [
   *     'account_id' => (string) Acquia Account ID. Required.
   *     'origin' => (string) Site hash. Required.
   *     'environment' => (string) Site envireonment. Required.
   *     'entity_variations' => (array) Entity variation data. Required.
   *     'site_hash' => (string) Site hash. Optional.
   *   ].
   *
   * @return \Psr\Http\Message\ResponseInterface|null
   *   Response.
   *
   * @throws \GuzzleHttp\Exception\GuzzleException
   *   Guzzle Exception.
   */
  public function putVariations(array $data): ResponseInterface|null {
    $client = $this->getClient();
    return $client->putVariations($data);
  }

  /**
   * Delete entities from Personalization.
   *
   * @param array $data
   *   An array of Entity data.
   *   $data = [
   *     'account_id' => (string) Acquia Account ID. Required.
   *     'origin' => (string) Site hash. Required.
   *     'environment' => (string) Site environment. Required.
   *     'content_uuid' => (string) UUID of the entity. Optional.
   *     'language' => (string) UUID of the entity. Optional.
   *     'view_mode' => (string) UUID of the entity. Optional.
   *     'site_hash' => (string) Site hash. Optional. Optional.
   *   ].
   *
   * @return \Psr\Http\Message\ResponseInterface|null
   *   Response.
   *
   * @throws \GuzzleHttp\Exception\GuzzleException
   *   Guzzle Exception.
   */
  public function deleteEntities(array $data): ResponseInterface|null {
    $client = $this->getClient();
    return $client->deleteEntities($data);
  }

  /**
   * Returns Client's user agent.
   *
   * @return string
   *   User Agent.
   */
  public function getClientUserAgent(): string {
    // Find out the module version in use.
    $module_info = $this->moduleList->getExtensionInfo('acquia_perz');
    $module_version = (isset($module_info['version'])) ? $module_info['version'] : '0.0.0';
    $drupal_version = (isset($module_info['core'])) ? $module_info['core'] : '0.0.0';

    return 'AcquiaPerzApiPhp/' . $drupal_version . '-' . $module_version;
  }

  /**
   * Makes a call to get a client response based on the client name.
   *
   * Note, this receives a Symfony request, but uses a PSR7 Request to Auth.
   *
   * @param \Symfony\Component\HttpFoundation\Request $request
   *   Request.
   *
   * @return \Acquia\Hmac\KeyInterface|bool
   *   Controller Key, FALSE otherwise.
   */
  public function authenticate(Request $request): KeyInterface|bool {
    if (!$this->subscription) {
      return FALSE;
    }

    $keys = [$this->subscription['api_key'] => $this->subscription['secret_key']];
    $keyLoader = new KeyLoader($keys);
    $authenticator = new RequestAuthenticator($keyLoader);
    $psr7_request = $this->httpMessageFactory->createRequest($request);
    try {
      return $authenticator->authenticate($psr7_request);
    }
    catch (KeyNotFoundException $exception) {
      $this->loggerFactory
        ->get('acquia_perz')
        ->debug('HMAC validation failed. [authorization_header = %authorization_header]', [
          '%authorization_header' => $request->headers->get('authorization'),
        ]);
    }

    return FALSE;
  }

  /**
   * Generates and add HMAC auth signature to repsonse.
   *
   * @param \Symfony\Component\HttpFoundation\Request $request
   *   Request.
   * @param \Symfony\Component\HttpFoundation\Response $response
   *   Response.
   * @param \Acquia\Hmac\KeyInterface $key
   *   Controller Key.
   *
   * @return \Psr\Http\Message\ResponseInterface
   *   Controller Key, FALSE otherwise.
   */
  public function generateResponseWithSignature(Request $request, Response $response, KeyInterface $key): ResponseInterface {
    $psr7_request = $this->httpMessageFactory->createRequest($request);
    $psr7Response = $this->httpMessageFactory->createResponse($response);
    $signer = new ResponseSigner($key, $psr7_request);
    $signedResponse = $signer->signResponse($psr7Response);
    return $this->httpFoundationFactory->createResponse($signedResponse);
  }

  /**
   * Generates and add HMAC auth signature to repsonse.
   *
   * @param \Symfony\Component\HttpFoundation\Request $request
   *   Request.
   *
   * @return \Symfony\Component\HttpFoundation\Request
   *   Request signed with hmac
   */
  public function generateRequestWithSignature(Request $request): Request {
    $key = ObjectFactory::getAuthenticationKey($this->subscription['api_key'], $this->subscription['secret_key']);
    $middleware = ObjectFactory::getHmacAuthMiddleware($key);
    $psr7_request = $this->httpMessageFactory->createRequest($request);
    $signed_request = $middleware->signRequest($psr7_request);
    return $this->httpFoundationFactory->createRequest($signed_request);
  }

  /**
   * Delete content from CIS.
   *
   * @return \Psr\Http\Message\ResponseInterface|null
   *   Response.
   *
   * @throws \GuzzleHttp\Exception\GuzzleException
   *   Guzzle Exception.
   */
  public function deleteContentFromCis(): ResponseInterface|null {
    $data = [
      'account_id' => PerzHelper::getAccountId(),
      'origin' => PerzHelper::getSiteId(),
      'environment' => PerzHelper::getSiteEnvironment(),
      'site_hash' => PerzHelper::getSiteHash(),
    ];
    return $this->deleteEntities($data);
  }

  /**
   * Push variations to Personalization.
   *
   * @param string|null $account_id
   *   Account ID.
   * @param string|null $site_hash
   *   Site hash.
   * @param string|null $site_env
   *   Site environment.
   * @param array $entity_variations
   *   Entity variations.
   * @param string $op
   *   Operation.
   *
   * @throws \GuzzleHttp\Exception\GuzzleException
   */
  public function pushDataToPersonalization(?string $account_id, ?string $site_hash, ?string $site_env, array $entity_variations, string $op = 'normal'): void {
    if (!empty($account_id) && !empty($site_hash) && !empty($site_env)) {
      $data = [
        'account_id' => $account_id,
        'origin' => $site_hash,
        'environment' => $site_env,
        'entity_variations' => $entity_variations,
        'site_hash' => PerzHelper::getSiteHash(),
      ];
      $this->putVariations($data);
    }
  }

  /**
   * Delete All contents from CIS.
   *
   * @return \Psr\Http\Message\ResponseInterface|null
   *   Response.
   *
   * @throws \GuzzleHttp\Exception\GuzzleException
   *   Guzzle Exception.
   */
  public function deleteAllContentsFromCis(): ResponseInterface|null {
    $data = [
      'account_id' => PerzHelper::getAccountId(),
      'environment' => PerzHelper::getSiteEnvironment(),
    ];
    return $this->deleteEntities($data);
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc