function multiversion_update_8007 in Multiversion 8
Create missing revisionable fields in the revision table.
File
- ./
multiversion.install, line 301
Code
function multiversion_update_8007() {
$connection = Database::getConnection();
if ($connection instanceof Connection) {
$schema = $connection
->schema();
$entity_type_manager = \Drupal::entityTypeManager();
$manager = \Drupal::service('multiversion.manager');
// Find all supported entities.
$entity_types = $manager
->getSupportedEntityTypes();
// Loop through each one.
foreach ($entity_types as $entity_type_id => $entity_type) {
$id_key = $entity_type
->getKey('id');
/** @var \Drupal\Core\Entity\Sql\SqlContentEntityStorage $storage */
$storage = $entity_type_manager
->getStorage($entity_type_id);
// Get the tables name used for base table and revision table.
$table_base = $entity_type
->isTranslatable() ? $entity_type
->getDataTable() : $entity_type
->getBaseTable();
$table_revision = $entity_type
->isTranslatable() ? $entity_type
->getRevisionDataTable() : $entity_type
->getRevisionTable();
// Block content definition doesn't include the revision field table.
// So get it.
/** @var \Drupal\Core\Entity\Sql\TableMappingInterface $table_mapping */
$table_mapping = $storage
->getTableMapping();
$tables = $table_mapping
->getTableNames();
if (!$table_revision && in_array($entity_type_id . '_field_revision', $tables)) {
$table_revision = $entity_type_id . '_field_revision';
}
elseif (!$table_revision && in_array($entity_type_id . '_revision', $tables)) {
$table_revision = $entity_type_id . '_revision';
}
if ($schema
->tableExists($table_base) && $table_revision) {
// Get data from base table.
$table_base_results = $connection
->select($table_base)
->fields($table_base)
->execute()
->fetchAll();
// Get data from revision table.
$table_revision_results = $connection
->select($table_revision)
->fields($table_revision)
->execute()
->fetchAll();
if (in_array($table_revision, $tables)) {
$table_revision_fields = $table_mapping
->getFieldNames($table_revision);
$entity_field_manager = \Drupal::service('entity_field.manager');
$fields = $entity_field_manager
->getBaseFieldDefinitions($entity_type_id);
$new_field_storage_definitions = [];
// Loop through all the fields, if the field exists in the new
// revision table mapping and it doesn't exist in the database,
// create the new field.
foreach ($fields as $field_name => $field) {
if (in_array($field_name, $table_revision_fields) && !$schema
->fieldExists($table_revision, $field_name)) {
$new_field_storage_definitions[] = $field
->getFieldStorageDefinition($field
->getName(), $entity_type_id);
}
}
if (!empty($new_field_storage_definitions)) {
// Remove all data from revision table before adding new fields.
$connection
->truncate($table_revision)
->execute();
foreach ($new_field_storage_definitions as $storage_definition) {
\Drupal::service('field_storage_definition.listener')
->onFieldStorageDefinitionCreate($storage_definition);
}
}
// If the revision table has been updated (new field has been added),
// complete new fields with data from base table.
if (!empty($new_field_storage_definitions)) {
$table_base_results_keyed = [];
foreach ($table_base_results as $result) {
if (isset($result->{$id_key})) {
$data = (array) $result;
$table_base_results_keyed[$result->{$id_key}] = $data;
// Add data for fields with multiple columns, like link__title,
// link__description, ...
foreach ($data as $field_column_name => $value) {
if ($field_name = strstr($field_column_name, '__', TRUE)) {
if (in_array($field_name, $table_revision_fields) && !in_array($field_column_name, $table_revision_fields)) {
$table_base_results_keyed[$result->{$id_key}][$field_column_name] = $data[$field_column_name];
$table_revision_fields[] = $field_column_name;
}
}
}
}
}
// For the new created revisionable fields take data from base table.
foreach ($table_revision_results as $result) {
$data = (array) $result;
foreach ($table_revision_fields as $field_name) {
if (!isset($data[$field_name]) && isset($table_base_results_keyed[$result->{$id_key}][$field_name])) {
$data[$field_name] = $table_base_results_keyed[$result->{$id_key}][$field_name];
}
}
// Save the information in the revision table.
$connection
->insert($table_revision)
->fields($data)
->execute();
}
}
}
}
}
}
}