Skip to content

Instantly share code, notes, and snippets.

@pcambra
Last active June 8, 2023 15:41
Show Gist options
  • Save pcambra/9e82652a3a1212d4c30e7d8561708500 to your computer and use it in GitHub Desktop.
Save pcambra/9e82652a3a1212d4c30e7d8561708500 to your computer and use it in GitHub Desktop.
How to change the type/bundle of an entity/node
<?php
$entity_type_id = 'node';
$type = 'new_type';
$field_base_table_name = 'node__field_data';
// Fill nids with the entity ids you want to switch.
// $entity_ids = [...]
$storage = \Drupal::entityTypeManager()->getStorage($entity_type_id);
$definitions = \Drupal::service('entity_field.manager')->getFieldDefinitions($entity_type_id, $type);
$database = Database::getConnection();
// Get the names of the base tables.
$base_table_names = [];
$base_table_names[$storage->getBaseTable()] = $storage->getBaseTable();
$base_table_names[$storage->getDataTable()] = $storage->getDataTable();
// (Note that revision base tables don't have the bundle.)
$table_mapping = \Drupal::service('entity_type.manager')->getStorage($entity_type_id)->getTableMapping();
// Get the names of the field tables for fields on the service node type.
$field_table_names = [];
// Add the base table for all fields.
$field_table_names['node__field_data'] = $field_base_table_name;
/** @var \Drupal\Core\Field\FieldDefinitionInterface $field */
foreach ($definitions as $field) {
if (!$field->isComputed()) {
$field_table = $table_mapping->getFieldTableName($field->getName());
if ($database->schema()->tableExists($field_table)) {
$field_table_names[$field_table] = $field_table;
}
$field_storage_definition = $field->getFieldStorageDefinition();
$field_revision_table = $table_mapping->getDedicatedRevisionTableName($field_storage_definition);
// Field revision tables DO have the bundle!
if ($database->schema()->tableExists($field_revision_table)) {
$field_table_names[$field_revision_table] = $field_revision_table;
}
}
}
// Remove general base and revision tables that could be in some fields and
// those don't have the entity_id field, bundle or are handled by the base
// fields.
unset($field_table_names[$storage->getBaseTable()]);
unset($field_table_names[$storage->getDataTable()]);
unset($field_table_names[$storage->getRevisionTable()]);
unset($field_table_names[$storage->getRevisionDataTable()]);
// Base tables have 'nid' and 'type' columns. (@TODO: This is for nodes)
foreach ($base_table_names as $table_name) {
$database
->update($table_name)
->fields(['type' => $type])
->condition('nid', $entity_ids, 'IN')
->execute();
}
// Field tables have 'entity_id' and 'bundle' columns.
foreach ($field_table_names as $table_name) {
$database
->update($table_name)
->fields(['bundle' => 'partner_country'])
->condition('entity_id', $entity_ids, 'IN')
->execute();
}
@pcambra
Copy link
Author

pcambra commented Jun 8, 2023

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment