cloudinary-8.x-1.x-dev/modules/cloudinary_source_migrate/src/CloudinarySourceMigrateHelper.php

modules/cloudinary_source_migrate/src/CloudinarySourceMigrateHelper.php
<?php

namespace Drupal\cloudinary_source_migrate;

use Cloudinary\Api\Admin\AdminApi;
use Cloudinary\Asset\AssetType;
use Cloudinary\Asset\DeliveryType;
use Drupal\cloudinary_media_library_widget\CloudinaryInterface;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Field\FieldItemList;
use Drupal\Core\State\State;
use Drupal\file\Plugin\Field\FieldType\FileItem;
use Drupal\media\MediaInterface;
use Drupal\media\MediaTypeInterface;
use Drupal\video_embed_field\Plugin\Field\FieldType\VideoEmbedField;

/**
 * Build a service to help migrating cloudinary source.
 */
class CloudinarySourceMigrateHelper implements CloudinarySourceMigrateHelperInterface {

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

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

  /**
   * The entity field manager.
   *
   * @var \Drupal\Core\Entity\EntityFieldManagerInterface
   */
  protected EntityFieldManagerInterface $entityFieldManager;

  /**
   * Construct of CloudinarySourceMigrateHelper.
   *
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity type manager.
   * @param \Drupal\Core\State\State $state
   *   The state storage.
   * @param \Drupal\Core\Entity\EntityFieldManagerInterface $entity_field_manager
   *   The entity field manager.
   */
  public function __construct(EntityTypeManagerInterface $entity_type_manager, State $state, EntityFieldManagerInterface $entity_field_manager) {
    $this->entityTypeManager = $entity_type_manager;
    $this->state = $state;
    $this->entityFieldManager = $entity_field_manager;
  }

  /**
   * {@inheritdoc}
   */
  public function getMediaBundleMap(): array {
    $resource_old_bundle_map = [
      AssetType::IMAGE => 'cloudinary_image',
      AssetType::VIDEO => 'cloudinary_video',
      AssetType::RAW => 'file',
    ];

    $media_type_storage = $this->entityTypeManager->getStorage('media_type');

    /** @var \Drupal\media\MediaTypeInterface[] $media_types */
    $media_types = $media_type_storage->loadMultiple();

    $cloudinary_types = array_filter($media_types, function (MediaTypeInterface $media_type) {
      return $media_type->getSource() instanceof CloudinaryInterface;
    });

    $bundle_map = [];

    foreach ($cloudinary_types as $media_type) {
      $configuration = $media_type->getSource()->getConfiguration();
      $resource_type = $configuration['resource_type'];

      if (!isset($resource_old_bundle_map[$resource_type])) {
        continue;
      }

      $bundle_map[$resource_old_bundle_map[$resource_type]] = $media_type->id();
    }

    return $bundle_map;
  }

  /**
   * {@inheritdoc}
   */
  public function getDestinationMap(): array {
    return $this->state->get(self::DESTINATION_MAP_KEY, []);
  }

  /**
   * {@inheritdoc}
   */
  public function setDestinationId(MediaInterface $old_media, MediaInterface $new_media): void {
    $state = $this->getDestinationMap();
    $state[$old_media->id()] = $new_media->id();
    $this->state->set(self::DESTINATION_MAP_KEY, $state);
  }

  /**
   * {@inheritdoc}
   */
  public function clearDestinationMap(): void {
    $this->state->delete(self::DESTINATION_MAP_KEY);
  }

  /**
   * {@inheritdoc}
   */
  public function isMigrated(MediaInterface $media): bool {
    return isset($this->getDestinationMap()[$media->id()]);
  }

  /**
   * {@inheritdoc}
   */
  public function getPublicIdFromFieldItem($item): string {
    if ($item instanceof VideoEmbedField) {
      $uri = $item->value;
    }
    elseif ($item instanceof FileItem) {
      /** @var \Drupal\file\FileInterface $file */
      $file = $item->entity;
      $uri = $file->getFileUri();
    }

    if (!isset($uri)) {
      throw new \Exception('Not applicable');
    }

    [$scheme, $target] = explode('://', $uri);

    // Make sure we work with cloudinary file scheme only.
    if ($scheme !== 'cloudinary') {
      throw new \Exception('Not applicable');
    }

    $parts = explode('.', $target);

    // Exclude format from the target.
    if (count($parts) > 1) {
      array_pop($parts);
    }

    return implode('.', $parts);
  }

  /**
   * {@inheritdoc}
   */
  public function getAssetFromFieldItem($item, string $resource_type): array {
    $public_id = $this->getPublicIdFromFieldItem($item);
    $api = new AdminApi();

    $resource_types = [];

    // Common documents like PDF use image type. So let's try to load a resource
    // with image type first.
    if ($resource_type === AssetType::RAW) {
      $resource_types[] = AssetType::IMAGE;
    }

    $resource_types[] = $resource_type;

    foreach ($resource_types as $type) {
      try {
        return (array) $api->asset($public_id, [
          AssetType::KEY => $type,
          DeliveryType::KEY => DeliveryType::UPLOAD,
        ]);
      }
      catch (\Exception $e) {
        // We try again but with fallback type.
      }
    }

    // Asset not found.
    throw new \Exception('Not applicable');
  }

  /**
   * {@inheritdoc}
   */
  public function getEntityReferenceFieldsToMigrate(): array {
    $media_type_storage = $this->entityTypeManager->getStorage('media_type');

    /** @var \Drupal\media\MediaTypeInterface[] $media_types */
    $media_types = $media_type_storage->loadMultiple();

    $map = $this->entityFieldManager->getFieldMapByFieldType('entity_reference');
    $fields_to_migrate = [];

    foreach ($map as $entity_type => $fields) {
      foreach ($fields as $field_name => $info) {
        foreach ($info['bundles'] as $bundle) {
          $field_definitions = $this->entityFieldManager->getFieldDefinitions($entity_type, $bundle);
          $target_type = $field_definitions[$field_name]->getSetting('target_type');

          if ($target_type !== 'media') {
            continue;
          }

          $settings = $field_definitions[$field_name]->getSetting('handler_settings');
          $types_to_migrate = array_filter($settings['target_bundles'], function ($media_type_id) use ($media_types) {
            return $media_types[$media_type_id]->getSource() instanceof CloudinaryInterface;
          });

          if ($types_to_migrate) {
            $fields_to_migrate[$entity_type][$bundle][] = $field_name;
          }
        }
      }
    }

    return $fields_to_migrate;
  }

}

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

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