migrate_file_to_media-8.x-1.x-dev/src/Plugin/migrate/process/MediaFileCopy.php

src/Plugin/migrate/process/MediaFileCopy.php
<?php

namespace Drupal\migrate_file_to_media\Plugin\migrate\process;

use Drupal\Core\Entity\EntityRepositoryInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\File\FileExists;
use Drupal\Core\File\FileSystemInterface;
use Drupal\Core\StreamWrapper\StreamWrapperManagerInterface;
use Drupal\crop\Entity\Crop;
use Drupal\file\FileInterface;
use Drupal\file\FileRepositoryInterface;
use Drupal\migrate\MigrateException;
use Drupal\migrate\MigrateExecutableInterface;
use Drupal\migrate\Plugin\MigrateProcessInterface;
use Drupal\migrate\Plugin\migrate\process\FileCopy;
use Drupal\migrate\Row;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Copies or local file for usage in media module.
 *
 * Examples:
 *
 * @code
 * process:
 *   path_to_file:
 *     plugin: file_copy
 *     source:
 *       - id
 *       - public://new/path/to/
 * @endcode
 *
 * @see \Drupal\migrate\Plugin\MigrateProcessInterface
 *
 * @MigrateProcessPlugin(
 *   id = "media_file_copy"
 * )
 */
class MediaFileCopy extends FileCopy {

  /**
   * The module handler service.
   *
   * @var \Drupal\Core\Extension\ModuleHandlerInterface
   */
  protected ModuleHandlerInterface $moduleHandler;

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

  /**
   * The entity repository.
   *
   * @var \Drupal\Core\Entity\EntityRepositoryInterface
   */
  protected EntityRepositoryInterface $entityRepository;

  /**
   * The Entity Type Manager.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  private EntityTypeManagerInterface $entityTypeManager;

  /**
   * {@inheritdoc}
   */
  public function __construct(array $configuration, $plugin_id, array $plugin_definition, StreamWrapperManagerInterface $stream_wrappers, FileSystemInterface $file_system, MigrateProcessInterface $download_plugin, ModuleHandlerInterface $module_handler, FileRepositoryInterface $file_repository, EntityTypeManagerInterface $entityTypeManager) {
    parent::__construct($configuration, $plugin_id, $plugin_definition, $stream_wrappers, $file_system, $download_plugin);
    $this->moduleHandler = $module_handler;
    $this->fileRepository = $file_repository;
    $this->entityTypeManager = $entityTypeManager;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container->get('stream_wrapper_manager'),
      $container->get('file_system'),
      $container->get('plugin.manager.migrate.process')->createInstance('download', $configuration),
      $container->get('module_handler'),
      $container->get('file.repository'),
      $container->get('entity_type.manager'),
    );
  }

  /**
   * {@inheritdoc}
   */
  public function transform($source_id, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
    // If we're stubbing a file entity, return a URI of NULL so it will get
    // stubbed by the general process.
    if ($row->isStub()) {
      return NULL;
    }

    $destination_folder = $this->configuration['path'] ?? 'public://media/';

    $destination = $destination_folder . $row->getSourceProperty('file_name');

    $source_file = FALSE;

    // If the source path or URI represents a remote resource, delegate to the
    // download plugin.
    if (!$this->isLocalUri($source_id)) {
      $source = $this->downloadPlugin->transform([
        $source_id,
        'public://download/' . $row->getSourceProperty('file_name'),
      ], $migrate_executable, $row, $destination_property);
    }
    else {
      $source_file = $this->entityTypeManager->getStorage('file')->load($source_id);
      $source = $source_file?->getFileUri();
    }

    if ($source_file) {
      $destination = $destination_folder . $source_file->getFilename();
    }

    // Ensure the source file exists, if it's a local URI or path.
    if (!file_exists($source)) {
      throw new MigrateException("File '$source' does not exist");
    }

    // Prepare destination folder.
    if (strpos($destination_folder, 'rokka') !== 0) {
      // Check if a writable directory exists, and if not try to create it.
      $dir = $this->getDirectory($destination);
      // If the directory exists and is writable, avoid file_prepare_directory()
      // call and write the file to destination.
      if (!$dir || !is_dir($dir) || !is_writable($dir)) {
        if (!$this->fileSystem->prepareDirectory($dir, FileSystemInterface::CREATE_DIRECTORY | FileSystemInterface::MODIFY_PERMISSIONS)) {
          throw new MigrateException("Could not create or write to directory '$dir'");
        }
      }
    }

    $final_destination = $this->saveFile($source, $destination);
    if ($this->moduleHandler->moduleExists('crop')) {
      $this->updateFocalPoint($source, (string) $final_destination->getFileUri(), $final_destination);
    }
    return $final_destination->id();
  }

  /**
   * Save file to a defined destination.
   */
  protected function saveFile(string $source, string $destination, FileExists|int $replace = FileExists::Rename): FileInterface {
    $data = file_get_contents($source);
    if ($data === FALSE) {
      throw new MigrateException("File $source could not be read");
    }
    return $this->fileRepository->writeData($data, $destination, $replace);
  }

  /**
   * Update focal point.
   *
   * @param string $uri_old
   *   Old URI.
   * @param string $uri_rokka
   *   Rokka URI.
   * @param \Drupal\file\FileInterface $rokka_file
   *   Rokka file.
   *
   * @throws \Drupal\migrate\MigrateException
   */
  private function updateFocalPoint(string $uri_old, string $uri_rokka, FileInterface $rokka_file): void {

    try {

      /** @var \Drupal\crop\Entity\Crop|null $old_crop */
      $old_crop = Crop::findCrop($uri_old, 'focal_point');

      if (!empty($old_crop)) {

        $crop = Crop::create([
          'type' => 'focal_point',
          'entity_id' => $rokka_file->id(),
          'entity_type' => 'file',
          'uri' => $uri_rokka,
          'height' => $old_crop->height->value,
          'width' => $old_crop->width->value,
          'x' => $old_crop->x->value,
          'y' => $old_crop->y->value,
        ]);

        $crop->save();
      }

    }
    catch (\Exception $exception) {
      throw new MigrateException('Failed to save the focal point to rokka');
    }

  }

}

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

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