File_entity modülü, her dosya türü için dosya grupları oluşturmamıza izin veren harika bir moduldur.
{file_managed} tablosuna bir tür alanı ekler. Çekirdekte Drupal 7'den Drupal'a 8 dosya taşınması için yönetilen dosyalar Drupal 7'deki alansal olmayan varlıklardır, dolayısıyla çekirdekteki dosyaları taşıyamayız. Ancak file_entity modülü, dosya paketlerine alanlar eklemenize izin verir.
Nihai kaynak eklentisi şuna benziyor:
// modules/custom/my_custom_module/src/Plugin/migrate/source/FileEntity.php
namespace Drupal\my_custom_module\Plugin\migrate\source;
use Drupal\Core\Database\Query\Condition;
use Drupal\migrate\Row;
use Drupal\migrate_drupal\Plugin\migrate\source\d7\FieldableEntity;
/**
* Drupal 7 file_entity source from database.
*
* @MigrateSource(
* id = "file_entity",
* source_provider = "file"
* )
*/
class FileEntity extends FieldableEntity {
/**
* {@inheritdoc}
*/
public function query() {
$query = $this->select('file_managed', 'f')
->fields('f')
->orderBy('f.fid');
if (isset($this->configuration['type'])) {
$query->condition('f.type', $this->configuration['type']);
}
// Filter by scheme(s), if configured.
if (isset($this->configuration['scheme'])) {
$schemes = array();
// Accept either a single scheme, or a list.
foreach ((array) $this->configuration['scheme'] as $scheme) {
$schemes[] = rtrim($scheme) . '://';
}
$schemes = array_map([$this->getDatabase(), 'escapeLike'], $schemes);
// The uri LIKE 'public://%' OR uri LIKE 'private://%'.
$conditions = new Condition('OR');
foreach ($schemes as $scheme) {
$conditions->condition('uri', $scheme . '%', 'LIKE');
}
$query->condition($conditions);
}
return $query;
}
/**
* {@inheritdoc}
*/
public function prepareRow(Row $row) {
// Get Field API field values.
foreach (array_keys($this->getFields('file', $row->getSourceProperty('type'))) as $field) {
$fid = $row->getSourceProperty('fid');
$row->setSourceProperty($field, $this->getFieldValues('file', $field, $fid));
}
return parent::prepareRow($row);
}
/**
* {@inheritdoc}
*/
public function fields() {
return array(
'fid' => $this->t('File ID'),
'uid' => $this->t('The {users}.uid who added the file. If set to 0, this file was added by an anonymous user.'),
'filename' => $this->t('File name'),
'uri' => $this->t('The URI to access the file'),
'filemime' => $this->t('File MIME Type'),
'status' => $this->t('The published status of a file.'),
'timestamp' => $this->t('The time that the file was added.'),
'type' => $this->t('The type of this file.'),
);
}
/**
* {@inheritdoc}
*/
public function getIds() {
$ids['fid']['type'] = 'integer';
return $ids;
}
}}
Drupal 7'de dört dosya türü vardı.
Audio
Image (local)
Videos (local)
Videos (youtube)
Bunun için dört modül kuruyoruz.
media_entity_audio
media_entity_image
media_entity_video
video_embed_field
Ayrıca bu ortam türü eklentileri için dört ortam paketi oluşturuyoruz
Asıl verileri yazmadan önce dosyaları taşımamız gerekiyor.
# modules/custom/my_custom_module/migrations/my_files.yml
id: my_files
label: Files
migration_tags:
- Custom
source:
plugin: d7_file
constants:
source_base_path: 'sites/default/files/'
old_files_path: 'sites/default/files/migration-files'
process:
filename: filename
source_full_path:
-
plugin: concat
delimiter: /
source:
- constants/old_files_path
- filepath
-
plugin: urlencode
uri:
-
plugin: skip_youtube_files
source:
- '@source_full_path'
- uri
-
plugin: file_copy
filemime: filemime
# filesize is dynamically computed when file entities are saved, so there is
# no point in migrating it.
# filesize: filesize
status: status
created: timestamp
changed: timestamp
fid: fid
uid:
-
plugin: skip_on_empty
method: process
source: uid
-
plugin: migration
migration: my_users
destination:
plugin: entity:file
migration_dependencies:
required:
- my_users
Drupal 7'de, media_youtube modülü dosyaları depolamak için Youtube akış sarmalayıcıyı kullanıyor. Youtube videolarını görmezden gelmek için, bir süreç eklentisi yazmamız gerekiyor.
# modules/custom/my_custom_module/src/Plugin/migrate/process/SkipYoutubeVideos.php
namespace Drupal\my_custom_module\Plugin\migrate\process;
use Drupal\migrate\MigrateExecutableInterface;
use Drupal\migrate\MigrateSkipRowException;
use Drupal\migrate\ProcessPluginBase;
use Drupal\migrate\Row;
/** * Skip youtube videos. * * @MigrateProcessPlugin( * id = "skip_youtube_files" * ) */ class SkipYoutubeVideos extends ProcessPluginBase { /** * {@inheritdoc} */ public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) { if (parse_url(end($value), PHP_URL_SCHEME) == 'youtube') { throw new MigrateSkipRowException(); } return $value; } }
Drupal 7 ve Drupal 8 arasında dosya kimliğini aynı tuttuğumuzdan, medya gövdesini medya göçü için dosya kimliği ile aynı tutmak gerekiyor. Her dosya türü farklı alanlar grubuna sahiptir. Bu yüzden grup göçlerine göre yazmamız gereklidir.
# modules/custom/my_custom_module/migrations/my_media_audio.yml id: my_media_audio label: Media Audio migration_tags: - Custom source: plugin: file_entity type: audio constants: bundle: 'audio' process: mid: fid bundle: 'constants/bundle' langcode: plugin: default_value source: language default_value: "und" name: filename uid: - plugin: skip_on_empty method: process source: uid - plugin: migration migration: my_users status: status created: timestamp changed: timestamp # File field see media_entity.bundle.audio.yml. field_media_audio/target_id: fid # Title field. field_title: field_title # Transcript field. field_transcript: field_transcript destination: plugin: entity:media migration_dependencies: required: - my_files - my_users
Medya görüntülerini taşımak için, alt alan ve başlık için ayrılmış alanları resim alanına taşıdık.
# modules/custom/my_custom_module/migrations/my_media_audio.yml id: my_media_image label: Files migration_tags: - Custom source: plugin: file_entity type: image constants: bundle: 'image' process: mid: fid bundle: 'constants/bundle' langcode: plugin: default_value source: language default_value: "und" name: filename uid: - plugin: skip_on_empty method: process source: uid - plugin: migration migration: my_users status: status created: timestamp changed: timestamp # Image field see media_entity.bundle.image.yml. field_media_image/target_id: fid field_media_image/alt: field_file_image_alt_text/0/value field_media_image/title: field_file_image_title_text/0/value # Description field. field_description: field_image_description # Caption field. field_caption: field_caption destination: plugin: entity:media migration_dependencies: required: - my_files - my_users
Yerel videoyu içe aktarmak için URI şemasını video taşıma işlemine ekliyelim.
# modules/custom/my_custom_module/migrations/my_media_local_video.yml id: my_media_local_video label: Files migration_tags: - Custom source: plugin: file_entity type: video # See output of SELECT DISTINCT(SUBSTRING_INDEX(uri, ':', 1)) FROM file_managed WHERE type = 'video'; scheme: - "public" constants: bundle: 'local_video' process: mid: fid bundle: 'constants/bundle' langcode: plugin: default_value source: language default_value: "und" name: filename uid: - plugin: skip_on_empty method: process source: uid - plugin: migration migration: my_users status: status created: timestamp changed: timestamp # File field see media_entity.bundle.local_video.yml. field_media_video/target_id: fid # Title field. field_title: field_video_title # Transcript field. field_transcript: field_transcript destination: plugin: entity:media migration_dependencies: required: - my_files - my_users
Youtube videolarını içe aktarmak için URI embed alanının youtube video youtube://v/video_id URL'sine ihtiyacı var, bu nedenle video kimliğini URL'ye dönüştürmek için bir işlem eklentisi oluşturuyoruz.
# modules/custom/my_custom_module/migrations/my_media_video.yml id: my_media_video label: Files migration_tags: - Custom source: plugin: file_entity type: video # See output of SELECT DISTINCT(SUBSTRING_INDEX(uri, ':', 1)) FROM file_managed WHERE type = 'video'; scheme: - "youtube" constants: bundle: 'video' process: mid: fid bundle: 'constants/bundle' langcode: plugin: default_value source: language default_value: "und" name: filename uid: - plugin: skip_on_empty method: process source: uid - plugin: migration migration: my_users status: status created: timestamp changed: timestamp # Embed field see media_entity.bundle.video.yml. field_media_video_embed_field: plugin: youtube source: uri # Title field. field_title: field_video_title # Transcript field. field_transcript: field_transcript destination: plugin: entity:media migration_dependencies: required: - my_files - my_users The Youtube process plugin
Bu taşıma işlemlerini migrate_drush kullanarak yürütüyoruz.
Kaynak: gist
mutlu kodlamalar