Issue #2976103 by amateescu, catch, tstoeckler, alexpott: Make it possible to retrieve all the last installed entity type definitions at once from the update manager
parent
7410ab4ab0
commit
5e908886e9
|
@ -575,7 +575,7 @@ services:
|
|||
- { name: event_subscriber }
|
||||
entity.definition_update_manager:
|
||||
class: Drupal\Core\Entity\EntityDefinitionUpdateManager
|
||||
arguments: ['@entity.manager']
|
||||
arguments: ['@entity.manager', '@entity.last_installed_schema.repository']
|
||||
entity.last_installed_schema.repository:
|
||||
class: Drupal\Core\Entity\EntityLastInstalledSchemaRepository
|
||||
arguments: ['@keyvalue']
|
||||
|
|
|
@ -21,14 +21,29 @@ class EntityDefinitionUpdateManager implements EntityDefinitionUpdateManagerInte
|
|||
*/
|
||||
protected $entityManager;
|
||||
|
||||
/**
|
||||
* The last installed schema repository.
|
||||
*
|
||||
* @var \Drupal\Core\Entity\EntityLastInstalledSchemaRepositoryInterface
|
||||
*/
|
||||
protected $entityLastInstalledSchemaRepository;
|
||||
|
||||
/**
|
||||
* Constructs a new EntityDefinitionUpdateManager.
|
||||
*
|
||||
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
|
||||
* The entity manager.
|
||||
* @param \Drupal\Core\Entity\EntityLastInstalledSchemaRepositoryInterface $entity_last_installed_schema_repository
|
||||
* The last installed schema repository service.
|
||||
*/
|
||||
public function __construct(EntityManagerInterface $entity_manager) {
|
||||
public function __construct(EntityManagerInterface $entity_manager, EntityLastInstalledSchemaRepositoryInterface $entity_last_installed_schema_repository = NULL) {
|
||||
$this->entityManager = $entity_manager;
|
||||
|
||||
if (!isset($entity_last_installed_schema_repository)) {
|
||||
@trigger_error('The $entity_last_installed_schema_repository parameter was added in Drupal 8.6.x and will be required in 9.0.0. See https://www.drupal.org/node/2973262.', E_USER_DEPRECATED);
|
||||
$entity_last_installed_schema_repository = \Drupal::service('entity.last_installed_schema.repository');
|
||||
}
|
||||
$this->entityLastInstalledSchemaRepository = $entity_last_installed_schema_repository;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -63,7 +78,7 @@ class EntityDefinitionUpdateManager implements EntityDefinitionUpdateManagerInte
|
|||
// Process field storage definition changes.
|
||||
if (!empty($change_list['field_storage_definitions'])) {
|
||||
$storage_definitions = $this->entityManager->getFieldStorageDefinitions($entity_type_id);
|
||||
$original_storage_definitions = $this->entityManager->getLastInstalledFieldStorageDefinitions($entity_type_id);
|
||||
$original_storage_definitions = $this->entityLastInstalledSchemaRepository->getLastInstalledFieldStorageDefinitions($entity_type_id);
|
||||
|
||||
foreach ($change_list['field_storage_definitions'] as $field_name => $change) {
|
||||
switch ($change) {
|
||||
|
@ -108,7 +123,7 @@ class EntityDefinitionUpdateManager implements EntityDefinitionUpdateManagerInte
|
|||
// Process field storage definition changes.
|
||||
if (!empty($change_list['field_storage_definitions'])) {
|
||||
$storage_definitions = $this->entityManager->getFieldStorageDefinitions($entity_type_id);
|
||||
$original_storage_definitions = $this->entityManager->getLastInstalledFieldStorageDefinitions($entity_type_id);
|
||||
$original_storage_definitions = $this->entityLastInstalledSchemaRepository->getLastInstalledFieldStorageDefinitions($entity_type_id);
|
||||
|
||||
foreach ($change_list['field_storage_definitions'] as $field_name => $change) {
|
||||
$storage_definition = isset($storage_definitions[$field_name]) ? $storage_definitions[$field_name] : NULL;
|
||||
|
@ -123,10 +138,17 @@ class EntityDefinitionUpdateManager implements EntityDefinitionUpdateManagerInte
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function getEntityType($entity_type_id) {
|
||||
$entity_type = $this->entityManager->getLastInstalledDefinition($entity_type_id);
|
||||
$entity_type = $this->entityLastInstalledSchemaRepository->getLastInstalledDefinition($entity_type_id);
|
||||
return $entity_type ? clone $entity_type : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getEntityTypes() {
|
||||
return $this->entityLastInstalledSchemaRepository->getLastInstalledDefinitions();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -173,7 +195,7 @@ class EntityDefinitionUpdateManager implements EntityDefinitionUpdateManagerInte
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function getFieldStorageDefinition($name, $entity_type_id) {
|
||||
$storage_definitions = $this->entityManager->getLastInstalledFieldStorageDefinitions($entity_type_id);
|
||||
$storage_definitions = $this->entityLastInstalledSchemaRepository->getLastInstalledFieldStorageDefinitions($entity_type_id);
|
||||
return isset($storage_definitions[$name]) ? clone $storage_definitions[$name] : NULL;
|
||||
}
|
||||
|
||||
|
@ -211,7 +233,7 @@ class EntityDefinitionUpdateManager implements EntityDefinitionUpdateManagerInte
|
|||
break;
|
||||
|
||||
case static::DEFINITION_UPDATED:
|
||||
$original = $this->entityManager->getLastInstalledDefinition($entity_type_id);
|
||||
$original = $this->entityLastInstalledSchemaRepository->getLastInstalledDefinition($entity_type_id);
|
||||
$this->entityManager->onEntityTypeUpdate($entity_type, $original);
|
||||
break;
|
||||
}
|
||||
|
@ -262,7 +284,7 @@ class EntityDefinitionUpdateManager implements EntityDefinitionUpdateManagerInte
|
|||
$change_list = [];
|
||||
|
||||
foreach ($this->entityManager->getDefinitions() as $entity_type_id => $entity_type) {
|
||||
$original = $this->entityManager->getLastInstalledDefinition($entity_type_id);
|
||||
$original = $this->entityLastInstalledSchemaRepository->getLastInstalledDefinition($entity_type_id);
|
||||
|
||||
// @todo Support non-storage-schema-changing definition updates too:
|
||||
// https://www.drupal.org/node/2336895.
|
||||
|
@ -277,7 +299,7 @@ class EntityDefinitionUpdateManager implements EntityDefinitionUpdateManagerInte
|
|||
if ($this->entityManager->getStorage($entity_type_id) instanceof DynamicallyFieldableEntityStorageInterface) {
|
||||
$field_changes = [];
|
||||
$storage_definitions = $this->entityManager->getFieldStorageDefinitions($entity_type_id);
|
||||
$original_storage_definitions = $this->entityManager->getLastInstalledFieldStorageDefinitions($entity_type_id);
|
||||
$original_storage_definitions = $this->entityLastInstalledSchemaRepository->getLastInstalledFieldStorageDefinitions($entity_type_id);
|
||||
|
||||
// Detect created field storage definitions.
|
||||
foreach (array_diff_key($storage_definitions, $original_storage_definitions) as $field_name => $storage_definition) {
|
||||
|
|
|
@ -108,6 +108,18 @@ interface EntityDefinitionUpdateManagerInterface {
|
|||
*/
|
||||
public function getEntityType($entity_type_id);
|
||||
|
||||
/**
|
||||
* Returns all the entity type definitions, ready to be manipulated.
|
||||
*
|
||||
* When needing to apply updates to existing entity type definitions, this
|
||||
* method should always be used to retrieve all the definitions ready to be
|
||||
* manipulated.
|
||||
*
|
||||
* @return \Drupal\Core\Entity\EntityTypeInterface[]
|
||||
* The last installed entity type definitions, keyed by the entity type ID.
|
||||
*/
|
||||
public function getEntityTypes();
|
||||
|
||||
/**
|
||||
* Installs a new entity type definition.
|
||||
*
|
||||
|
|
|
@ -34,6 +34,28 @@ class EntityLastInstalledSchemaRepository implements EntityLastInstalledSchemaRe
|
|||
return $this->keyValueFactory->get('entity.definitions.installed')->get($entity_type_id . '.entity_type');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getLastInstalledDefinitions() {
|
||||
$all_definitions = $this->keyValueFactory->get('entity.definitions.installed')->getAll();
|
||||
|
||||
// Filter out field storage definitions.
|
||||
$filtered_keys = array_filter(array_keys($all_definitions), function ($key) {
|
||||
return substr($key, -12) === '.entity_type';
|
||||
});
|
||||
$entity_type_definitions = array_intersect_key($all_definitions, array_flip($filtered_keys));
|
||||
|
||||
// Ensure that the returned array is keyed by the entity type ID.
|
||||
$keys = array_keys($entity_type_definitions);
|
||||
$keys = array_map(function ($key) {
|
||||
$parts = explode('.', $key);
|
||||
return $parts[0];
|
||||
}, $keys);
|
||||
|
||||
return array_combine($keys, $entity_type_definitions);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
|
|
@ -41,6 +41,34 @@ interface EntityLastInstalledSchemaRepositoryInterface {
|
|||
*/
|
||||
public function getLastInstalledDefinition($entity_type_id);
|
||||
|
||||
/**
|
||||
* Gets the entity type definitions in their most recently installed state.
|
||||
*
|
||||
* During the application lifetime, entity type definitions can change. For
|
||||
* example, updated code can be deployed. The
|
||||
* \Drupal\Core\Entity\EntityTypeManagerInterface::getDefinitions() method
|
||||
* will always return the definitions as determined by the current codebase.
|
||||
* This method returns the definitions from the last time that a
|
||||
* \Drupal\Core\Entity\EntityTypeListener event was completed. In other words,
|
||||
* the definitions that the entity type's handlers have incorporated into the
|
||||
* application state. For example, if the entity type's storage handler is
|
||||
* SQL-based, the definition for which database tables were created.
|
||||
*
|
||||
* Application management code can check if
|
||||
* \Drupal\Core\Entity\EntityTypeManagerInterface::getDefinitions() differs
|
||||
* from getLastInstalledDefinitions() and decide whether to:
|
||||
* - Invoke the appropriate \Drupal\Core\Entity\EntityTypeListenerInterface
|
||||
* event so that handlers react to the new definitions.
|
||||
* - Raise a warning that the application state is incompatible with the
|
||||
* codebase.
|
||||
* - Perform some other action.
|
||||
*
|
||||
* @return \Drupal\Core\Entity\EntityTypeInterface[]
|
||||
* An array containing the installed definition for all entity types, keyed
|
||||
* by the entity type ID.
|
||||
*/
|
||||
public function getLastInstalledDefinitions();
|
||||
|
||||
/**
|
||||
* Stores the entity type definition in the application state.
|
||||
*
|
||||
|
|
|
@ -20,6 +20,8 @@ use Drupal\Tests\system\Functional\Entity\Traits\EntityDefinitionTestTrait;
|
|||
/**
|
||||
* Tests EntityDefinitionUpdateManager functionality.
|
||||
*
|
||||
* @coversDefaultClass \Drupal\Core\Entity\EntityDefinitionUpdateManager
|
||||
*
|
||||
* @group Entity
|
||||
*/
|
||||
class EntityDefinitionUpdateTest extends EntityKernelTestBase {
|
||||
|
@ -1180,4 +1182,18 @@ class EntityDefinitionUpdateTest extends EntityKernelTestBase {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::getEntityTypes
|
||||
*/
|
||||
public function testGetEntityTypes() {
|
||||
$entity_type_definitions = $this->entityDefinitionUpdateManager->getEntityTypes();
|
||||
|
||||
// Ensure that we have at least one entity type to check below.
|
||||
$this->assertGreaterThanOrEqual(1, count($entity_type_definitions));
|
||||
|
||||
foreach ($entity_type_definitions as $entity_type_id => $entity_type) {
|
||||
$this->assertEquals($this->entityDefinitionUpdateManager->getEntityType($entity_type_id), $entity_type);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue