entity_legal-4.0.x-dev/entity_legal.install

entity_legal.install
<?php

/**
 * @file
 * Install, update and uninstall functions for the entity_legal module.
 */

declare(strict_types=1);

use Drupal\Core\Database\Database;
use Drupal\Core\Field\BaseFieldDefinition;

/**
 * Implements hook_update_last_removed().
 */
function entity_legal_update_last_removed(): int {
  /** @var \Drupal\Core\Update\UpdateHookRegistry $updateHookRegistry */
  $updateHookRegistry = \Drupal::service('update.update_hook_registry');
  $state = \Drupal::state();

  // When running updates, the theme registry is also rebuilt (why?). This
  // triggers the 'theme' hooks, including `views_theme()`, which builds the
  // Views data. Subsequently, `EntityViewsData::getViewsData()` is called which
  // uses the INSTALLED entity type definition, thus the old entity keys, and
  // crashes because the current field storage definitions doesn't contain
  // anymore the old ID key (name), but the new one (vid). That's why we need to
  // install the new definition of 'entity_legal_document_version' very early.
  // Unfortunately, the described scenario happens before `hook_update_N()` are
  // running. As a workaround, we update the entity type definition here to
  // prevent the crash. Only run this once for `entity_legal_update_9002()`.
  // @see \views_theme()
  // @see \Drupal\views\EntityViewsData::getViewsData()
  // @see \entity_legal_update_9002()
  if ($updateHookRegistry->getInstalledVersion('entity_legal') === 9001 && !$state->get('entity_legal.update_9002')) {
    $updateManager = \Drupal::entityDefinitionUpdateManager();
    $entityTypeManager = \Drupal::entityTypeManager();
    // Update the 'entity_legal_document_version' entity type definition.
    $fieldStorageDefinition = BaseFieldDefinition::create('integer')
      ->setLabel(t('ID'))
      ->setReadOnly(TRUE)
      ->setSetting('unsigned', TRUE);
    $updateManager->installFieldStorageDefinition('vid', 'entity_legal_document_version', 'entity_legal', $fieldStorageDefinition);
    $entityType = $entityTypeManager->getDefinition('entity_legal_document_version');
    $updateManager->updateEntityType($entityType);
    // Make sure we run this update only once.
    $state->set('entity_legal.update_9002', TRUE);
  }

  return 9001;
}

/**
 * Convert document version ID from string to serial.
 *
 * Changing the entity type ID field is painful, and it could not be achieved by
 * using the entity definition update manager service in every case. It's
 * necessary to perform raw SQL operations against the database. Note: this
 * update path hasn't been tested on databases other than MySQL and PostgreSQL.
 */
function entity_legal_update_9002(): string {
  $db = Database::getConnection();
  if (!in_array($db->driver(), ['mysql', 'pgsql'], TRUE)) {
    \Drupal::messenger()->addWarning(__FUNCTION__ . "() was tested only with the MySQL and PostgreSQL drivers but the current database driver is '{$db->driver()}'. Use it on your own risk");
  }
  $schema = $db->schema();
  $updateManager = \Drupal::entityDefinitionUpdateManager();
  $entityTypeManager = \Drupal::entityTypeManager();
  // Don't use cached definitions.
  $entityTypeManager->useCaches();

  $fieldTables = [];
  foreach (['entity_legal_document_version', 'entity_legal_document_acceptance'] as $entityTypeId) {
    /** @var \Drupal\Core\Entity\Sql\SqlContentEntityStorage $storage */
    $storage = $entityTypeManager->getStorage($entityTypeId);
    $tables = $storage->getTableMapping()->getTableNames();
    foreach ($tables as $table) {
      // Collect 'entity_legal_document_version' field dedicated table names.
      if ($entityTypeId === 'entity_legal_document_version' && str_starts_with($table, 'entity_legal_document_version__')) {
        $fieldTables[] = $table;
      }
    }
  }

  // PostgreSQL doesn't support UNSIGNED as cast type and SUBSTRING_INDEX().
  $subString = $db->driver() === 'pgsql' ? "CAST(REVERSE(SPLIT_PART(REVERSE(%s), '_', 1)) AS INTEGER)" : "CAST(SUBSTRING_INDEX(%s, '_', -1) AS UNSIGNED)";

  // Update content tables.
  $schema->dropPrimaryKey('entity_legal_document_version');
  $schema->addField('entity_legal_document_version', 'vid', [
    'type' => 'serial',
    'unsigned' => TRUE,
    'not null' => TRUE,
  ], ['primary key' => ['vid']]);
  $db->query("UPDATE {entity_legal_document_version} SET vid = " . sprintf($subString, 'name'));
  $schema->dropField('entity_legal_document_version', 'name');

  $schema->dropPrimaryKey('entity_legal_document_version_data');
  $schema->dropIndex('entity_legal_document_version_data', 'entity_legal_document_version__id__default_langcode__langcode');
  $db->query("UPDATE {entity_legal_document_version_data} SET vid = " . sprintf($subString, 'name'));
  $schema->addPrimaryKey('entity_legal_document_version_data', [
    'vid',
    'langcode',
  ]);
  $schema->addIndex('entity_legal_document_version_data', 'entity_legal_document_version__id__default_langcode__langcode', [
    'vid',
    'default_langcode',
    'langcode',
  ],
  [
    'fields' => [
      'vid' => [
        'type' => 'int',
        'size' => 'normal',
        'unsigned' => TRUE,
        'not null' => TRUE,
      ],
      'default_langcode' => [
        'type' => 'int',
        'size' => 'tiny',
        'not null' => TRUE,
      ],
      'langcode' => [
        'type' => 'varchar_ascii',
        'length' => 12,
        'not null' => TRUE,
      ],
    ],
    'indexes' => [
      'entity_legal_document_version__id__default_langcode__langcode' => [
        'vid',
        'default_langcode',
        'langcode',
      ],
    ],
  ]);

  foreach ($fieldTables as $table) {
    $schema->dropPrimaryKey($table);
    $schema->dropIndex($table, 'revision_id');
    $db->query("UPDATE {{$table}} SET entity_id = " . sprintf($subString, 'entity_id') . ", revision_id = " . sprintf($subString, 'revision_id'));
    $schema->changeField($table, 'entity_id', 'entity_id', [
      'type' => 'int',
      'size' => 'normal',
      'unsigned' => TRUE,
      'not null' => TRUE,
    ], ['primary key' => ['entity_id', 'deleted', 'delta', 'langcode']]);
    $schema->changeField($table, 'revision_id', 'revision_id', [
      'type' => 'int',
      'size' => 'normal',
      'unsigned' => TRUE,
      'not null' => TRUE,
    ]);
    $schema->addIndex($table, 'revision_id', ['revision_id'], [
      'fields' => [
        'revision_id' => [
          'type' => 'int',
          'size' => 'normal',
          'unsigned' => TRUE,
          'not null' => TRUE,
        ],
      ],
      'indexes' => ['revision_id' => ['revision_id']],
    ]);
  }

  $schema->addField('entity_legal_document_acceptance', 'vid', [
    'type' => 'int',
    'size' => 'normal',
    'unsigned' => TRUE,
    'not null' => FALSE,
  ]);
  $db->query("UPDATE {entity_legal_document_acceptance} SET vid = " . sprintf($subString, 'document_version_name'));
  $schema->changeField('entity_legal_document_acceptance', 'vid', 'vid', [
    'type' => 'int',
    'size' => 'normal',
    'unsigned' => TRUE,
    'not null' => TRUE,
  ]);
  $schema->dropField('entity_legal_document_acceptance', 'document_version_name');
  $schema->addIndex('entity_legal_document_acceptance', 'entity_legal_document_acceptance__cad57f4c0e', [
    'vid',
  ],
  [
    'fields' => [
      'vid' => [
        'type' => 'int',
        'size' => 'normal',
        'unsigned' => TRUE,
        'not null' => TRUE,
      ],
    ],
    'indexes' => [
      'entity_legal_document_acceptance__cad57f4c0e' => ['vid'],
    ],
  ]);

  // Update field storage definitions.
  $legacyIdDefinition = $updateManager->getFieldStorageDefinition('name', 'entity_legal_document_version');
  $updateManager->uninstallFieldStorageDefinition($legacyIdDefinition);

  $fieldDefinitions = unserialize(
    $db->select('key_value')
      ->fields('key_value', ['value'])
      ->condition('collection', 'entity.definitions.installed')
      ->condition('name', 'entity_legal_document_acceptance.field_storage_definitions')
      ->execute()
      ->fetchField()
  );
  unset($fieldDefinitions['document_version_name']);
  $fieldDefinitions['vid'] = BaseFieldDefinition::create('entity_reference')
    ->setName('vid')
    ->setLabel(t('Document version'))
    ->setDescription(t('The document version this acceptance is bound to.'))
    ->setSetting('target_type', 'entity_legal_document_version')
    ->setTargetEntityTypeId('entity_legal_document_acceptance')
    ->setRequired(TRUE)
    ->setProvider('entity_legal');
  $db->update('key_value')
    ->fields(['value' => serialize($fieldDefinitions)])
    ->condition('collection', 'entity.definitions.installed')
    ->condition('name', 'entity_legal_document_acceptance.field_storage_definitions')
    ->execute();

  $schema = unserialize($db->select('key_value')
    ->fields('key_value', ['value'])
    ->condition('collection', 'entity.storage_schema.sql')
    ->condition('name', 'entity_legal_document_version.entity_schema_data')
    ->execute()
    ->fetchField());
  $schema['entity_legal_document_version']['primary key'] = ['vid'];
  $schema['entity_legal_document_version_data']['primary key'] = [
    'vid',
    'langcode',
  ];
  $schema['entity_legal_document_version_data']['indexes']['entity_legal_document_version__id__default_langcode__langcode'] = [
    'vid',
    'default_langcode',
    'langcode',
  ];
  $db->update('key_value')
    ->fields(['value' => serialize($schema)])
    ->condition('collection', 'entity.storage_schema.sql')
    ->condition('name', 'entity_legal_document_version.entity_schema_data')
    ->execute();

  $schema = unserialize($db->select('key_value')
    ->fields('key_value', ['value'])
    ->condition('collection', 'entity.storage_schema.sql')
    ->condition('name', 'entity_legal_document_version.field_schema_data.vid')
    ->execute()
    ->fetchField());
  $schema['entity_legal_document_version']['fields'] = [
    'vid' => [
      'type' => 'serial',
      'unsigned' => TRUE,
      'not null' => TRUE,
      'size' => 'normal',
    ],
  ];
  $schema['entity_legal_document_version_data']['fields'] = [
    'vid' => [
      'type' => 'int',
      'size' => 'normal',
      'unsigned' => TRUE,
      'not null' => TRUE,
    ],
  ];
  $db->update('key_value')
    ->fields(['value' => serialize($schema)])
    ->condition('collection', 'entity.storage_schema.sql')
    ->condition('name', 'entity_legal_document_version.field_schema_data.vid')
    ->execute();

  $schema = unserialize($db->select('key_value')
    ->fields('key_value', ['value'])
    ->condition('collection', 'entity.storage_schema.sql')
    ->condition('name', 'entity_legal_document_version.field_schema_data.entity_legal_document_text')
    ->execute()
    ->fetchField());
  foreach ($fieldTables as $table) {
    $schema[$table]['fields']['entity_id'] = [
      'description' => 'The entity id this data is attached to',
      'type' => 'int',
      'unsigned' => TRUE,
      'not null' => TRUE,
    ];
    $schema[$table]['fields']['revision_id'] = [
      'description' => 'The entity revision id this data is attached to, which for an unversioned entity type is the same as the entity id',
      'type' => 'int',
      'unsigned' => TRUE,
      'not null' => TRUE,
    ];
  }
  $db->update('key_value')
    ->fields(['value' => serialize($schema)])
    ->condition('collection', 'entity.storage_schema.sql')
    ->condition('name', 'entity_legal_document_version.field_schema_data.entity_legal_document_text')
    ->execute();

  $schema = unserialize($db->select('key_value')
    ->fields('key_value', ['value'])
    ->condition('collection', 'entity.storage_schema.sql')
    ->condition('name', 'entity_legal_document_acceptance.field_schema_data.document_version_name')
    ->execute()
    ->fetchField());
  $schema['entity_legal_document_acceptance']['fields'] = [
    'vid' => [
      'description' => 'The ID of the target entity.',
      'type' => 'int',
      'unsigned' => TRUE,
      'not null' => FALSE,
    ],
  ];
  $schema['entity_legal_document_acceptance']['indexes'] = [
    'entity_legal_document_acceptance__cad57f4c0e' => ['vid'],
  ];
  $db->update('key_value')
    ->fields([
      'name' => 'entity_legal_document_acceptance.field_schema_data.vid',
      'value' => serialize($schema),
    ])
    ->condition('collection', 'entity.storage_schema.sql')
    ->condition('name', 'entity_legal_document_acceptance.field_schema_data.document_version_name')
    ->execute();

  return "Document version entity IDs were converted from strings to auto-increment integers. Old IDs were converted by retaining the numeric part (former timestamp) as new integer ID. For instance, 'legal_notice_1683794048' (string) was converted into 1683794048 (int).";
}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc