Commit 42302da7 authored by Mathilde Dumond's avatar Mathilde Dumond Committed by Sascha Grossenbacher
Browse files

Issue #3136910 by mathilde_dumond: Provide field mapping support for Media entity reference field

parent cc503f59
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -46,3 +46,20 @@ migrate_plus.destination.gc_entity:
  mapping:
    translations:
      type: boolean

migrate_plus.process.gather_content_media:
  type: migrate_process
  label: 'media'
  mapping:
    uri_scheme:
      type: string
      label: 'uri scheme'
    file_dir:
      type: string
      label: 'File directory'
    language:
      type: string
      label: 'Language'
    bundle:
      type: string
      label: 'Bundle'
+3 −0
Original line number Diff line number Diff line
@@ -328,6 +328,8 @@ abstract class MappingSteps {
   *   Nested ID array.
   * @param string $bundle_label
   *   Bundle label string.
   * @param int $counter
   *   Field depth, to avoid infinite recursion.
   *
   * @return array
   *   Associative array with equivalent fields.
@@ -337,6 +339,7 @@ abstract class MappingSteps {
      'attachment' => [
        'file',
        'image',
        'entity_reference',
        'entity_reference_revisions',
      ],
      'guidelines' => [
+46 −16
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@ use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\datetime\Plugin\Field\FieldType\DateTimeItemInterface;
use Drupal\field\Entity\FieldConfig;
use Drupal\gathercontent\Entity\MappingInterface;
use Drupal\media\Entity\MediaType;
use Drupal\migrate_plus\Entity\Migration;

/**
@@ -507,15 +508,14 @@ class MigrationDefinitionCreator {
        break;

      case 'entity_reference':
        if (!empty($fieldInfo->getSetting('handler_settings')['auto_create_bundle'])) {
          $bundle = $fieldInfo->getSetting('handler_settings')['auto_create_bundle'];
        $handler_settings = $fieldInfo->getSetting('handler_settings');
        if (count($handler_settings['target_bundles']) == 1 || !$fieldInfo->getSetting('handler_settings')['auto_create']) {
          $bundle = reset($handler_settings['target_bundles']);
        }
        else {
          $handler_settings = $fieldInfo->getSetting('handler_settings');
          $handler_settings = reset($handler_settings);
          $bundle = array_shift($handler_settings);
          $bundle = $fieldInfo->getSetting('handler_settings')['auto_create_bundle'];
        }

        if ($fieldInfo->getSetting('target_type') == 'taxonomy_term') {
          $definition['process'][$element] = [
            'plugin' => 'sub_process',
            'source' => $elementId,
@@ -527,6 +527,36 @@ class MigrationDefinitionCreator {
              ],
            ],
          ];
        }
        elseif ($fieldInfo->getSetting('target_type') == 'media') {
          $media_type = MediaType::load($bundle);
          $source = $media_type->getSource();
          $media_image_field = $source->getSourceFieldDefinition($media_type);
          if (!$media_image_field) {
            break;
          }
          $media_image_field_type = $media_image_field->getType();

          if (!in_array($media_image_field_type, ['image', 'file'])) {
            break;
          }

          $fileDir = $media_image_field->getSetting('file_directory');
          $uriScheme = $media_image_field->getFieldStorageDefinition()->getSetting('uri_scheme') . '://';

          $definition['process'][$element] = [
            'plugin' => 'gather_content_media',
            'source' => $elementId,
            'uri_scheme' => $uriScheme,
            'file_dir' => $fileDir,
            'language' => $this->siteDefaultLangCode,
            'bundle' => $bundle,
          ];

          if ($definition['langcode'] == 'und') {
            $definition['process'][$element]['language'] = 'und';
          }
        }
        break;

      case 'entity_reference_revisions':
+1 −4
Original line number Diff line number Diff line
@@ -79,10 +79,7 @@ class GatherContentFile extends ProcessPluginBase implements ContainerFactoryPlu
    $createDir = $this->fileSystem->realpath($this->configuration['uri_scheme']) . '/' . $fileDir;
    $this->fileSystem->prepareDirectory($createDir, FileSystemInterface::CREATE_DIRECTORY);

    if (is_array($value)) {
      return $this->client->downloadFiles($value, $this->configuration['uri_scheme'] . $fileDir, $language);
    }

    // The plugin does not handle_multiples, so we know that there is always one value.
    $fileId = $this->client->downloadFiles([$value], $this->configuration['uri_scheme'] . $fileDir, $language);

    if (empty($fileId[0])) {
+113 −0
Original line number Diff line number Diff line
<?php

namespace Drupal\gathercontent\Plugin\migrate\process;

use Cheppers\GatherContent\GatherContentClientInterface;
use Drupal\Component\Render\PlainTextOutput;
use Drupal\Core\File\FileSystem;
use Drupal\Core\File\FileSystemInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\media\Entity\Media;
use Drupal\media\Entity\MediaType;
use Drupal\migrate\MigrateExecutableInterface;
use Drupal\migrate\ProcessPluginBase;
use Drupal\migrate\Row;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Perform custom value transformation.
 *
 * @\Drupal\migrate\Annotation\MigrateProcessPlugin(
 *   id = "gather_content_media"
 * )
 *
 * @code
 * file:
 *   plugin: gather_content_media
 *   source: file
 *   uri_scheme: string
 *   file_dir: string
 *   language: string
 * @endcode
 */
class GatherContentMedia extends ProcessPluginBase implements ContainerFactoryPluginInterface {

  /**
   * GatherContent client.
   *
   * @var \Drupal\gathercontent\DrupalGatherContentClient
   */
  protected $client;

  /**
   * File system service.
   *
   * @var \Drupal\Core\File\FileSystem
   */
  protected $fileSystem;

  /**
   * {@inheritdoc}
   */
  public function __construct(array $configuration, $plugin_id, $plugin_definition, GatherContentClientInterface $client, FileSystem $fileSystem) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);
    $this->client = $client;
    $this->fileSystem = $fileSystem;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container->get('gathercontent.client'),
      $container->get('file_system')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
    if (empty($value)) {
      return NULL;
    }
    $language = $this->configuration['language'];
    $fileDir = PlainTextOutput::renderFromHtml(\Drupal::token()->replace($this->configuration['file_dir'], []));
    $createDir = $this->fileSystem->realpath($this->configuration['uri_scheme']) . '/' . $fileDir;
    $this->fileSystem->prepareDirectory($createDir, FileSystemInterface::CREATE_DIRECTORY);

    // The plugin does not handle_multiples, so we know that there is always one value.
    $fileId = $this->client->downloadFiles([$value], $this->configuration['uri_scheme'] . $fileDir, $language);
    $media_type = MediaType::load($this->configuration['bundle']);
    $fileId = reset($fileId);
    if (!$fileId) {
      return NULL;
    }
    $entity_ids = \Drupal::entityQuery('media')
      ->condition($media_type->getSource()->getSourceFieldDefinition($media_type)->getName() . '.target_id', $fileId)
      ->execute();
    if ($entity_ids) {
      $media_id = reset($entity_ids);
    }
    else {
      $mediaData = [
        'bundle' => $this->configuration['bundle'],
        'status' => 1,
        'title' => $value->filename,
        $media_type->getSource()->getSourceFieldDefinition($media_type)->getName() => [
          'target_id' => $fileId,
          'alt' => $value->altText,
        ],
      ];
      $media = Media::create($mediaData);
      $media->save();
      $media_id = $media->id();
    }
    return ['target_id' => $media_id];
  }

}