Обновление схемы BaseFieldDefinition поля сущности в Drupal
Иногда при работе с сущностями Drupal возникает необходимость обновить структуру кастомного поля, которое состоит из нескольких колонок. Делается это следующим образом:
use Drupal\Core\Field\BaseFieldDefinition; function site_commerce_order_update_8101($sandbox) { // Менеджер обновлений сущностей. $definition_update_manager = \Drupal::entityDefinitionUpdateManager(); // Менеджер для работы с базой данных. $database = \Drupal::database(); // Получаем объект сущности, в которую вносим изменения. $entity_type_manager = \Drupal::entityTypeManager(); $bundle_of = 'site_commerce_order'; $bundle_definition = $entity_type_manager->getDefinition($bundle_of); // Получаем идентификатор ключевого поля сущности. $id_key = $bundle_definition->getKey('id'); // Определяем имеет ли сущность отдельную таблицу для хранения данных. // Если сущность не поддерживает переводы, то используется базовая таблица. $storage = $entity_type_manager->getStorage($bundle_of); $table_name = $storage->getDataTable() ?: $storage->getBaseTable(); // Сохраняем текущие значения поля из таблицы определения сущности. $current_values = $database->select($table_name, 'n') ->fields('n', [ 'delivery_address__latitude', 'delivery_address__longitude', 'delivery_address__country', 'delivery_address__region', 'delivery_address__postcode', ]) ->execute() ->fetchAllAssoc($id_key, PDO::FETCH_ASSOC); // Удаляем значения из таблицы определения сущности. $database->update($table_name) ->fields([ 'delivery_address__latitude' => NULL, 'delivery_address__longitude' => NULL, 'delivery_address__country' => NULL, 'delivery_address__region' => NULL, 'delivery_address__postcode' => NULL, ]) ->execute(); // Получаем новое определение поля. $new_field_definition = BaseFieldDefinition::create('delivery_address') ->setLabel(t('Delivery address')) ->setDisplayConfigurable('form', TRUE) ->setDisplayConfigurable('view', TRUE); // Удаляем текущее поле. $field_storage_definition = $definition_update_manager->getFieldStorageDefinition('delivery_address', $bundle_of); $definition_update_manager->uninstallFieldStorageDefinition($field_storage_definition); // Устанавливаем новое определение поля. $definition_update_manager->installFieldStorageDefinition('delivery_address', $bundle_of, $bundle_of, $new_field_definition); // Восстанавливаем значения в поля таблицы определения сущности. foreach ($current_values as $id => $value) { $database->update($table_name) ->fields([ 'delivery_address__latitude' => $value['delivery_address__latitude'], 'delivery_address__longitude' => $value['delivery_address__longitude'], 'delivery_address__country' => $value['delivery_address__country'], 'delivery_address__region' => $value['delivery_address__region'], 'delivery_address__postcode' => $value['delivery_address__postcode'], ]) ->condition($id_key, $id) ->execute(); } }