Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Drupal 8 file field to media entities simple migration. Does not move files in filesystem, just creates new media entities.
<?php
/**
* Create media entities from existing file fields.
*
* @link https://chromatichq.com/blog/migrating-drupal-file-fields-media-entities-without-migrate-module
*/
function MODULENAME_update_8001() {
// Nodes types that will get media migrated.
$node_types = ['article','event','page','session','sponsor'];
// Map old file fields => new media fields.
$map = [
'field_background_image' => 'field_background_img',
'field_image' => 'field_img',
'field_metadata_image' => 'field_metadata_img',
];
// Load all of the nodes.
$nodes = \Drupal::entityTypeManager()
->getStorage('node')
->loadByProperties(['type' => $node_types]);
$log = \Drupal::logger('dcavl_media');
foreach ($nodes as $node) {
/*** @var $node \Drupal\node\NodeInterface */
foreach ($map as $file_field => $media_field) {
// Verify that both the old and new fields exist on the node and that the file field has a value.
if ($node->hasField($media_field) && $node->hasField($file_field) && !empty($node->{$file_field}->entity)) {
// Loop through the values and make a list of unique media entity ids.
// If there is an existing media entity with the file uri, use it.
// Otherwise create a new media entity from the file.
$items = [];
foreach ($node->{$file_field} as $delta => $item) {
$existing = MODULENAME_load_media_image_by_file_uri($item->entity->getFileUri());
if ($existing) {
$log->notice(sprintf('Media entity found for "%s".', $item->entity->getFileUri()));
$items[$existing] = $existing;
}
else {
$log->notice(sprintf('No media entity found. Creating media entity for "%s".', $item->entity->getFileUri()));
$entity = MODULENAME_create_media_image_entity_from_file(
$item->entity,
$item->alt
);
$items[$entity->id()] = $entity->id();
}
}
// Update the media field with the list of media entity ids.
$node->{$media_field}->setValue($items);
}
}
$node->save();
$log->notice(sprintf('Updated images for node "%s".', $node->getTitle()));
}
}
<?php
use Drupal\file\FileInterface;
use Drupal\media\Entity\Media;
/**
* Creates a media image entity from a file entity.
*
* @param \Drupal\file\FileInterface $file
* The existing file object.
* @param string $alt
* The image alt text.
*
* @return \Drupal\media\Entity\Media
* The media entity.
*/
function MODULENAME_create_media_image_entity_from_file(FileInterface $file, $alt = NULL) {
$media_entity = Media::create([
'bundle' => 'image',
'uid' => '1',
'name' => $file->alt,
'status' => \Drupal\node\NodeInterface::PUBLISHED,
'field_media_image' => [
'target_id' => $file->id(),
'alt' => $alt,
],
]);
$media_entity->save();
return $media_entity;
}
/**
* Fetch a media image entity id by uri.
*
* @param string $uri
* Drupal file system uri.
*
* @return bool|int
* The found entity id, or FALSE.
*/
function MODULENAME_load_media_image_by_file_uri($uri) {
$ids = \Drupal::entityQuery('media')
->condition('status', 1)
->condition('field_media_image.entity.uri', $uri)
->execute();
if (!empty($ids)) {
return reset($ids);
}
return FALSE;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment