improvements-2.x-dev/src/Plugin/migrate/process/D7FileFieldCopy.php

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

namespace Drupal\improvements\Plugin\migrate\process;

use Drupal\Core\Database\Connection;
use Drupal\file\Entity\File;
use Drupal\file\FileInterface;
use Drupal\migrate\MigrateExecutableInterface;
use Drupal\migrate\MigrateSkipProcessException;
use Drupal\migrate\Plugin\migrate\process\FileCopy;
use Drupal\migrate\Plugin\MigrationInterface;
use Drupal\migrate\ProcessPluginBase;
use Drupal\migrate\Row;
use Drupal\migrate_drupal\Plugin\migrate\source\d7\FieldableEntity;

/**
 * @code
 *   source:
 *     plugin: d7_taxonomy_term # Any plugin implements FieldableEntity
 *     constants:
 *       source_base_path: '/path/to/old/site' # Required
 *       source_public_path: 'sites/default/files' # Required
 *   process:
 *     field_file_destination:
 *       plugin: d7_file_field_copy
 *       source: field_field_source
 *       destination_file_directory: 'images'
 *   destination:
 *     plugin: entity:taxonomy_term
 * @endcode
 *
 * @MigrateProcessPlugin(
 *   id = "d7_file_field_copy"
 * )
 */
class D7FileFieldCopy extends ProcessPluginBase {

  protected MigrationInterface $migration;

  protected FieldableEntity $source;

  protected Connection $sourceDatabase;

  /**
   * {@inheritdoc}
   */
  public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);
    $this->migration = $migration;
    $this->source = $migration->getSourcePlugin();
    $this->sourceDatabase = $this->source->getDatabase();
  }

  /**
   * {@inheritdoc}
   */
  public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
    if (!$value || (!isset($value['fid']) && !isset($value['target_id']))) {
      throw new MigrateSkipProcessException('$value does not contain fid property');
    }
    $fid = $value['fid'] ?? ($value['target_id'] ?? NULL);
    if (!$fid || !($source_file_info = $this->getSourceFileInfo($fid))) {
      throw new MigrateSkipProcessException('File with fid ' . $fid . ' does not exist');
    }

    $source_base_path = rtrim($row->getSourceProperty('constants/source_base_path'), '/'); // Eg "/path/to/old/site"
    $source_public_path = trim($row->getSourceProperty('constants/source_public_path'), '/'); // Eg "sites/default/files"
    $source_file_fullpath = str_replace('public://', $source_base_path . '/' . $source_public_path . '/', $source_file_info['uri']); // Eg "/path/to/old/site/sites/default/files/example.jpg"
    // @TODO Use field setting "file_directory"
    $destination_file_directory = trim($this->configuration['destination_file_directory'] ?? '', '/'); // Eg "images"
    // @TODO Use tokens without hardcoded file name
    $destination_file_uri = 'public://' . $destination_file_directory . '/o' . $fid . '.' . $source_file_info['extension']; // Eg "public://images/o123.jpg"

    if ($destination_file_uri = $this->copyFile($source_file_fullpath, $destination_file_uri, $migrate_executable, $row, $destination_property)) {
      $destination_file = $this->loadFileByUri($destination_file_uri) ?: File::create([
        'uri' => $destination_file_uri,
        'filename' => $source_file_info['filename'],
      ]);
      return ['entity' => $destination_file];
    }
  }

  /**
   * Return source file info.
   */
  protected function getSourceFileInfo($fid): array {
    $file_info = $this->sourceDatabase->select('file_managed', 'f')
      ->fields('f', ['filename', 'uri'])
      ->condition('f.fid', $fid)
      ->execute()
      ->fetchAssoc();
    $file_info['extension'] = pathinfo($file_info['filename'])['extension'];
    return $file_info;
  }

  /**
   * Load file entity by uri.
   */
  protected function loadFileByUri($file_uri): ?FileInterface {
    if ($files = \Drupal::entityTypeManager()->getStorage('file')->loadByProperties(['uri' => $file_uri])) {
      return current($files);
    }
    return NULL;
  }

  /**
   * Copy file and return destination path.
   *
   * @return string|FALSE
   */
  protected function copyFile($source_file_fullpath, $destination_file_uri, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
    $file_copy_configuration = $this->configuration + ['file_exists' => 'use existing'];
    /** @var FileCopy $file_copy_plugin */
    $file_copy_plugin = \Drupal::service('plugin.manager.migrate.process')->createInstance('file_copy', $file_copy_configuration);
    return $file_copy_plugin->transform([$source_file_fullpath, $destination_file_uri], $migrate_executable, $row, $destination_property);
  }

}

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

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