summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNathaniel Catchpole2018-06-28 22:02:16 (GMT)
committerNathaniel Catchpole2018-06-28 22:02:16 (GMT)
commit246e95d4f5376c7b3d0014754e90f5f92aedd5fb (patch)
treee68b4fef567c7c4cea9eb829d4dd2b3a44380999
parente2651fce3d9c1e606f04d39b6fa5ce2484b90a44 (diff)
Issue #2976103 by amateescu, tstoeckler, alexpott: Make it possible to retrieve all the last installed entity type definitions at once from the update manager
-rw-r--r--core/core.services.yml2
-rw-r--r--core/lib/Drupal/Core/Entity/EntityDefinitionUpdateManager.php38
-rw-r--r--core/lib/Drupal/Core/Entity/EntityDefinitionUpdateManagerInterface.php12
-rw-r--r--core/lib/Drupal/Core/Entity/EntityLastInstalledSchemaRepository.php21
-rw-r--r--core/lib/Drupal/Core/Entity/EntityLastInstalledSchemaRepositoryInterface.php28
-rw-r--r--core/tests/Drupal/KernelTests/Core/Entity/EntityDefinitionUpdateTest.php16
6 files changed, 108 insertions, 9 deletions
diff --git a/core/core.services.yml b/core/core.services.yml
index 680c23b..de408ad 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -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']
diff --git a/core/lib/Drupal/Core/Entity/EntityDefinitionUpdateManager.php b/core/lib/Drupal/Core/Entity/EntityDefinitionUpdateManager.php
index d9a4d84..c5d0abd 100644
--- a/core/lib/Drupal/Core/Entity/EntityDefinitionUpdateManager.php
+++ b/core/lib/Drupal/Core/Entity/EntityDefinitionUpdateManager.php
@@ -22,13 +22,28 @@ 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,13 +138,20 @@ 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}
+ */
public function installEntityType(EntityTypeInterface $entity_type) {
$this->entityManager->clearCachedDefinitions();
$this->entityManager->onEntityTypeCreate($entity_type);
@@ -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) {
diff --git a/core/lib/Drupal/Core/Entity/EntityDefinitionUpdateManagerInterface.php b/core/lib/Drupal/Core/Entity/EntityDefinitionUpdateManagerInterface.php
index 7754170..a219f3c 100644
--- a/core/lib/Drupal/Core/Entity/EntityDefinitionUpdateManagerInterface.php
+++ b/core/lib/Drupal/Core/Entity/EntityDefinitionUpdateManagerInterface.php
@@ -109,6 +109,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.
*
* @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
diff --git a/core/lib/Drupal/Core/Entity/EntityLastInstalledSchemaRepository.php b/core/lib/Drupal/Core/Entity/EntityLastInstalledSchemaRepository.php
index 6130012..1230ecc 100644
--- a/core/lib/Drupal/Core/Entity/EntityLastInstalledSchemaRepository.php
+++ b/core/lib/Drupal/Core/Entity/EntityLastInstalledSchemaRepository.php
@@ -37,6 +37,27 @@ class EntityLastInstalledSchemaRepository implements EntityLastInstalledSchemaRe
/**
* {@inheritdoc}
*/
+ public function getLastInstalledDefinitions() {
+ $all_definitions = $this->keyValueFactory->get('entity.definitions.installed')->getAll();
+
+ // Filter out field storage definitions.
+ $entity_type_definitions = array_filter($all_definitions, function ($key) {
+ return substr($key, -12) === '.entity_type';
+ }, ARRAY_FILTER_USE_KEY);
+
+ // 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}
+ */
public function setLastInstalledDefinition(EntityTypeInterface $entity_type) {
$entity_type_id = $entity_type->id();
$this->keyValueFactory->get('entity.definitions.installed')->set($entity_type_id . '.entity_type', $entity_type);
diff --git a/core/lib/Drupal/Core/Entity/EntityLastInstalledSchemaRepositoryInterface.php b/core/lib/Drupal/Core/Entity/EntityLastInstalledSchemaRepositoryInterface.php
index 53f02a0..af910bb 100644
--- a/core/lib/Drupal/Core/Entity/EntityLastInstalledSchemaRepositoryInterface.php
+++ b/core/lib/Drupal/Core/Entity/EntityLastInstalledSchemaRepositoryInterface.php
@@ -42,6 +42,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.
*
* @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntityDefinitionUpdateTest.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityDefinitionUpdateTest.php
index 01044f7..1a743ec 100644
--- a/core/tests/Drupal/KernelTests/Core/Entity/EntityDefinitionUpdateTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityDefinitionUpdateTest.php
@@ -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);
+ }
+ }
+
}