Skip to content
Snippets Groups Projects

Add helper class to migrate to/from enum fields

Open Dieter Holvoet requested to merge issue/enum_field-3496602:3496602-add-helper-class into 1.x
2 files
+ 162
0
Compare changes
  • Side-by-side
  • Inline
Files
2
src/Migration.php 0 → 100644
+ 154
0
<?php
namespace Drupal\enum_field;
use Drupal\Core\Config\Config;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityLastInstalledSchemaRepositoryInterface;
use Drupal\field\Entity\FieldConfig;
use Drupal\field\Entity\FieldStorageConfig;
/**
* Helper methods to migrate between list and enum field types.
*/
class Migration {
protected const FIELD_TYPE_MAP = [
'enum_integer' => 'list_integer',
'enum_string' => 'list_string',
];
/**
* Constructor.
*
* @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory
* The config factory service.
* @param \Drupal\Core\Entity\EntityFieldManagerInterface $entityFieldManager
* The entity field manager service.
* @param \Drupal\Core\Entity\EntityLastInstalledSchemaRepositoryInterface $entityLastInstalledSchemaRepository
* The entity last installed schema repository service.
*/
public function __construct(
protected ConfigFactoryInterface $configFactory,
protected EntityFieldManagerInterface $entityFieldManager,
protected EntityLastInstalledSchemaRepositoryInterface $entityLastInstalledSchemaRepository,
) {
}
/**
* Migrates an enum field to a list field.
*
* @param string $entityTypeId
* The entity type ID.
* @param string $fieldName
* The field name.
*
* @throws \Exception
* Thrown when the field is not a list field.
*/
public function migrateEnumField(string $entityTypeId, string $fieldName): void {
$fieldStorageConfig = $this->configFactory->getEditable("field.storage.$entityTypeId.$fieldName");
$sourceFieldType = $fieldStorageConfig->get('type');
$targetFieldType = static::FIELD_TYPE_MAP[$sourceFieldType] ?? NULL;
if ($sourceFieldType === $targetFieldType) {
// Already migrated
return;
}
if ($targetFieldType === NULL) {
throw new \Exception('Not an enum field');
}
$this->doMigrateField(
entityTypeId: $entityTypeId,
fieldName: $fieldName,
fieldStorageConfig: $fieldStorageConfig,
sourceFieldType: $sourceFieldType,
targetFieldType: $targetFieldType,
targetModule: 'options',
);
}
/**
* Migrates a list field to an enum field.
*
* @param string $entityTypeId
* The entity type ID.
* @param string $fieldName
* The field name.
*
* @throws \Exception
* Thrown when the field is not a list field.
*/
public function migrateListField(string $entityTypeId, string $fieldName): void {
$fieldStorageConfig = $this->configFactory->getEditable("field.storage.$entityTypeId.$fieldName");
$sourceFieldType = $fieldStorageConfig->get('type');
$targetFieldType = array_reverse(static::FIELD_TYPE_MAP)[$sourceFieldType] ?? NULL;
if ($sourceFieldType === $targetFieldType) {
// Already migrated
return;
}
if ($targetFieldType === NULL) {
throw new \Exception('Not a list field');
}
$this->doMigrateField(
entityTypeId: $entityTypeId,
fieldName: $fieldName,
fieldStorageConfig: $fieldStorageConfig,
sourceFieldType: $sourceFieldType,
targetFieldType: $targetFieldType,
targetModule: 'enum_field',
);
}
/**
* Migrates a field.
*
* @param string $entityTypeId
* The entity type ID.
* @param string $fieldName
* The field name.
* @param \Drupal\Core\Config\Config $fieldStorageConfig
* The field storage config.
* @param string $sourceFieldType
* The source field type.
* @param string $targetFieldType
* The target field type.
* @param string $targetModule
* The target module.
*/
protected function doMigrateField(string $entityTypeId, string $fieldName, Config $fieldStorageConfig, string $sourceFieldType, string $targetFieldType, string $targetModule): void {
// Update the field storage.
/** @var \Drupal\field\Entity\FieldStorageConfig[] $schemaDefinitions */
$schemaDefinitions = $this->entityLastInstalledSchemaRepository->getLastInstalledFieldStorageDefinitions($entityTypeId);
$schemaDefinitions[$fieldName]->set('type', $targetFieldType);
$this->entityLastInstalledSchemaRepository->setLastInstalledFieldStorageDefinitions($entityTypeId, $schemaDefinitions);
$this->entityFieldManager->clearCachedFieldDefinitions();
$fieldStorageConfig->set('type', $targetFieldType);
$fieldStorageConfig->set('module', $targetModule);
$fieldStorageConfig->save(TRUE);
FieldStorageConfig::loadByName($entityTypeId, $fieldName)->calculateDependencies()->save();
// Update the field instances.
$fieldMap = $this->entityFieldManager->getFieldMapByFieldType($sourceFieldType)[$entityTypeId][$fieldName];
foreach ($fieldMap['bundles'] as $bundle) {
$fieldConfig = $this->configFactory->getEditable("field.field.$entityTypeId.$bundle.$fieldName");
$fieldConfig->set('field_type', $targetFieldType);
$fieldConfig->save();
/** @var \Drupal\field\FieldConfigInterface $fieldConfig */
$fieldConfig = FieldConfig::loadByName($entityTypeId, $bundle, $fieldName);
$fieldConfig->calculateDependencies()->save();
}
}
}
Loading