Created
October 24, 2024 02:00
-
-
Save herbdool/eebe5d0b612e07bf81e29cf7a02207f0 to your computer and use it in GitHub Desktop.
Convert embedded media (images and video) from Drupal 7 to Backdrop equivalents
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Convert d7 media to Backdrop media | |
* | |
* bee php-script convert-d7media2backdrop.php | |
* | |
* Requires video_filter module in Backdrop. | |
* Will convert from Drupal 7 media module format. | |
*/ | |
define('VIDEO_SETTINGS', array( | |
'set_alignment' => TRUE, | |
)); | |
/** | |
* Video Codecs | |
* The key is first part of the uri in file_managed. | |
* The value is the part that goes before the unique code. | |
*/ | |
define('VIDEO_CODECS', array( | |
'youtube:' => '//www.youtube.com/watch?v=', | |
'vimeo:' => '//www.vimeo.com/watch?v=', | |
# Add more. | |
)); | |
/** | |
* Don't edit below | |
*/ | |
$number_updated = array(); | |
$number_updated['Blocks'] = convert_custom_blocks(); | |
$number_updated['Layouts'] = convert_layouts(); | |
$number_updated['Entity Fields'] = convert_entity_fields(); | |
print_r($number_updated); | |
/** | |
* Convert media in custom blocks | |
*/ | |
function convert_custom_blocks() { | |
$custom_blocks = config_get_names_with_prefix('block.custom'); | |
$num = 0; | |
foreach ($custom_blocks as $custom_block) { | |
$block_updated = FALSE; | |
$block_config = config($custom_block); | |
$update = update_string_with_conversions($block_config->get('body.value')); | |
if ($update != $block_config->get('body.value')) { | |
$block_config->set('body.value', $update); | |
$block_updated = TRUE; | |
} | |
$translations = $block_config->get('translations'); | |
if ($translations) { | |
foreach ($translations as $langcode => $translation) { | |
$update = update_string_with_conversions($translation['body']['value']); | |
if ($update != $translation['body']['value']) { | |
$block_config->set('translations.' . $langcode . '.body.value', $update); | |
$block_updated = TRUE; | |
} | |
} | |
} | |
if ($block_updated) { | |
$block_config->save(); | |
$num++; | |
} | |
} | |
return $num; | |
} | |
/** | |
* Convert media in layouts | |
*/ | |
function convert_layouts() { | |
$layouts = config_get_names_with_prefix('layout.layout'); | |
$num = 0; | |
foreach ($layouts as $layout) { | |
$layout_updated = FALSE; | |
$layout_config = config($layout); | |
$content_items = $layout_config->get('content'); | |
foreach ($content_items as $uuid => $item) { | |
if ($item['plugin'] != 'layout:custom_block') { | |
continue; | |
} | |
$update = update_string_with_conversions($item['data']['settings']['content']); | |
$layout_config->set('content.' . $uuid . '.data.settings.content', $update); | |
$layout_updated = TRUE; | |
} | |
if ($layout_updated) { | |
$layout_config->save(); | |
$num++; | |
} | |
} | |
return $num; | |
} | |
/** | |
* Convert media in entity fields. | |
*/ | |
function convert_entity_fields() { | |
$languages = language_list(TRUE, TRUE); | |
$langcodes = array_keys($languages); | |
$langcodes[] = 'und'; | |
$num = 0; | |
$field_bundles = field_info_bundles(); | |
$entity_types = array_keys($field_bundles); | |
foreach ($entity_types as $entity_type) { | |
$query = new EntityFieldQuery(); | |
$query = $query->entityCondition('entity_type', $entity_type) | |
->addTag('DANGEROUS_ACCESS_CHECK_OPT_OUT'); | |
$result = $query->execute(); | |
$fields = field_info_fields(); | |
$convert_fields = array(); | |
foreach ($fields as $key => $field) { | |
if (!in_array($entity_type, $field['entity_types'])) { | |
continue; | |
} | |
if ($field['type'] == 'text_with_summary') { | |
$convert_fields[] = array( | |
'name' => $field['field_name'], | |
'cardinality' => $field['cardinality'], | |
'columns' => array('value', 'summary'), | |
); | |
} | |
if ($field['type'] == 'text_long') { | |
$convert_fields[] = array( | |
'name' => $field['field_name'], | |
'cardinality' => $field['cardinality'], | |
'columns' => array('value'), | |
); | |
} | |
} | |
// Entity doesn't have fields that concern us. | |
if (empty($convert_fields)) { | |
continue; | |
} | |
foreach ($result[$entity_type] as $id => $item) { | |
$entity = entity_load($entity_type, $id); | |
$field_updated = FALSE; | |
foreach ($convert_fields as $convert_field) { | |
$field_name = $convert_field['name']; | |
foreach ($langcodes as $langcode) { | |
if (!isset($entity->$field_name[$langcode])) { | |
continue; | |
} | |
foreach ($convert_field['columns'] as $column) { | |
for ($i = 0; $i < $convert_field['cardinality']; $i++) { | |
$original = $entity->$field_name[$langcode][$i][$column]; | |
$update = update_string_with_conversions($original); | |
if ($update != $original) { | |
$entity->$field_name[$langcode][$i][$column] = $update; | |
$field_updated = TRUE; | |
} | |
} | |
} | |
} | |
} | |
if ($field_updated) { | |
$entity->save(); | |
$num++; | |
} | |
} | |
} | |
return $num; | |
} | |
/** | |
* Update string with conversion. | |
* | |
* @param string $string | |
* @return string | |
* Updated string with new image formats. | |
*/ | |
function update_string_with_conversions($string) { | |
$chunks = preg_split('/\}\}\]\]/', $string); | |
$searches = array(); | |
$replacements = array(); | |
foreach ($chunks as $chunk) { | |
$matches = array(); | |
preg_match('/\[\[\{(?<=\[\[\{)(.*)/', $chunk, $matches); | |
if (empty($matches)) { | |
continue; | |
} | |
$media = json_decode($matches[0] . '}}]]'); | |
$fid = $media[0][0]->fid; | |
$file = file_load($fid); | |
if (!is_object($file)) { | |
continue; | |
} | |
if ($file->type == 'image') { | |
$replacement = format_image($media[0][0], $file); | |
} | |
if ($file->type == 'video') { | |
$replacement = format_video($media[0][0], $file); | |
} | |
if (isset($replacement)) { | |
$searches[] = $matches[0] . '}}]]'; | |
$replacements[] = $replacement; | |
} | |
} | |
return str_replace($searches, $replacements, $string); | |
} | |
/** | |
* Format Image | |
* | |
* @param object $media | |
* @param object $file | |
* @return string | |
*/ | |
function format_image($media, $file) { | |
// Example from D7 embedded image: | |
// [[{"fid":"3231","view_mode":"default","fields":{"format":"default","alignment":"","field_file_image_alt_text[und][0][value]":"Graphic","field_file_image_title_text[und][0][value]":false},"type":"media","field_deltas":{"3":{"format":"default","alignment":"","field_file_image_alt_text[und][0][value]":"Graphic","field_file_image_title_text[und][0][value]":false}},"attributes":{"alt":"Graphic","height":"251","width":"496","style":"display: block; margin-left: auto; margin-right: auto;","class":"media-element file-default","data-delta":"3"}}]] | |
$file_directory = config_get('system.core', 'file_public_path'); | |
$src = preg_replace('/public:\/\//', '/' . $file_directory . '/', $file->uri); | |
$alt = isset($media->attributes->alt) ? $media->attributes->alt : ''; | |
$caption = isset($media->attributes->title) ? $media->attributes->title : ''; | |
// Get width and height. | |
$width = isset($file->width) ? $file->width : ''; | |
$height = isset($file->height) ? $file->height : ''; | |
// Get from display mode if it has either width or height set. | |
// @todo Figure out what to do about cropping. | |
$view_mode = $media->view_mode; | |
$config_file_display = config('file_display.image'); | |
$formatter = $config_file_display->get($view_mode . '.formatter'); | |
$image_style = $config_file_display->get($view_mode . '.settings.' . $formatter . '.image_style'); | |
if ($image_style) { | |
$config_image_style = config('image.style.' . $image_style); | |
$image_style_width = $config_image_style->get('effects.data.width'); | |
$image_style_height = $config_image_style->get('effects.data.height'); | |
if ($image_style_width) { | |
$width = $image_style_width; | |
} | |
if ($image_style_height) { | |
$width = $image_style_height; | |
} | |
} | |
// If set in the embedded json use that instead. | |
if (isset($media->attributes->width)) { | |
$width = $media->attributes->width; | |
} | |
if (isset($media->attributes->height)) { | |
$height = $media->attributes->height; | |
} | |
// Maybe don't use original if it's wider than the screen. | |
// 72.25rem = 1040 px (base font 14.4 px) | |
if ($width > 1040) { | |
$width = 1040; | |
$height = ''; | |
} | |
$alignment = isset($media->fields->alignment) ? $media->fields->alignment : ''; | |
// Example result: | |
// <img alt="hello" data-align="right" data-caption="Bye" data-file-id="1" height="533" src="/files/field/image/card1-layout_1.png" width="800" /> | |
$image = '<img alt="' . $alt . '" data-file-id="' . $file->fid . '" '; | |
$image .= $alignment ? 'data-align="' . $alignment . '" ' : ''; | |
$image .= $caption ? 'data-caption="' . $caption . '" ' : ''; | |
$image .= 'src="' . $src . '" width="' . $width . '" height="' . $height . '" />'; | |
return $image; | |
} | |
/** | |
* Format Video | |
* Returns a Video Filter format. | |
* | |
* @param object $media | |
* @param object $file | |
* @return string | |
*/ | |
function format_video($media, $file) { | |
// Example D7 embedded video: | |
// [[{"fid":"3992","view_mode":"media_original","fields":{"format":"media_original","alignment":"left"},"link_text":"Test","type":"media","field_deltas":{"1":{"format":"media_original","alignment":"left"}},"attributes":{"class":"media-element file-media-original media-wysiwyg-align-left","data-delta":"1"}}]] | |
// Converted (examples): | |
// [video://www.vimeo.com/123456] | |
// [video:/www.youtube.com/watch?v=123456 width:900 align:left] | |
// Ignoring view_mode and format since all these videos are being displayed. | |
// Ignoring link text. | |
$width = ''; | |
$height = ''; | |
if (isset($media->attributes->width)) { | |
$width = $media->attributes->width; | |
} | |
if (isset($media->attributes->height)) { | |
$height = $media->attributes->height; | |
} | |
// Maybe don't use original if it's wider than the screen. | |
// 72.25rem = 1040 px (base font 14.4 px) | |
if ($width > 1040) { | |
$width = 1040; | |
$height = ''; | |
} | |
$alignment = isset($media->fields->alignment) ? $media->fields->alignment : ''; | |
$uri_parts = explode('/', $file->uri); | |
$uri = VIDEO_CODECS[$uri_parts[0]] . $uri_parts[3]; | |
if (empty($uri)) { | |
return NULL; | |
} | |
$video = '[video:' . $uri; | |
$video .= $width ? ' width:' . $width : ''; | |
$video .= $height ? ' height:' . $height : ''; | |
if (VIDEO_SETTINGS['set_alignment']) { | |
$video .= $alignment ? ' align:' . $alignment : ''; | |
} | |
$video .= ']'; | |
return $video; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment