Обновление схемы BaseFieldDefinition поля сущности в Drupal

11.05.2020

Иногда при работе с сущностями 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();
  }
}
На нашем сайте filinkov.ru мы используем cookie. Примите нашу Политику использования cookie.
Принимаю