SqlContentEntityStorageSchemaConverter.php 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. <?php
  2. namespace Drupal\Core\Entity\Sql;
  3. use Drupal\Core\Entity\EntityDefinitionUpdateManagerInterface;
  4. use Drupal\Core\Entity\EntityTypeManagerInterface;
  5. use Drupal\Core\Field\BaseFieldDefinition;
  6. use Drupal\Core\StringTranslation\TranslatableMarkup;
  7. /**
  8. * Defines a schema converter for entity types with existing data.
  9. *
  10. * @deprecated in drupal:8.7.0 and is removed from drupal:9.0.0.
  11. * Use \Drupal\Core\Entity\EntityDefinitionUpdateManagerInterface::updateFieldableEntityType()
  12. * instead.
  13. *
  14. * @see https://www.drupal.org/node/3029997
  15. */
  16. class SqlContentEntityStorageSchemaConverter {
  17. /**
  18. * The entity type ID this schema converter is responsible for.
  19. *
  20. * @var string
  21. */
  22. protected $entityTypeId;
  23. /**
  24. * The entity type manager.
  25. *
  26. * @var \Drupal\Core\Entity\EntityTypeManagerInterface
  27. */
  28. protected $entityTypeManager;
  29. /**
  30. * The entity definition update manager service.
  31. *
  32. * @var \Drupal\Core\Entity\EntityDefinitionUpdateManagerInterface
  33. */
  34. protected $entityDefinitionUpdateManager;
  35. /**
  36. * SqlContentEntityStorageSchemaConverter constructor.
  37. *
  38. * @param string $entity_type_id
  39. * The ID of the entity type.
  40. * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
  41. * The entity type manager.
  42. * @param \Drupal\Core\Entity\EntityDefinitionUpdateManagerInterface $entity_definition_update_manager
  43. * Entity definition update manager service.
  44. */
  45. public function __construct($entity_type_id, EntityTypeManagerInterface $entity_type_manager, EntityDefinitionUpdateManagerInterface $entity_definition_update_manager) {
  46. @trigger_error('\Drupal\Core\Entity\Sql\SqlContentEntityStorageSchemaConverter is deprecated in Drupal 8.7.0, will be removed before Drupal 9.0.0. Use \Drupal\Core\Entity\EntityDefinitionUpdateManagerInterface::updateFieldableEntityType() instead. See https://www.drupal.org/node/3029997.', E_USER_DEPRECATED);
  47. $this->entityTypeId = $entity_type_id;
  48. $this->entityTypeManager = $entity_type_manager;
  49. $this->entityDefinitionUpdateManager = $entity_definition_update_manager;
  50. }
  51. /**
  52. * Converts an entity type with existing data to be revisionable.
  53. *
  54. * This process does the following tasks:
  55. * - creates the schema from scratch with the new revisionable entity type
  56. * definition (i.e. the current definition of the entity type from code)
  57. * using temporary table names;
  58. * - loads the initial entity data by using the last installed entity and
  59. * field storage definitions;
  60. * - saves the entity data to the temporary tables;
  61. * - at the end of the process:
  62. * - deletes the original tables and replaces them with the temporary ones
  63. * that hold the new (revisionable) entity data;
  64. * - updates the installed entity schema data;
  65. * - updates the entity type definition in order to trigger the
  66. * \Drupal\Core\Entity\EntityTypeEvents::UPDATE event;
  67. * - updates the field storage definitions in order to mark the
  68. * revisionable ones as such.
  69. *
  70. * In case of an error during the entity save process, the temporary tables
  71. * are deleted and the original entity type and field storage definitions are
  72. * restored.
  73. *
  74. * @param array $sandbox
  75. * The sandbox array from a hook_update_N() implementation.
  76. * @param string[] $fields_to_update
  77. * (optional) An array of field names that should be converted to be
  78. * revisionable. Note that the 'langcode' field, if present, is updated
  79. * automatically. Defaults to an empty array.
  80. *
  81. * @throws \Exception
  82. * Re-throws any exception raised during the update process.
  83. */
  84. public function convertToRevisionable(array &$sandbox, array $fields_to_update = []) {
  85. /** @var \Drupal\Core\Entity\ContentEntityTypeInterface $entity_type */
  86. $this->entityTypeManager->useCaches(FALSE);
  87. $entity_type = $this->entityTypeManager->getDefinition($this->entityTypeId);
  88. /** @var \Drupal\Core\Entity\EntityLastInstalledSchemaRepositoryInterface $last_installed_schema_repository */
  89. $last_installed_schema_repository = \Drupal::service('entity.last_installed_schema.repository');
  90. $field_storage_definitions = $last_installed_schema_repository->getLastInstalledFieldStorageDefinitions($this->entityTypeId);
  91. // Add the revision ID field.
  92. $field_name = $entity_type->getKey('revision');
  93. $field_storage_definitions[$entity_type->getKey('revision')] = BaseFieldDefinition::create('integer')
  94. ->setName($field_name)
  95. ->setTargetEntityTypeId($entity_type->id())
  96. ->setTargetBundle(NULL)
  97. ->setLabel(t('Revision ID'))
  98. ->setReadOnly(TRUE)
  99. ->setSetting('unsigned', TRUE);
  100. // Add the 'revision_default' field.
  101. $field_name = $entity_type->getRevisionMetadataKey('revision_default');
  102. $field_storage_definitions[$field_name] = BaseFieldDefinition::create('boolean')
  103. ->setName($field_name)
  104. ->setTargetEntityTypeId($entity_type->id())
  105. ->setTargetBundle(NULL)
  106. ->setLabel(t('Default revision'))
  107. ->setDescription(t('A flag indicating whether this was a default revision when it was saved.'))
  108. ->setStorageRequired(TRUE)
  109. ->setTranslatable(FALSE)
  110. ->setRevisionable(TRUE);
  111. // Add the 'revision_translation_affected' field if needed.
  112. if ($entity_type->isTranslatable()) {
  113. $field_name = $entity_type->getKey('revision_translation_affected');
  114. $field_storage_definitions[$field_name] = BaseFieldDefinition::create('boolean')
  115. ->setName($field_name)
  116. ->setTargetEntityTypeId($entity_type->id())
  117. ->setTargetBundle(NULL)
  118. ->setLabel(new TranslatableMarkup('Revision translation affected'))
  119. ->setDescription(new TranslatableMarkup('Indicates if the last edit of a translation belongs to current revision.'))
  120. ->setReadOnly(TRUE)
  121. ->setRevisionable(TRUE)
  122. ->setTranslatable(TRUE);
  123. }
  124. // Mark various fields as revisionable.
  125. $field_storage_definitions[$entity_type->getKey('langcode')]->setRevisionable(TRUE);
  126. foreach ($fields_to_update as $field_name) {
  127. $field_storage_definitions[$field_name]->setRevisionable(TRUE);
  128. }
  129. $this->entityDefinitionUpdateManager->updateFieldableEntityType($entity_type, $field_storage_definitions, $sandbox);
  130. }
  131. }