o365-2.0.3/modules/o365_groups/src/GroupsService.php

modules/o365_groups/src/GroupsService.php
<?php

namespace Drupal\o365_groups;

use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Database\Connection;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\o365\GraphService;
use Microsoft\Graph\Model\Channel;
use Microsoft\Graph\Model\Group;

/**
 * Service used to do all kinds of stuff with groups and teams.
 */
class GroupsService {

  /**
   * The o365.graph service.
   *
   * @var \Drupal\o365\GraphService
   */
  protected GraphService $o365Graph;

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

  /**
   * The current user.
   *
   * @var \Drupal\Core\Session\AccountInterface
   */
  protected AccountInterface $currentUser;

  /**
   * List of all teams.
   *
   * @var array
   */
  protected array $teams = [];

  /**
   * The database connection.
   *
   * @var \Drupal\Core\Database\Connection
   */
  protected Connection $connection;

  /**
   * The default endpoint for getting a list of teams.
   *
   * @var string
   */
  protected string $getTeamsEndpoint = "/me/joinedTeams";

  /**
   * Constructs a GroupsService object.
   *
   * @param \Drupal\o365\GraphService $o365_graph
   *   The o365.graph service.
   * @param \Drupal\Core\Cache\CacheBackendInterface $cacheBackend
   *   The cache backend.
   * @param \Drupal\Core\Session\AccountProxyInterface $accountProxy
   *   The account proxy.
   * @param \Drupal\Core\Database\Connection $connection
   *   The database connection.
   */
  public function __construct(GraphService $o365_graph, CacheBackendInterface $cacheBackend, AccountProxyInterface $accountProxy, Connection $connection) {
    $this->o365Graph = $o365_graph;
    $this->cacheBackend = $cacheBackend;
    $this->currentUser = $accountProxy->getAccount();
    $this->connection = $connection;
  }

  /**
   * Get all the available groups from teams.
   *
   * @return array
   *   The list of available teams.
   *
   * @throws \Drupal\Core\TempStore\TempStoreException
   * @throws \GuzzleHttp\Exception\GuzzleException
   * @throws \League\OAuth2\Client\Provider\Exception\IdentityProviderException
   */
  public function getGroupsFromTeams(): array {
    $this->getTeamsFromGraph();

    $teams = [];
    foreach ($this->teams as $id => $name) {
      $teams[$id] = $name;
    }

    // Sort on value.
    asort($teams);
    return $teams;
  }

  /**
   * Get a list of all groups in Microsoft 365.
   *
   * @param bool|string $endpoint
   *   The endpoint string containing the skipToken or FALSE for default.
   *
   * @throws \Drupal\Core\TempStore\TempStoreException
   * @throws \GuzzleHttp\Exception\GuzzleException
   * @throws \League\OAuth2\Client\Provider\Exception\IdentityProviderException
   */
  protected function getTeamsFromGraph(bool|string $endpoint = FALSE): void {
    $cid = 'getTeamsFromGraph::' . $this->currentUser->id();
    $cache = $this->cacheBackend->get($cid);
    $teams = [];

    if (!$cache) {
      try {
        if (!$endpoint) {
          $endpoint = $this->getTeamsEndpoint;
        }

        $data = $this->o365Graph->getGraphData($endpoint, 'GET', FALSE, FALSE, Group::class);

        if ($data) {
          /** @var \Microsoft\Graph\Model\Group $group */
          foreach ($data as $group) {
            $channelEndpoint = '/teams/' . $group->getId() . '/channels';
            $groupName = $group->getDisplayName();

            $channels = $this->o365Graph->getGraphData($channelEndpoint, 'GET', FALSE, FALSE, Channel::class);
            if ($channels) {
              /** @var \Microsoft\Graph\Model\Channel $channel */
              foreach ($channels as $channel) {
                $key = $group->getId() . '|||' . $channel->getId();
                $teams[$key] = $groupName . ' - ' . $channel->getDisplayName();
              }
            }
          }
        }

        $expireDate = strtotime('+4 hours');
        $this->cacheBackend->set($cid, $teams, $expireDate);
      }
      finally {
        $this->teams = $teams;
      }
    }
    else {
      $this->teams = $cache->data;
    }
  }

  /**
   * Generate a link to a team channel based on the ID.
   *
   * @param int $gid
   *   The group ID.
   *
   * @return string|false
   *   The URL to the team or FALSE.
   *
   * @throws \Drupal\Core\TempStore\TempStoreException
   * @throws \GuzzleHttp\Exception\GuzzleException
   * @throws \League\OAuth2\Client\Provider\Exception\IdentityProviderException
   */
  public function generateTeamChannelLink(int $gid): bool|string {
    if ($this->o365Graph->getCurrentUserId()) {
      $data = $this->getTeamsUuidForGroup($gid);
      if ($data) {
        // Explode the ID on the 3 pipes.
        $ids = explode('|||', $data['uuid']);

        if (count($ids) > 1) {
          $endpoint = '/teams/' . $ids[0] . '/channels/' . $ids[1];
          /** @var \Microsoft\Graph\Model\Channel $channel */
          $channel = $this->o365Graph->getGraphData($endpoint, 'GET', FALSE, FALSE, Channel::class);

          if ($channel) {
            return $channel->getWebUrl();
          }
        }
      }
    }

    return FALSE;
  }

  /**
   * Get the saved teams UUID from the database, or FALSE.
   *
   * @param int $gid
   *   The group ID.
   * @param bool $onlyUuid
   *   If we only want to return the UUID.
   *
   * @return mixed
   *   The data from the database or FALSE.
   */
  public function getTeamsUuidForGroup(int $gid, $onlyUuid = FALSE): mixed {
    $result = $this->connection->select('o365_groups_teams', 't')
      ->fields('t', ['gid', 'uuid'])
      ->condition('gid', $gid)
      ->execute();

    $assoc = $result->fetchAssoc();

    if ($onlyUuid && $assoc) {
      return $assoc['uuid'];
    }

    return $assoc;
  }

  /**
   * Save the teams UUID in the database.
   *
   * @param string $uuid
   *   The teams UUID.
   * @param int $gid
   *   The group ID.
   *
   * @throws \Exception
   */
  public function saveTeamsUuidForGroup(string $uuid, int $gid): void {
    // Create a new row in our table.
    if (!$this->getTeamsUuidForGroup($gid)) {
      $this->connection->insert('o365_groups_teams')
        ->fields([
          'gid' => $gid,
          'uuid' => $uuid,
        ])
        ->execute();
    }
    else {
      // Update the existing row or delete the row when UUID is empty.
      if (empty($uuid)) {
        $this->connection->delete('o365_groups_teams')
          ->condition('gid', $gid)
          ->execute();
      }
      else {
        $this->connection->update('o365_groups_teams')
          ->fields([
            'uuid' => $uuid,
          ])
          ->condition('gid', $gid)
          ->execute();
      }
    }
  }

}

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

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