Skip to content

Instantly share code, notes, and snippets.

@mglaman
Created August 1, 2016 20:14
Show Gist options
  • Save mglaman/f465a8028ad99c12a6b85b1d14a703fe to your computer and use it in GitHub Desktop.
Save mglaman/f465a8028ad99c12a6b85b1d14a703fe to your computer and use it in GitHub Desktop.
<?php
function address_test_bullshit() {
// Save a list of processed fields so that we can do clean up once the
// original data is migrated.
$processed_fields = [];
$columns_to_add = ['family_name', 'additional_name', 'given_name'];
$field_type_manager = \Drupal::getContainer()->get('plugin.manager.field.field_type');
$address_definition = $field_type_manager->getDefinition('address');
/** @var \Drupal\address\Plugin\Field\FieldType\AddressItem $class */
$class = $address_definition['class'];
$field_schema = $class::schema($this);
$schema = \Drupal::database()->schema();
$entity_type_manager = \Drupal::getContainer()->get('entity_type.manager');
$entity_field_manager = \Drupal::getContainer()->get('entity_field.manager');
$entity_field_map = \Drupal::getContainer()->get('entity_field.manager')->getFieldMapByFieldType('address');
// The key-value collection for tracking installed storage schema.
$entity_storage_schema_sql = \Drupal::keyValue('entity.storage_schema.sql');
$entity_definitions_installed = \Drupal::keyValue('entity.definitions.installed');
foreach ($entity_field_map as $entity_type_id => $field_map) {
$entity_storage = $entity_type_manager->getStorage($entity_type_id);
// Only SQL storage based entities are supported / throw known exception.
if ($entity_storage instanceof SqlContentEntityStorage) {
$field_storage_definitions = $entity_field_manager->getFieldStorageDefinitions($entity_type_id);
/** @var Drupal\Core\Entity\Sql\DefaultTableMapping $table_mapping */
$table_mapping = $entity_storage->getTableMapping($field_storage_definitions);
// Only need field storage definitions of address fields.
/** @var \Drupal\Core\Field\FieldStorageDefinitionInterface $field_storage_definition */
foreach (array_intersect_key($field_storage_definitions, $field_map) as $field_storage_definition) {
// Get the current field's name.
$field_name = $field_storage_definition->getName();
$processed_fields[$field_name] = $entity_type_id;
// We need to know the schema column name for the old `recipient` value.
$initial_from_field = $table_mapping->getFieldColumnName($field_storage_definition, 'recipient');
// Get the name of the field's table.
$table = $table_mapping->getFieldTableName($field_name);
// Loop over each new column and add it as a schema column change.
foreach ($columns_to_add as $column_id) {
$column = $table_mapping->getFieldColumnName($field_storage_definition, $column_id);
// Add `initial_from_field` to the new spec, as this will copy over
// the entire data.
$spec = $field_schema['columns'][$column_id];
// We will not seed data into `additional_name`.
if ($column_id != 'additional_name') {
$spec += [
'initial_from_field' => $initial_from_field,
];
}
// Add the new column.
$schema->addField($table, $column, $spec);
// Update the installed storage schema for this field as well.
$key = "$entity_type_id.field_schema_data.$field_name";
if ($field_schema_data = $entity_storage_schema_sql->get($key)) {
$field_schema_data[$table]['fields'][$column_id] = $field_schema['columns'][$column_id];
$entity_storage_schema_sql->set($key, $field_schema_data);
}
if ($table_mapping->allowsSharedTableStorage($field_storage_definition)) {
$key = "$entity_type_id.field_storage_definitions";
if ($definitions = $entity_definitions_installed->get($key)) {
$definitions[$field_name] = $field_storage_definition;
$entity_definitions_installed->set($key, $definitions);
}
}
}
// Once all columns added, and data copied. Delete the field.
$schema->dropField($table, $initial_from_field);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment