私はD7からD8への移行に移行モジュールを使用しており、移行全体をコードで手動で記述しています(移行をより細かく制御するため、組み込みのD7移行モジュールを使用するのではありません)。
私は次のような構造になっています。D7サイトには、画像がファイルエンティティとして保存される画像フィールドがあります。 D8サイトでは、画像フィールドはメディアエンティティへのエンティティ参照です(メディアエンティティには画像フィールドがあります)。
もともと、私は私のイメージの移行のために以下を持っていました:
id: image_files
source:
plugin: legacy_images
constants:
source_base_path: http://example.com/
destination:
plugin: 'entity:file'
process:
fid: fid
filename: filename
source_full_path:
-
plugin: concat
delimiter: /
source:
- constants/source_base_path
- uri
-
plugin: urlencode
uri:
plugin: file_copy
source:
- '@source_full_path'
- uri
filemime: filemime
status: status
記事ノードの移行ファイルには、次のものが含まれていました。
'field_article_image/target_id':
plugin: migration
migration: image_files
source: field_article_image
しかし、これはうまくいかないことに気づきました。 image_filesマイグレーションからのtarget_idは、メディアエンティティIDではなく、実際にはファイルエンティティIDでした。理想的な世界では、この中間のステップを作成し、ファイルエンティティをメディアエンティティに移行し、その移行を記事の移行にマッピングする3番目の移行を作成する方法を見つけたいと思います。しかし、私はこれを行う良い方法を理解できません。
プランBは、イメージの移行用のプロセスプラグインを作成するだけです。これにより、手動でファイルエンティティを作成し、メディアエンティティに添付して、その移行をArticlesに渡します(これにより、中央のステップが削除されます)。ただし、メディアエンティティはロールバックできますが、ファイルエンティティはロールバックできませんでした。
少し異なる方法を選択することになりました。通常のファイルインポートを作成し、その移行をメディアエンティティ参照フィールドのソースとして設定してから、2番目のプロセスプラグイン「MediaGenerate」を適用して、FIDを新しいメディアのtarget_idに変換しました。
<?php
namespace Drupal\my_migration\Plugin\migrate\process;
use Drupal\media_entity\Entity\Media;
use Drupal\migrate\MigrateExecutableInterface;
use Drupal\migrate\MigrateException;
use Drupal\migrate\Row;
use Drupal\migrate_plus\Plugin\migrate\process\EntityGenerate;
/**
* Generate a media entity with specified metadata.
*
* This plugin is to be used by migrations which have media entity reference
* fields.
*
* Available configuration keys:
* - destinationField: the name of the file field on the media entity.
*
* @code
* process:
* 'field_files/target_id':
* -
* plugin: migration
* source: files
* -
* plugin: media_generate
* destinationField: image
*
* @endcode
*
* @MigrateProcessPlugin(
* id = "media_generate"
* )
*/
class MediaGenerate extends EntityGenerate {
/**
* {@inheritdoc}
*/
public function transform($value, MigrateExecutableInterface $migrateExecutable, Row $row, $destinationProperty) {
if (!isset($this->configuration['destinationField'])) {
throw new MigrateException('Destination field must be set.');
}
// First load the target_id of the file referenced via the migration.
/* @var /Drupal/file/entity/File $file */
$file = $this->entityManager->getStorage('file')->load($value);
if (empty($file)) {
throw new MigrateException('Referenced file does not exist');
}
// Creates a media entity if the lookup determines it doesn't exist.
$fileName = $file->label();
if (!($entityId = parent::transform($fileName, $migrateExecutable, $row, $destinationProperty))) {
return NULL;
}
$entity = Media::load($entityId);
$fileId = $file->id();
$entity->{$this->configuration['destinationField']}->setValue($fileId);
$entity->save();
return $entityId;
}
}
私は受け入れられた回答に感謝しましたが、すでにいくつかの非推奨の定義があり、altおよびtitle画像のプロパティの投稿をサポートしていませんでした。したがって、私はそれをサポートし、最新のDrupal 8.6.x.
<?php
namespace Drupal\my_migration\Plugin\migrate\process;
use Drupal\media\Entity\Media;
use Drupal\migrate\MigrateExecutableInterface;
use Drupal\migrate\MigrateException;
use Drupal\migrate\Row;
use Drupal\migrate_plus\Plugin\migrate\process\EntityGenerate;
/**
* Generate a media entity with specified metadata.
*
* This plugin is to be used by migrations which have media entity reference
* fields.
*
* Available configuration keys:
* - destinationField: the name of the file field on the media entity.
*
* @code
* process:
* 'field_files/target_id':
* -
* plugin: migration_lookup
* migration: my_file_migration
* source: field_image/0/fid
* -
* plugin: media_generate
* destinationField: image
* imageAltSource: field_image/0/alt
* imageTitleSource: field_image/0/title
*
* @endcode
*
* If image_alt_source and/or image_title_source configuration parameters
* are provided, alt and/or title image properties will be fetched from provided
* source fields (if available) and pushed into media entity
*
* @MigrateProcessPlugin(
* id = "media_generate"
* )
*/
class MediaGenerate extends EntityGenerate {
/**
* {@inheritdoc}
*/
public function transform($value, MigrateExecutableInterface $migrateExecutable, Row $row, $destinationProperty) {
if (!isset($this->configuration['destinationField'])) {
throw new MigrateException('Destination field must be set.');
}
// First load the target_id of the file referenced via the migration.
/* @var /Drupal/file/entity/File $file */
$file = $this->entityManager->getStorage('file')->load($value);
if (empty($file)) {
throw new MigrateException('Referenced file does not exist');
}
// Creates a media entity if the lookup determines it doesn't exist.
$fileName = $file->label();
if (!($entityId = parent::transform($fileName, $migrateExecutable, $row, $destinationProperty))) {
return NULL;
}
$entity = Media::load($entityId);
$fileId = $file->id();
$destinationFieldValues = $entity->{$this->configuration['destinationField']}->getValue();
$destinationFieldValues[0]['target_id'] = $fileId;
$this->insertPropertyIntoDestinationField($destinationFieldValues, $row, 'alt', 'imageAltSource');
$this->insertPropertyIntoDestinationField($destinationFieldValues, $row, 'title', 'imageTitleSource');
$entity->{$this->configuration['destinationField']}->setValue($destinationFieldValues);
$entity->save();
return $entityId;
}
protected function insertPropertyIntoDestinationField(array &$destinationFieldValues, Row $row, $propertyKey, $configurationKey) {
// Set alt and title into media entity if not empty
if (isset($this->configuration[$configurationKey])) {
$propertyValue = $row->getSourceProperty($this->configuration[$configurationKey]);
if (!empty($propertyValue)) {
$destinationFieldValues[0][$propertyKey] = $propertyValue;
}
}
}
}
メディアはエンティティタイプであるため、独自の移行を作成する必要があります。ファイルテーブルから新しいソースを生成できます。ここに例があります
https://Gist.github.com/jibran/8e7cd2319e873858dd49a272227a4fd2
次にmigration_lookup
このようにフィールドをマッピングできます。
field_d8_media_image/0/target_id:
plugin: migration_lookup
migration: my_media_image
source: field_d7_image/0/fid
Drupal 8のファイルをメディアエンティティに移行する場合は、このモジュールを使用できます: https://www.drupal.org/project/migrate_file_to_media
メディア参照フィールドを自動的に作成するDrushスクリプトがあります。さらに、バイナリハッシュを使用して重複画像を検出します。そして、それは翻訳をサポートします。