Last active
November 18, 2023 02:26
-
-
Save herbdool/d50baf524f5a55f55786a5d522153ed5 to your computer and use it in GitHub Desktop.
Convert D7 Media to Backdrop Media
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 | |
* | |
* @todo add batching. | |
*/ | |
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