o365-2.0.3/modules/o365_sso_user/src/SsoUserSync.php

modules/o365_sso_user/src/SsoUserSync.php
<?php

namespace Drupal\o365_sso_user;

use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\File\FileSystemInterface;
use Drupal\file\FileRepositoryInterface;
use Drupal\o365\GraphService;
use Drupal\o365_profile\O365ProfileGetDataService;
use Drupal\user\UserInterface;
use Mimey\MimeTypes;

/**
 * User sync service that syncs data from Graph API to entities.
 */
class SsoUserSync {

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

  /**
   * The modules config.
   *
   * @var \Drupal\Core\Config\ImmutableConfig
   */
  protected $config;

  /**
   * The o365 Graph Service.
   *
   * @var \Drupal\o365\GraphService
   */
  protected $graphService;

  /**
   * The entity type manager.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * The profile data service.
   *
   * @var \Drupal\o365_profile\O365ProfileGetDataService
   */
  protected $profileGetDataService;

  /**
   * The file repository.
   *
   * @var \Drupal\file\FileRepositoryInterface
   */
  protected $fileRepository;

  /**
   * The file system service.
   *
   * @var \Drupal\Core\File\FileSystemInterface
   */
  private FileSystemInterface $fileSystem;

  /**
   * Constructs a SsoUserSync object.
   *
   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
   *   The config factory.
   * @param \Drupal\o365\GraphService $graphService
   *   The Graph API service.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
   *   The entity type manager.
   * @param \Drupal\o365_profile\O365ProfileGetDataService $o365ProfileGetDataService
   *   The profile data service.
   * @param \Drupal\file\FileRepositoryInterface $fileRepository
   *   The drupal file repository.
   * @param \Drupal\Core\File\FileSystemInterface $fileSystem
   *   The drupal file system.
   */
  public function __construct(ConfigFactoryInterface $config_factory, GraphService $graphService, EntityTypeManagerInterface $entityTypeManager, O365ProfileGetDataService $o365ProfileGetDataService, FileRepositoryInterface $fileRepository, FileSystemInterface $fileSystem) {
    $this->configFactory = $config_factory;
    $this->graphService = $graphService;
    $this->entityTypeManager = $entityTypeManager;
    $this->profileGetDataService = $o365ProfileGetDataService;
    $this->fileRepository = $fileRepository;
    $this->fileSystem = $fileSystem;
    $this->config = $config_factory->get('o365_sso_user.settings');
  }

  /**
   * Sync the user data with data from the graph API.
   */
  public function syncUserData($user): void {
    // Only do this when we want to use graph data.
    if (!empty($this->config->get('use_graph_data'))) {
      // Get user data.
      $userData = $this->profileGetDataService->getProfileData(NULL, '648x648');
      if ($userData) {
        $entityAltered = FALSE;

        if ($this->config->get('use_profile_module')) {
          $this->syncUserProfileData($user, $userData);
        }
        else {
          $this->synUserUserData($user, $userData, $entityAltered);
        }

        // Save the user when it has changed.
        if ($entityAltered) {
          $user->save();
        }
      }
    }
  }

  /**
   * Sync a standard drupal user.
   *
   * @param \Drupal\user\UserInterface $user
   *   The user object.
   * @param array $userData
   *   The user data from the Graph API.
   * @param bool $entityAltered
   *   If the entity is altered or not. Used later on.
   *
   * @throws \Drupal\Core\Entity\EntityStorageException
   */
  private function synUserUserData(UserInterface $user, array $userData, &$entityAltered): void {
    $this->mapDataToFields($user, $userData['userData'], $entityAltered);

    // Sync the user picture.
    $this->syncUserPicture($user, $entityAltered, $userData);
  }

  /**
   * Sync a Drupal user using the profile module.
   *
   * @param \Drupal\user\UserInterface $user
   *   The user object.
   * @param array $userData
   *   The user data from the Graph API.
   *
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   * @throws \Drupal\Core\Entity\EntityStorageException
   */
  private function syncUserProfileData(UserInterface $user, array $userData): void {
    // First get the profile for this user.
    /** @var \Drupal\profile\ProfileStorage $storage */
    $storage = $this->entityTypeManager->getStorage('profile');

    $profileBundle = ($this->config->get('profile_bundle')) ?: 'profile';
    $profiles = $storage->loadMultipleByUser($user, $profileBundle);
    if (!empty($profiles)) {
      $entityAltered = FALSE;
      /** @var \Drupal\profile\Entity\Profile $profile */
      $profile = reset($profiles);
      $this->mapDataToFields($profile, $userData['userData'], $entityAltered);

      // Sync the user picture.
      $this->syncUserPicture($profile, $entityAltered, $userData);

      if ($entityAltered) {
        $profile->save();
      }
    }
  }

  /**
   * Sync the user picture if needed and wanted.
   *
   * @param \Drupal\user\UserInterface|\Drupal\profile\Entity\Profile $entity
   *   The user or profile entity.
   * @param bool $entityAltered
   *   If the entity is altered or not. Used later on.
   * @param array $userData
   *   The user data array containing the image.
   *
   * @throws \Drupal\Core\Entity\EntityStorageException
   */
  private function syncUserPicture(&$entity, &$entityAltered, array $userData): void {
    if (!empty($this->config->get('sync_profile_image'))) {
      $entityField = $this->config->get('profile_image_mapping');
      if ($entity->hasField($entityField)) {
        if ($userData && array_key_exists('imageBase64', $userData)) {
          /** @var \Drupal\file\Entity\File $origImage */
          $origImage = $entity->get($entityField)->entity;
          $origFileBase64 = 'empty';
          $newFileBase64 = $userData['imageBase64'];

          if ($origImage) {
            $origFilePath = $this->fileSystem->realpath($origImage->getFileUri());
            $origFileBase64 = base64_encode(file_get_contents($origFilePath));
          }

          // Only upload and save new profile pics.
          if ($origFileBase64 !== $newFileBase64) {
            $data = base64_decode($userData['imageBase64']);

            // Set up the image file uri.
            $fieldDefinition = $entity->getFieldDefinition($entityField);
            if ($fieldDefinition) {
              $fieldDefinitionSettings = $fieldDefinition->getSettings();
              $uri = $fieldDefinitionSettings['uri_scheme'] . '://';
              $mimes = new MimeTypes();
              $imageName = $entity->id() . '.' . $mimes->getExtension($userData['imageMeta']['@odata.mediaContentType']);

              $imageFile = $this->fileRepository->writeData($data, $uri . $imageName);

              // Save the file to the entity .
              if ($imageFile) {
                $entity->set($entityField, $imageFile->id());
                $entityAltered = TRUE;
              }
            }
          }
        }
      }
    }
  }

  /**
   * Map the user data to field in a entity.
   *
   * @param \Drupal\user\UserInterface|\Drupal\profile\Entity\Profile $entity
   *   The user or profile entity.
   * @param array $userData
   *   The user data.
   * @param bool $entityAltered
   *   If the entity is altered or not. Used later on.
   */
  private function mapDataToFields(&$entity, array $userData, &$entityAltered = FALSE): void {
    $mapping = $this->getFieldMapping();

    if (!empty($mapping)) {
      // Loop through the mappings.
      foreach ($mapping as $userDataField => $entityField) {
        // Check if the fields exist in both the data and the user.
        if (isset($userData[$userDataField]) && $entity->hasField($entityField)) {
          $origValue = $entity->get($entityField)->getString();
          if ($origValue != $userData[$userDataField]) {
            $entity->set($entityField, $userData[$userDataField]);
            $entityAltered = TRUE;
          }
        }
      }
    }
  }

  /**
   * Get the field mappings from the settings.
   *
   * @return array
   *   The mapping as graph_api_field => drupal_field.
   */
  private function getFieldMapping(): array {
    $mapping = [];
    $data = $this->config->get('graph_data_mapping');
    $lines = preg_split('/\r\n|\r|\n/', $data);

    if (!empty($lines) && !empty($lines[0])) {
      foreach ($lines as $line) {
        $field = explode('|', $line);
        $mapping[trim($field[0])] = trim($field[1]);
      }
    }

    return $mapping;
  }

}

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

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