time_field-8.x-1.13/time_field.install
time_field.install
<?php
/**
* @file
* Install, update and uninstall functions for the time_field module.
*/
use Drupal\Core\Entity\Sql\SqlContentEntityStorageException;
/**
* Update 10200: allow NULL values in the 'to' column for all time_range fields.
*
* Code inspired/copied from:
* - https://gist.github.com/JPustkuchen/ce53d40303a51ca5f17ce7f48c363b9b
* - https://www.drupal.org/project/drupal/issues/937442
*/
function time_field_update_10200() {
$entity_type_manager = \Drupal::entityTypeManager();
$entity_field_manager = \Drupal::service('entity_field.manager');
$entity_field_map = $entity_field_manager->getFieldMapByFieldType('time_range');
foreach ($entity_field_map as $entity_type_id => $field_map) {
$entity_storage = $entity_type_manager->getStorage($entity_type_id);
$entity_type = $entity_type_manager->getDefinition($entity_type_id);
$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 our field type:
/** @var \Drupal\Core\Field\FieldStorageDefinitionInterface $field_storage_definition */
foreach (array_intersect_key($field_storage_definitions, $field_map) as $field_storage_definition) {
$field_name = $field_storage_definition->getName();
$tables = [];
try {
$table = $table_mapping->getFieldTableName($field_name);
$tables[] = $table;
}
catch (SqlContentEntityStorageException $e) {
// Custom storage? Broken site? No matter what, if there is no table
// there's little we can do.
\Drupal::messenger()->addWarning(t(
'time_field update: skipped field "@field" on entity "@entity" (no dedicated table).',
['@field' => $field_name, '@entity' => $entity_type_id]
));
continue;
}
// See if the field has a revision table.
if ($entity_type->isRevisionable() && $field_storage_definition->isRevisionable()) {
if ($table_mapping->requiresDedicatedTableStorage($field_storage_definition)) {
$revision_table = $table_mapping->getDedicatedRevisionTableName($field_storage_definition);
$tables[] = $revision_table;
}
elseif ($table_mapping->allowsSharedTableStorage($field_storage_definition)) {
$revision_table = $entity_type->getRevisionDataTable() ?: $entity_type->getRevisionTable();
$tables[] = $revision_table;
}
}
$to_column = $table_mapping->getFieldColumnName($field_storage_definition, 'to');
$database = \Drupal::database();
$existing_data = [];
foreach ($tables as $table) {
// Get the old data.
$existing_data[$table] = $database->select($table)
->fields($table)
->execute()
->fetchAll(PDO::FETCH_ASSOC);
// Wipe it.
$database->truncate($table)->execute();
}
$manager = \Drupal::entityDefinitionUpdateManager();
$manager->updateFieldStorageDefinition($manager->getFieldStorageDefinition($field_name, $entity_type_id));
// Restore the data.
foreach ($tables as $table) {
if (empty($existing_data[$table]) || !is_array($existing_data[$table])) {
// Skip if there are no rows:
continue;
}
$first_row = reset($existing_data[$table]);
if (empty($first_row)) {
// Skip if there is no data:
continue;
}
$fields = array_keys($first_row);
$insert_query = $database
->insert($table)
->fields($fields);
foreach ($existing_data[$table] as $row) {
$insert_query->values(array_values($row));
}
$insert_query->execute();
// Convert any sentinel 86401 values to NULL.
$database->update($table)
->fields([$to_column => NULL])
->condition($to_column, 86401)
->execute();
}
\Drupal::messenger()->addStatus(t(
'time_field update: updated field "@field" on entity "@entity".',
['@field' => $field_name, '@entity' => $entity_type_id]
));
}
}
}
