Skip to content

Instantly share code, notes, and snippets.

@herbdool
Last active October 11, 2023 15:27
Show Gist options
  • Save herbdool/556b5246544868f66debcaaa0c2ed5b3 to your computer and use it in GitHub Desktop.
Save herbdool/556b5246544868f66debcaaa0c2ed5b3 to your computer and use it in GitHub Desktop.
Convert Field Collection to Paragraph
<?php
/**
* Convert Field Collection to Paragraphs
*
* bee php-script convert-fc2p.php
*
* @todo add batching.
*
* - Both field_collection and paragraphs need to be enabled.
* - It creates unique paragraph types for each field collection since FC
* can't be shared across entity types.
* - This hasn't been tested with nested field collection fields. Not sure
* if that's possible.
* - Manually update field collection in views. Can probably search and
* replace.
* - Manually drop tables when ready to move on.
* - After running, this go through all paragraph field configuration to
* ensure they're set up properly.
*/
$child_field_names = convert_config();
convert_child_field_tables($child_field_names);
convert_to_paragraph_tables();
/**
* Convert config files
*/
function convert_config() {
$paragraph_bundles = [];
$field_names = [];
$child_field_names = [];
// Convert field_collection bundles
$config_bundle_names = config_get_names_with_prefix('field.bundle.field_collection_item');
foreach ($config_bundle_names as $config_bundle_name) {
$config_fc = config($config_bundle_name);
// Create a paragraph bundle based on field collection field name.
$new_bundle = substr($config_fc->get('bundle'), 6);
$config_p = config('field.bundle.paragraphs_item.' . $new_bundle);
$config_p->setData($config_fc->getData());
$config_p->set('entity_type', 'paragraphs_item');
$config_p->set('bundle', $new_bundle);
$config_p->save();
$config_fc->delete();
$paragraph_bundles[] = $new_bundle;
}
// Create paragraph types based on the bundle.
foreach ($paragraph_bundles as $paragraph_bundle) {
$config_p = config('paragraphs.type.' . $paragraph_bundle);
$config_p->set('bundle', $paragraph_bundle);
$config_p->set('name', $paragraph_bundle);
$config_p->set('label', ucfirst(str_replace('_', ' ', $paragraph_bundle)));
$config_p->set('description', '');
$config_p->set('locked', 1);
$config_p->set('allow_unpublish', 1);
$config_p->save();
}
// Convert field_collection fields
$config_fields = config_get_names_with_prefix('field.field');
foreach ($config_fields as $config_field) {
$config = config($config_field);
$field_name = $config->get('field_name');
if ($config->get('type') == 'field_collection') {
$config->set('type', 'paragraphs');
$config->set('module', 'paragraphs');
$config->save();
$field_names[] = $field_name;
}
}
// Convert field collection instances.
$config_all_instances = config_get_names_with_prefix('field.instance');
foreach($config_all_instances as $cai) {
$config = config($cai);
$field_name = $config->get('field_name');
if (in_array($field_name, $field_names)) {
$config->set('widget.type', 'paragraphs_embed');
$config->set('widget.module', 'paragraphs');
$config->set('settings.title', 'Paragraph');
$config->set('settings.title_multiple', 'Paragraphs');
$displays = $config->get('display');
foreach ($displays as $key => $display) {
$config->set('display.' . $key . '.type', 'paragraphs_view');
$config->set('display.' . $key . '.module', 'paragraphs');
}
}
$config->save();
}
// Convert child field instances.
$config_field_instances = config_get_names_with_prefix('field.instance.field_collection_item');
foreach ($config_field_instances as $config_field_instance) {
$config_fc = config($config_field_instance);
$field_name = $config_fc->get('field_name');
$new_bundle = substr($config_fc->get('bundle'), 6);
$config_p = config('field.instance.paragraphs_item.' . $new_bundle . '.' . $field_name);
$config_p->setData($config_fc->getData());
$config_p->set('entity_type', 'paragraphs_item');
$config_p->set('bundle', $new_bundle);
$config_p->save();
$config_fc->delete();
$child_field_names[] = $field_name;
}
$config = config('entity.view_modes');
$field_collection_view_modes = $config->get('view_modes.field_collection_item');
if (!empty($field_collection_view_modes)) {
$config->set('view_modes.paragraphs_item', $field_collection_view_modes);
$config->clear('view_modes.field_collection_item');
}
$config->save();
return $child_field_names;
}
/**
* Convert child field tables
*/
function convert_child_field_tables($child_field_names) {
foreach($child_field_names as $field_name) {
db_update('field_data_' . $field_name)
->fields(array(
'entity_type' => 'paragraphs_item',
'bundle' => substr($field_name, 6)
))
->condition('entity_type', 'field_collection_item')
->execute();
db_update('field_revision_' . $field_name)
->fields(array(
'entity_type' => 'paragraphs_item',
'bundle' => substr($field_name, 6)
))
->condition('entity_type', 'field_collection_item')
->execute();
}
}
/**
* Convert to paragraph tables
*/
function convert_to_paragraph_tables() {
// field_collection_item > paragraphs_item
$result = db_select('field_collection_item', 'fci')
->fields('fci')
->execute();
foreach ($result as $row) {
db_insert('paragraphs_item')
->fields(array(
'item_id' => $row->item_id,
'revision_id' => $row->item_id,
'bundle' => substr($row->field_name, 6),
'field_name' => $row->field_name,
'archived' => $row->archived,
'status' => 1,
))
->execute();
}
// It's likely the revision is incorrect for field_collection_item so pull
// it from field_collection_item_revision.
$query = db_select('field_collection_item_revision', 'fcir')
->groupBy('item_id');
$query->fields('fcir', ['item_id']);
$query->addExpression('MAX(revision_id)', 'revision_id');
$result = $query->execute();
foreach ($result as $row) {
db_update('paragraphs_item')
->fields(['revision_id' => $row->revision_id])
->condition('item_id', $row->item_id)
->execute();
}
// field_collection_item_revision > paragraphs_item_revision
$result = db_select('field_collection_item_revision', 'fcir')
->fields('fcir')
->execute();
foreach ($result as $row) {
db_insert('paragraphs_item_revision')
->fields(array(
'item_id' => $row->item_id,
'revision_id' => $row->revision_id,
))
->execute();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment