o365-2.0.3/src/GraphService.php

src/GraphService.php
<?php

namespace Drupal\o365;

use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Logger\LoggerChannelFactoryInterface;
use Drupal\Core\Logger\LoggerChannelInterface;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\externalauth\AuthmapInterface;
use GuzzleHttp\Exception\ClientException;
use Microsoft\Graph\Graph;
use Microsoft\Graph\Http\GraphCollectionRequest;

/**
 * This is the GraphService.
 *
 * The main service that gets and sets data in Microsoft 365.
 */
class GraphService {

  /**
   * Drupal\o365\AuthenticationServiceInterface definition.
   */
  protected AuthenticationServiceInterface $authService;

  /**
   * The logger service.
   */
  protected O365LoggerServiceInterface $messenger;

  /**
   * The cache backend service.
   *
   * @var \Drupal\Core\Cache\CacheBackendInterface
   */
  protected CacheBackendInterface $cacheBackend;

  /**
   * The modules logger.
   *
   * @var \Drupal\Core\Logger\LoggerChannelInterface
   */
  protected LoggerChannelInterface $logger;

  /**
   * The externalauth authmap service.
   *
   * @var \Drupal\externalauth\AuthmapInterface
   */
  protected AuthmapInterface $authmap;

  /**
   * The current user account.
   */
  protected AccountProxyInterface $currentUser;

  /**
   * The timeout used in calls to the Graph API.
   *
   * @var int
   */
  private int $timeout = 1000;

  /**
   * Constructs a new GraphService object.
   *
   * @param \Drupal\o365\AuthenticationServiceInterface $authenticationService
   *   The AuthenticationServiceInterface definition.
   * @param \Drupal\o365\O365LoggerServiceInterface $messenger
   *   The O365LoggerServiceInterface definition.
   * @param \Drupal\Core\Cache\CacheBackendInterface $cacheBackend
   *   The CacheBackendInterface definition.
   * @param \Drupal\Core\Logger\LoggerChannelFactoryInterface $loggerChannelFactory
   *   The logger channel factory. Used to log to the watchdog.
   * @param \Drupal\externalauth\AuthmapInterface $authmap
   *   The externalauth authmap service.
   * @param \Drupal\Core\Session\AccountProxyInterface $currentUser
   *   The current user account.
   */
  public function __construct(AuthenticationServiceInterface $authenticationService, O365LoggerServiceInterface $messenger, CacheBackendInterface $cacheBackend, LoggerChannelFactoryInterface $loggerChannelFactory, AuthmapInterface $authmap, AccountProxyInterface $currentUser) {
    $this->authService = $authenticationService;
    $this->messenger = $messenger;
    $this->cacheBackend = $cacheBackend;
    $this->logger = $loggerChannelFactory->get('o365');
    $this->authmap = $authmap;
    $this->currentUser = $currentUser;
  }

  /**
   * Get data from the MS GraphAPI.
   *
   * @param string $endpoint
   *   The graph endpoint we want data from.
   * @param string $type
   *   The type of request we want to do.
   * @param bool $raw
   *   This determines if we want a raw body or not.
   * @param bool|string $version
   *   The version of the graph api that is used.
   * @param bool|string $returnType
   *   The return type we want to get.
   * @param array $headers
   *   An array of headers to send.
   *
   * @return mixed
   *   The data retrieved from the Graph API.
   *
   * @throws \Drupal\Core\TempStore\TempStoreException
   * @throws \League\OAuth2\Client\Provider\Exception\IdentityProviderException|\GuzzleHttp\Exception\GuzzleException|\Microsoft\Graph\Exception\GraphException
   */
  public function getGraphData(string $endpoint, string $type = 'GET', bool $raw = FALSE, bool|string $version = FALSE, bool|string $returnType = FALSE, array $headers = []): mixed {
    $authMapUser = $this->authmap->get($this->currentUser->getAccount()
      ->id(), 'o365_sso');
    if (!$this->currentUser->isAnonymous() && !$authMapUser) {
      return [];
    }

    return $this->getData($endpoint, $type, $raw, $version, [], $returnType, $headers);
  }

  /**
   * Send data to the MS GraphAPI.
   *
   * @param string $endpoint
   *   The graph endpoint we want data from.
   * @param mixed $data
   *   Sent data.
   * @param string $type
   *   The type of request we want to do.
   * @param bool $raw
   *   This determines if we want a raw body or not.
   * @param bool|string $version
   *   The version of the graph api that is used.
   * @param bool|string $returnType
   *   The return type we want to get.
   * @param array $headers
   *   An array of headers to send.
   *
   * @return mixed
   *   The data retrieved from the Graph API.
   *
   * @throws \Drupal\Core\TempStore\TempStoreException
   * @throws \League\OAuth2\Client\Provider\Exception\IdentityProviderException|\GuzzleHttp\Exception\GuzzleException
   * @throws \Microsoft\Graph\Exception\GraphException
   */
  public function sendGraphData(string $endpoint, mixed $data = [], string $type = 'POST', bool $raw = FALSE, bool|string $version = FALSE, bool|string $returnType = FALSE, array $headers = []): mixed {
    $authMapUser = $this->authmap->get($this->currentUser->getAccount()
      ->id(), 'o365_sso');
    if (!$this->currentUser->isAnonymous() && !$authMapUser) {
      return [];
    }

    return $this->getData($endpoint, $type, $raw, $version, $data, $returnType, $headers);
  }

  /**
   * Generic method to get or send data to the Graph endpoints.
   *
   * @param string $endpoint
   *   The graph endpoint we want data from.
   * @param string $type
   *   The type of request we want to do.
   * @param bool $raw
   *   This determines if we want a raw body or not.
   * @param bool|string $version
   *   The version of the graph api that is used.
   * @param mixed $data
   *   Sent data.
   * @param bool|string $returnType
   *   The return type we want to get.
   * @param array $headers
   *   An array of headers to send.
   *
   * @return mixed
   *   The retrieved data from the GRAPH API.
   *
   * @throws \Drupal\Core\TempStore\TempStoreException
   * @throws \GuzzleHttp\Exception\GuzzleException
   * @throws \League\OAuth2\Client\Provider\Exception\IdentityProviderException|\Microsoft\Graph\Exception\GraphException
   */
  private function getData(string $endpoint, string $type = 'GET', bool $raw = FALSE, bool|string $version = FALSE, mixed $data = [], bool|string $returnType = FALSE, array $headers = []): mixed {
    // Get the data from the Graph API.
    try {
      $graph = new Graph();

      if ($version) {
        $graph->setApiVersion($version);
      }

      $accessToken = $this->authService->getAccessToken();
      $graph->setAccessToken($accessToken);

      if ($type === 'POST' || $type === 'PUT'  || $type === 'PATCH') {
        $request = $graph->createRequest($type, $endpoint)
          ->addHeaders($headers)
          ->setTimeout($this->getTimeout())
          ->attachBody($data);

        if ($returnType) {
          $request->setReturnType($returnType);
          return $request->execute();
        }

        $request = $request->execute();
      }
      elseif ($type === 'UPLOAD') {
        $request = $graph->createRequest('PUT', $endpoint)
          ->addHeaders($headers);

        if ($returnType) {
          $request->setReturnType($returnType);
          return $request->upload($data);
        }

        $request->upload($data);
      }
      else {
        $request = $graph->createRequest($type, $endpoint)
          ->addHeaders($headers);

        if ($returnType) {
          $request->setReturnType($returnType);
          return $request->execute();
        }

        $request = $request->execute();
      }

      // Get the return values.
      $return = $request->getBody();
      if ($raw) {
        $return = $request->getRawBody();
      }

      return $return;
    }
    catch (ClientException $e) {
      // Log the error message.
      // If error is about a missing profile image, don't log it.
      if (!str_contains($e->getMessage(), 'Microsoft.Fast.Profile.Core.Exception.ImageNotFoundException')) {
        $this->logger->error($e->getMessage());
      }
    }

    return FALSE;
  }

  /**
   * Get a collection of data.
   *
   * @param string $endpoint
   *   The graph endpoint we want data from.
   * @param bool|string $returnType
   *   The return type we want to get.
   * @param bool|string $version
   *   The version of the graph api that is used.
   *
   * @return false|\Microsoft\Graph\Http\GraphCollectionRequest
   *   The collection request.
   *
   * @throws \Drupal\Core\TempStore\TempStoreException
   * @throws \League\OAuth2\Client\Provider\Exception\IdentityProviderException
   * @throws \Microsoft\Graph\Exception\GraphException
   */
  public function getCollectionData(string $endpoint, bool|string $returnType = FALSE, bool|string $version = FALSE): GraphCollectionRequest|bool {
    try {
      $graph = new Graph();

      if ($version) {
        $graph->setApiVersion($version);
      }

      $accessToken = $this->authService->getAccessToken();
      $graph->setAccessToken($accessToken);
      $request = $graph->createCollectionRequest('GET', $endpoint);

      if ($returnType) {
        $request->setReturnType($returnType);
      }

      return $request;
    }
    catch (ClientException $e) {
      $this->logger->error($e->getMessage());
    }

    return FALSE;
  }

  /**
   * Determine the office user ID.
   *
   * @return bool|string
   *   The ID or FALSE if not logged in via Office.
   */
  public function getCurrentUserId(): bool|string {
    return $this->authService->checkForOfficeLogin();
  }

  /**
   * Get the Graph API timeout.
   *
   * @return int
   *   The timeout in seconds.
   */
  public function getTimeout(): int {
    return $this->timeout;
  }

  /**
   * Set the Graph API timeout.
   *
   * @param int $timeout
   *   The timeout amount in seconds.
   */
  public function setTimeout(int $timeout): void {
    $this->timeout = $timeout;
  }

}

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

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