Commit 5d3322eb authored by plach's avatar plach

Issue #2554235 by amateescu, plach, Berdir, Sam152, joelpittet, mbaynton,...

Issue #2554235 by amateescu, plach, Berdir, Sam152, joelpittet, mbaynton, catch, jibran: Make the content entity storage and entity query use the last installed definitions instead of the ones living in code
parent 0b47db51
......@@ -552,7 +552,7 @@ services:
class: Drupal\Core\Cache\MemoryCache\MemoryCache
entity_type.manager:
class: Drupal\Core\Entity\EntityTypeManager
arguments: ['@container.namespaces', '@module_handler', '@cache.discovery', '@string_translation', '@class_resolver']
arguments: ['@container.namespaces', '@module_handler', '@cache.discovery', '@string_translation', '@class_resolver', '@entity.last_installed_schema.repository']
parent: container.trait
tags:
- { name: plugin_manager_cache_clear }
......
......@@ -985,7 +985,7 @@ protected function populateAffectedRevisionTranslations(ContentEntityInterface $
* The sanitized list of entity key values.
*/
protected function cleanIds(array $ids, $entity_key = 'id') {
$definitions = $this->entityFieldManager->getBaseFieldDefinitions($this->entityTypeId);
$definitions = $this->entityFieldManager->getActiveFieldStorageDefinitions($this->entityTypeId);
$field_name = $this->entityType->getKey($entity_key);
if ($field_name && $definitions[$field_name]->getType() == 'integer') {
$ids = array_filter($ids, function ($id) {
......
......@@ -227,6 +227,7 @@ public function updateFieldableEntityType(EntityTypeInterface $entity_type, arra
$original_field_storage_definitions = $this->entityLastInstalledSchemaRepository->getLastInstalledFieldStorageDefinitions($entity_type->id());
$this->entityTypeListener->onFieldableEntityTypeUpdate($entity_type, $original, $field_storage_definitions, $original_field_storage_definitions, $sandbox);
$this->clearCachedDefinitions();
}
/**
......
......@@ -55,6 +55,13 @@ class EntityFieldManager implements EntityFieldManagerInterface {
*/
protected $fieldStorageDefinitions;
/**
* Static cache of active field storage definitions per entity type.
*
* @var array
*/
protected $activeFieldStorageDefinitions;
/**
* An array keyed by entity type. Each value is an array whose keys are
* field names and whose value is an array with two entries:
......@@ -445,6 +452,25 @@ public function getFieldStorageDefinitions($entity_type_id) {
return $this->fieldStorageDefinitions[$entity_type_id];
}
/**
* Gets the active field storage definitions for a content entity type.
*
* @param string $entity_type_id
* The entity type ID. Only content entities are supported.
*
* @return \Drupal\Core\Field\FieldStorageDefinitionInterface[]
* An array of field storage definitions that are active in the current
* request, keyed by field name.
*
* @internal
*/
public function getActiveFieldStorageDefinitions($entity_type_id) {
if (!isset($this->activeFieldStorageDefinitions[$entity_type_id])) {
$this->activeFieldStorageDefinitions[$entity_type_id] = $this->keyValueFactory->get('entity.definitions.installed')->get($entity_type_id . '.field_storage_definitions', []);
}
return $this->activeFieldStorageDefinitions[$entity_type_id] ?: $this->getFieldStorageDefinitions($entity_type_id);
}
/**
* {@inheritdoc}
*/
......@@ -569,6 +595,7 @@ public function clearCachedFieldDefinitions() {
$this->baseFieldDefinitions = [];
$this->fieldDefinitions = [];
$this->fieldStorageDefinitions = [];
$this->activeFieldStorageDefinitions = [];
$this->fieldMap = [];
$this->fieldMapByFieldType = [];
$this->entityDisplayRepository->clearDisplayModeInfo();
......@@ -588,6 +615,7 @@ public function useCaches($use_caches = FALSE) {
$this->fieldDefinitions = [];
$this->baseFieldDefinitions = [];
$this->fieldStorageDefinitions = [];
$this->activeFieldStorageDefinitions = [];
}
}
......
......@@ -209,6 +209,20 @@ public function getFieldStorageDefinitions($entity_type_id) {
return $this->container->get('entity_field.manager')->getFieldStorageDefinitions($entity_type_id);
}
/**
* {@inheritdoc}
*
* @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0.
* Use \Drupal\Core\Entity\EntityFieldManagerInterface::getActiveFieldStorageDefinitions()
* instead.
*
* @see https://www.drupal.org/node/3040966
*/
public function getActiveFieldStorageDefinitions($entity_type_id) {
@trigger_error('EntityManagerInterface::getActiveFieldStorageDefinitions() is deprecated in 8.0.0 and will be removed before Drupal 9.0.0. Use \Drupal\Core\Entity\EntityFieldManagerInterface::getActiveFieldStorageDefinitions() instead. See https://www.drupal.org/node/3040966.', E_USER_DEPRECATED);
return $this->container->get('entity_field.manager')->getActiveFieldStorageDefinitions($entity_type_id);
}
/**
* {@inheritdoc}
*
......@@ -795,6 +809,20 @@ public function hasDefinition($plugin_id) {
return $this->container->get('entity_type.manager')->hasDefinition($plugin_id);
}
/**
* {@inheritdoc}
*
* @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0.
* Use \Drupal\Core\Entity\EntityTypeManagerInterface::getActiveDefinition()
* instead.
*
* @see https://www.drupal.org/node/3040966
*/
public function getActiveDefinition($entity_type_id) {
@trigger_error('EntityManagerInterface::getActiveDefinition() is deprecated in 8.0.0 and will be removed before Drupal 9.0.0. Use \Drupal\Core\Entity\EntityTypeManagerInterface::getActiveDefinition() instead. See https://www.drupal.org/node/3040966.', E_USER_DEPRECATED);
return $this->container->get('entity_type.manager')->getActiveDefinition($entity_type_id);
}
/**
* {@inheritdoc}
*
......
......@@ -58,6 +58,20 @@ class EntityTypeManager extends DefaultPluginManager implements EntityTypeManage
*/
protected $classResolver;
/**
* The entity last installed schema repository.
*
* @var \Drupal\Core\Entity\EntityLastInstalledSchemaRepositoryInterface
*/
protected $entityLastInstalledSchemaRepository;
/**
* A list of entity type definitions that are active for the current request.
*
* @var \Drupal\Core\Entity\EntityTypeInterface[]
*/
protected $activeDefinitions;
/**
* Constructs a new Entity plugin manager.
*
......@@ -72,8 +86,10 @@ class EntityTypeManager extends DefaultPluginManager implements EntityTypeManage
* The string translation.
* @param \Drupal\Core\DependencyInjection\ClassResolverInterface $class_resolver
* The class resolver.
* @param \Drupal\Core\Entity\EntityLastInstalledSchemaRepositoryInterface $entity_last_installed_schema_repository
* The entity last installed schema repository.
*/
public function __construct(\Traversable $namespaces, ModuleHandlerInterface $module_handler, CacheBackendInterface $cache, TranslationInterface $string_translation, ClassResolverInterface $class_resolver) {
public function __construct(\Traversable $namespaces, ModuleHandlerInterface $module_handler, CacheBackendInterface $cache, TranslationInterface $string_translation, ClassResolverInterface $class_resolver, EntityLastInstalledSchemaRepositoryInterface $entity_last_installed_schema_repository) {
parent::__construct('Entity', $namespaces, $module_handler, 'Drupal\Core\Entity\EntityInterface');
$this->setCacheBackend($cache, 'entity_type', ['entity_types']);
......@@ -82,6 +98,7 @@ public function __construct(\Traversable $namespaces, ModuleHandlerInterface $mo
$this->discovery = new AnnotatedClassDiscovery('Entity', $namespaces, 'Drupal\Core\Entity\Annotation\EntityType');
$this->stringTranslation = $string_translation;
$this->classResolver = $class_resolver;
$this->entityLastInstalledSchemaRepository = $entity_last_installed_schema_repository;
}
/**
......@@ -133,11 +150,31 @@ public function getDefinition($entity_type_id, $exception_on_invalid = TRUE) {
throw new PluginNotFoundException($entity_type_id, sprintf('The "%s" entity type does not exist.', $entity_type_id));
}
/**
* Gets the active definition for a content entity type.
*
* @param string $entity_type_id
* The entity type ID.
*
* @return \Drupal\Core\Entity\EntityTypeInterface
* The active entity type definition.
*
* @internal
*/
public function getActiveDefinition($entity_type_id) {
if (!isset($this->activeDefinitions[$entity_type_id])) {
$this->activeDefinitions[$entity_type_id] = $this->entityLastInstalledSchemaRepository->getLastInstalledDefinition($entity_type_id);
}
return $this->activeDefinitions[$entity_type_id] ?: $this->getDefinition($entity_type_id);
}
/**
* {@inheritdoc}
*/
public function clearCachedDefinitions() {
parent::clearCachedDefinitions();
$this->activeDefinitions = [];
$this->handlers = [];
}
......@@ -147,6 +184,7 @@ public function clearCachedDefinitions() {
public function useCaches($use_caches = FALSE) {
parent::useCaches($use_caches);
if (!$use_caches) {
$this->activeDefinitions = [];
$this->handlers = [];
$this->container->get('entity.memory_cache')->reset();
}
......
......@@ -3,6 +3,7 @@
namespace Drupal\Core\Entity\Query\Sql;
use Drupal\Core\Database\Query\SelectInterface;
use Drupal\Core\DependencyInjection\DeprecatedServicePropertyTrait;
use Drupal\Core\Entity\EntityType;
use Drupal\Core\Entity\Query\QueryException;
use Drupal\Core\Entity\Sql\SqlEntityStorageInterface;
......@@ -16,6 +17,13 @@
*/
class Tables implements TablesInterface {
use DeprecatedServicePropertyTrait;
/**
* {@inheritdoc}
*/
protected $deprecatedProperties = ['entityManager' => 'entity.manager'];
/**
* @var \Drupal\Core\Database\Query\SelectInterface
*/
......@@ -44,11 +52,18 @@ class Tables implements TablesInterface {
protected $fieldTables = [];
/**
* The entity manager.
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* The entity field manager.
*
* @var \Drupal\Core\Entity\EntityManager
* @var \Drupal\Core\Entity\EntityFieldManagerInterface
*/
protected $entityManager;
protected $entityFieldManager;
/**
* List of case sensitive fields.
......@@ -62,7 +77,8 @@ class Tables implements TablesInterface {
*/
public function __construct(SelectInterface $sql_query) {
$this->sqlQuery = $sql_query;
$this->entityManager = \Drupal::entityManager();
$this->entityTypeManager = \Drupal::entityTypeManager();
$this->entityFieldManager = \Drupal::service('entity_field.manager');
}
/**
......@@ -85,9 +101,9 @@ public function addField($field, $type, $langcode) {
// This will contain the definitions of the last specifier seen by the
// system.
$propertyDefinitions = [];
$entity_type = $this->entityManager->getDefinition($entity_type_id);
$entity_type = $this->entityTypeManager->getActiveDefinition($entity_type_id);
$field_storage_definitions = $this->entityManager->getFieldStorageDefinitions($entity_type_id);
$field_storage_definitions = $this->entityFieldManager->getActiveFieldStorageDefinitions($entity_type_id);
for ($key = 0; $key <= $count; $key++) {
// This can either be the name of an entity base field or a configurable
// field.
......@@ -118,7 +134,7 @@ public function addField($field, $type, $langcode) {
}
/** @var \Drupal\Core\Entity\Sql\DefaultTableMapping $table_mapping */
$table_mapping = $this->entityManager->getStorage($entity_type_id)->getTableMapping();
$table_mapping = $this->entityTypeManager->getStorage($entity_type_id)->getTableMapping();
// Check whether this field is stored in a dedicated table.
if ($field_storage && $table_mapping->requiresDedicatedTableStorage($field_storage)) {
......@@ -277,8 +293,8 @@ public function addField($field, $type, $langcode) {
if (!$entity_type_id && $target_definition instanceof EntityDataDefinitionInterface) {
$entity_type_id = $target_definition->getEntityTypeId();
}
$entity_type = $this->entityManager->getDefinition($entity_type_id);
$field_storage_definitions = $this->entityManager->getFieldStorageDefinitions($entity_type_id);
$entity_type = $this->entityTypeManager->getActiveDefinition($entity_type_id);
$field_storage_definitions = $this->entityFieldManager->getActiveFieldStorageDefinitions($entity_type_id);
// Add the new entity base table using the table and sql column.
$base_table = $this->addNextBaseTable($entity_type, $table, $sql_column, $field_storage);
$propertyDefinitions = [];
......@@ -364,7 +380,7 @@ protected function ensureFieldTable($index_prefix, &$field, $type, $langcode, $b
if (!isset($this->fieldTables[$index_prefix . $field_name])) {
$entity_type_id = $this->sqlQuery->getMetaData('entity_type');
/** @var \Drupal\Core\Entity\Sql\DefaultTableMapping $table_mapping */
$table_mapping = $this->entityManager->getStorage($entity_type_id)->getTableMapping();
$table_mapping = $this->entityTypeManager->getStorage($entity_type_id)->getTableMapping();
$table = !$this->sqlQuery->getMetaData('all_revisions') ? $table_mapping->getDedicatedDataTableName($field) : $table_mapping->getDedicatedRevisionTableName($field);
if ($field->getCardinality() != 1) {
$this->sqlQuery->addMetaData('simple_query', FALSE);
......@@ -395,7 +411,7 @@ protected function addJoin($type, $table, $join_condition, $langcode, $delta = N
$arguments = [];
if ($langcode) {
$entity_type_id = $this->sqlQuery->getMetaData('entity_type');
$entity_type = $this->entityManager->getDefinition($entity_type_id);
$entity_type = $this->entityTypeManager->getActiveDefinition($entity_type_id);
// Only the data table follows the entity language key, dedicated field
// tables have an hard-coded 'langcode' column.
$langcode_key = $entity_type->getDataTable() == $table ? $entity_type->getKey('langcode') : 'langcode';
......@@ -423,7 +439,7 @@ protected function addJoin($type, $table, $join_condition, $langcode, $delta = N
* mapping is not available, FALSE is returned.
*/
protected function getTableMapping($table, $entity_type_id) {
$storage = $this->entityManager->getStorage($entity_type_id);
$storage = $this->entityTypeManager->getStorage($entity_type_id);
if ($storage instanceof SqlEntityStorageInterface) {
$mapping = $storage->getTableMapping()->getAllColumns($table);
}
......
......@@ -58,15 +58,12 @@ public function onFieldableEntityTypeUpdate(EntityTypeInterface $entity_type, En
throw new EntityStorageException('Missing revision_translation_affected field.');
}
$sandbox['original_storage'] = $original_storage;
$sandbox['temporary_storage'] = $this->entityTypeManager->createHandlerInstance($entity_type->getStorageClass(), $entity_type);
$this->preUpdateEntityTypeSchema($entity_type, $original, $field_storage_definitions, $original_field_storage_definitions, $sandbox);
}
// Copy data from the original storage to the temporary one.
if ($has_data) {
$this->copyData($entity_type, $original, $sandbox);
$this->copyData($entity_type, $original, $field_storage_definitions, $original_field_storage_definitions, $sandbox);
}
else {
// If there is no existing data, we still need to run the
......@@ -127,10 +124,14 @@ protected function postUpdateEntityTypeSchema(EntityTypeInterface $entity_type,
* The updated entity type definition.
* @param \Drupal\Core\Entity\EntityTypeInterface $original
* The original entity type definition.
* @param \Drupal\Core\Field\FieldStorageDefinitionInterface[] $field_storage_definitions
* The updated field storage definitions, including possibly new ones.
* @param \Drupal\Core\Field\FieldStorageDefinitionInterface[] $original_field_storage_definitions
* The original field storage definitions.
* @param array &$sandbox
* The sandbox array from a hook_update_N() implementation.
*/
protected function copyData(EntityTypeInterface $entity_type, EntityTypeInterface $original, array &$sandbox) {
protected function copyData(EntityTypeInterface $entity_type, EntityTypeInterface $original, array $field_storage_definitions, array $original_field_storage_definitions, array &$sandbox) {
/** @var \Drupal\Core\Entity\ContentEntityTypeInterface $entity_type */
$id_key = $entity_type->getKey('id');
$revision_id_key = $entity_type->getKey('revision');
......@@ -139,9 +140,6 @@ protected function copyData(EntityTypeInterface $entity_type, EntityTypeInterfac
$default_langcode_key = $entity_type->getKey('default_langcode');
$revision_translation_affected_key = $entity_type->getKey('revision_translation_affected');
$temporary_storage = $sandbox['temporary_storage'];
$original_storage = $sandbox['original_storage'];
// If 'progress' is not set, then this will be the first run of the batch.
if (!isset($sandbox['progress'])) {
$sandbox['progress'] = 0;
......@@ -174,7 +172,13 @@ protected function copyData(EntityTypeInterface $entity_type, EntityTypeInterfac
->fetchCol();
/** @var \Drupal\Core\Entity\ContentEntityInterface[] $entities */
$entities = $load_revisions ? $original_storage->loadMultipleRevisions($entity_identifiers) : $original_storage->loadMultiple($entity_identifiers);
$entities = $load_revisions ? $this->storage->loadMultipleRevisions($entity_identifiers) : $this->storage->loadMultiple($entity_identifiers);
$temporary_storage = $this->entityTypeManager->createHandlerInstance($entity_type->getStorageClass(), $entity_type);
$temporary_storage->setEntityType($entity_type);
$temporary_storage->setFieldStorageDefinitions($field_storage_definitions);
$temporary_storage->setTableMapping($sandbox['temporary_table_mapping']);
foreach ($entities as $identifier => $entity) {
try {
if (!$original->isRevisionable() && $entity_type->isRevisionable()) {
......
......@@ -2,12 +2,10 @@
namespace Drupal\Core\Field;
use Drupal\Core\Database\DatabaseExceptionWrapper;
use Drupal\Core\Entity\EntityLastInstalledSchemaRepositoryInterface;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Entity\FieldableEntityStorageInterface;
use Drupal\Core\Entity\Sql\SqlContentEntityStorage;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
/**
......@@ -82,17 +80,7 @@ public function onFieldStorageDefinitionCreate(FieldStorageDefinitionInterface $
// @todo Forward this to all interested handlers, not only storage, once
// iterating handlers is possible: https://www.drupal.org/node/2332857.
$storage = clone $this->entityTypeManager->getStorage($entity_type_id);
// Entity type definition updates can change the schema by adding or
// removing entity tables (for example when switching an entity type from
// non-revisionable to revisionable), so CRUD operations on a field storage
// definition need to use the last installed entity type schema.
if ($storage instanceof SqlContentEntityStorage
&& ($last_installed_entity_type = $this->entityLastInstalledSchemaRepository->getLastInstalledDefinition($entity_type_id))) {
$storage->setEntityType($last_installed_entity_type);
}
$storage = $this->entityTypeManager->getStorage($entity_type_id);
if ($storage instanceof FieldStorageDefinitionListenerInterface) {
$storage->onFieldStorageDefinitionCreate($storage_definition);
}
......@@ -111,17 +99,7 @@ public function onFieldStorageDefinitionUpdate(FieldStorageDefinitionInterface $
// @todo Forward this to all interested handlers, not only storage, once
// iterating handlers is possible: https://www.drupal.org/node/2332857.
$storage = clone $this->entityTypeManager->getStorage($entity_type_id);
// Entity type definition updates can change the schema by adding or
// removing entity tables (for example when switching an entity type from
// non-revisionable to revisionable), so CRUD operations on a field storage
// definition need to use the last installed entity type schema.
if ($storage instanceof SqlContentEntityStorage
&& ($last_installed_entity_type = $this->entityLastInstalledSchemaRepository->getLastInstalledDefinition($entity_type_id))) {
$storage->setEntityType($last_installed_entity_type);
}
$storage = $this->entityTypeManager->getStorage($entity_type_id);
if ($storage instanceof FieldStorageDefinitionListenerInterface) {
$storage->onFieldStorageDefinitionUpdate($storage_definition, $original);
}
......@@ -140,32 +118,15 @@ public function onFieldStorageDefinitionDelete(FieldStorageDefinitionInterface $
// @todo Forward this to all interested handlers, not only storage, once
// iterating handlers is possible: https://www.drupal.org/node/2332857.
$storage = clone $this->entityTypeManager->getStorage($entity_type_id);
// Entity type definition updates can change the schema by adding or
// removing entity tables (for example when switching an entity type from
// non-revisionable to revisionable), so CRUD operations on a field storage
// definition need to use the last installed entity type schema.
if ($storage instanceof SqlContentEntityStorage
&& ($last_installed_entity_type = $this->entityLastInstalledSchemaRepository->getLastInstalledDefinition($entity_type_id))) {
$storage->setEntityType($last_installed_entity_type);
}
$storage = $this->entityTypeManager->getStorage($entity_type_id);
// Keep the field definition in the deleted fields repository so we can use
// it later during field_purge_batch(), but only if the field has data.
try {
if ($storage_definition instanceof BaseFieldDefinition && $storage instanceof FieldableEntityStorageInterface && $storage->countFieldData($storage_definition, TRUE)) {
$deleted_storage_definition = clone $storage_definition;
$deleted_storage_definition->setDeleted(TRUE);
$this->deletedFieldsRepository->addFieldDefinition($deleted_storage_definition);
$this->deletedFieldsRepository->addFieldStorageDefinition($deleted_storage_definition);
}
}
catch (DatabaseExceptionWrapper $e) {
// This may happen when changing field storage schema, since we are not
// able to use a table mapping matching the passed storage definition.
// @todo Revisit this once we are able to instantiate the table mapping
// properly. See https://www.drupal.org/node/2274017.
if ($storage_definition instanceof BaseFieldDefinition && $storage instanceof FieldableEntityStorageInterface && $storage->countFieldData($storage_definition, TRUE)) {
$deleted_storage_definition = clone $storage_definition;
$deleted_storage_definition->setDeleted(TRUE);
$this->deletedFieldsRepository->addFieldDefinition($deleted_storage_definition);
$this->deletedFieldsRepository->addFieldStorageDefinition($deleted_storage_definition);
}
if ($storage instanceof FieldStorageDefinitionListenerInterface) {
......
......@@ -531,7 +531,7 @@ public function testNonLangcodeEntityTypeModeration() {
\Drupal::state()->set('entity_test_rev.entity_type', $entity_type);
// Update the entity type in order to remove the 'langcode' field.
$this->applyEntityUpdates('entity_test_rev');
\Drupal::entityDefinitionUpdateManager()->updateFieldableEntityType($entity_type, \Drupal::service('entity_field.manager')->getFieldStorageDefinitions($entity_type->id()));
$workflow = $this->createEditorialWorkflow();
$workflow->getTypePlugin()->addEntityTypeAndBundle('entity_test_rev', 'entity_test_rev');
......
......@@ -97,7 +97,7 @@ protected function addJoin($type, $table, $join_condition, $langcode, $delta = N
if (isset($this->baseTablesEntityType[$base_table])) {
$entity_type_id = $this->baseTablesEntityType[$base_table];
$revision_key = $this->entityManager->getDefinition($entity_type_id)->getKey('revision');
$revision_key = $this->entityTypeManager->getActiveDefinition($entity_type_id)->getKey('revision');
if ($id_field === $revision_key || $id_field === 'revision_id') {
$workspace_association_table = $this->contentWorkspaceTables[$base_table];
......@@ -141,7 +141,7 @@ protected function addNextBaseTable(EntityType $entity_type, $table, $sql_column
*/
public function addWorkspaceAssociationJoin($entity_type_id, $base_table_alias, $active_workspace_id) {
if (!isset($this->contentWorkspaceTables[$base_table_alias])) {
$entity_type = $this->entityManager->getDefinition($entity_type_id);
$entity_type = $this->entityTypeManager->getActiveDefinition($entity_type_id);
$id_field = $entity_type->getKey('id');
// LEFT join the Workspace association entity's table so we can properly
......
......@@ -4,14 +4,14 @@
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\Entity\EntityDisplayRepositoryInterface;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityFieldManager;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityLastInstalledSchemaRepositoryInterface;
use Drupal\Core\Entity\EntityManager;
use Drupal\Core\Entity\EntityRepositoryInterface;
use Drupal\Core\Entity\EntityType;
use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Entity\EntityTypeManager;
use Drupal\Core\Entity\EntityTypeRepositoryInterface;
use Drupal\Tests\UnitTestCase;
......@@ -84,10 +84,10 @@ class EntityManagerTest extends UnitTestCase {
protected function setUp() {
parent::setUp();
$this->entityTypeManager = $this->prophesize(EntityTypeManagerInterface::class);
$this->entityTypeManager = $this->prophesize(EntityTypeManager::class);
$this->entityTypeRepository = $this->prophesize(EntityTypeRepositoryInterface::class);
$this->entityTypeBundleInfo = $this->prophesize(EntityTypeBundleInfoInterface::class);
$this->entityFieldManager = $this->prophesize(EntityFieldManagerInterface::class);
$this->entityFieldManager = $this->prophesize(EntityFieldManager::class);
$this->entityRepository = $this->prophesize(EntityRepositoryInterface::class);
$this->entityDisplayRepository = $this->prophesize(EntityDisplayRepositoryInterface::class);
$this->entityLastInstalledSchemaRepository = $this->prophesize(EntityLastInstalledSchemaRepositoryInterface::class);
......@@ -452,4 +452,22 @@ public function testGetCanonicalMultiple() {
$this->entityManager->getCanonicalMultiple($entity_type_id, $entity_ids, $contexts);
}
/**
* @covers ::getActiveDefinition
*
* @expectedDeprecation EntityManagerInterface::getActiveDefinition() is deprecated in 8.0.0 and will be removed before Drupal 9.0.0. Use \Drupal\Core\Entity\EntityTypeManagerInterface::getActiveDefinition() instead. See https://www.drupal.org/node/3040966.
*/
public function testGetActiveDefinition() {
$this->entityManager->getActiveDefinition('entity_test');
}
/**
* @covers ::getActiveFieldStorageDefinitions
*
* @expectedDeprecation EntityManagerInterface::getActiveFieldStorageDefinitions() is deprecated in 8.0.0 and will be removed before Drupal 9.0.0. Use \Drupal\Core\Entity\EntityFieldManagerInterface::getActiveFieldStorageDefinitions() instead. See https://www.drupal.org/node/3040966.
*/
public function testGetActiveFieldStorageDefinitions() {
$this->entityManager->getActiveFieldStorageDefinitions('entity_test');
}
}
......@@ -14,6 +14,7 @@
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Entity\EntityHandlerBase;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityLastInstalledSchemaRepositoryInterface;
use Drupal\Core\Entity\EntityManagerInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Entity\EntityTypeManager;
......@@ -66,6 +67,13 @@ class EntityTypeManagerTest extends UnitTestCase {
*/
protected $cacheBackend;
/**
* The entity last installed schema repository.
*
* @var \Drupal\Core\Entity\EntityLastInstalledSchemaRepositoryInterface|\Prophecy\Prophecy\ProphecyInterface
*/
protected $entityLastInstalledSchemaRepository;
/**
* {@inheritdoc}
*/
......@@ -78,8 +86,9 @@ protected function setUp() {
$this->cacheBackend = $this->prophesize(CacheBackendInterface::class);
$this->translationManager = $this->prophesize(TranslationInterface::class);
$this->entityLastInstalledSchemaRepository = $this->prophesize(EntityLastInstalledSchemaRepositoryInterface::class);
$this->entityTypeManager = new TestEntityTypeManager(new \ArrayObject(), $this->moduleHandler->reveal(), $this->cacheBackend->reveal(), $this->translationManager->reveal(), $this->getClassResolverStub());
$this->entityTypeManager = new TestEntityTypeManager(new \ArrayObject(), $this->moduleHandler->reveal(), $this->cacheBackend->reveal(), $this->translationManager->reveal(), $this->getClassResolverStub(), $this->entityLastInstalledSchemaRepository->reveal());
$this->discovery = $this->prophesize(DiscoveryInterface::class);
$this->entityTypeManager->setDiscovery($this->discovery->reveal());
}
......
......@@ -4,9 +4,9 @@
use Drupal\Core\Entity\ContentEntityType;
use Drupal\Core\Entity\ContentEntityTypeInterface;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityFieldManager;
use Drupal\Core\Entity\EntityLastInstalledSchemaRepositoryInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Entity\EntityTypeManager;
use Drupal\Core\Entity\Sql\DefaultTableMapping;
use Drupal\Tests\UnitTestCase;
......@@ -76,8 +76,8 @@ class SqlContentEntityStorageSchemaTest extends UnitTestCase {
* {@inheritdoc}
*/
protected function setUp() {
$this->entityTypeManager = $this->createMock(EntityTypeManagerInterface::class);
$this->entityFieldManager = $this->createMock(EntityFieldManagerInterface::class);
$this->entityTypeManager = $this->createMock(EntityTypeManager::class);
$this->entityFieldManager = $this->createMock(EntityFieldManager::class);
$this->entityLastInstalledSchemaRepository = $this->createMock(EntityLastInstalledSchemaRepositoryInterface::class);
$this->storage = $this->getMockBuilder('Drupal\Core\Entity\Sql\SqlContentEntityStorage')
->disableOriginalConstructor()
......@@ -1203,26 +1203,14 @@ public function testRequiresEntityDataMigration($updated_entity_type_definition,
'entity_keys' => ['id' => 'id'],
]);
$original_storage = $this->getMockBuilder('Drupal\Core\Entity\Sql\SqlContentEntityStorage')
->disableOriginalConstructor()
->getMock();
$original_storage->expects($this->exactly(is_null($original_storage_has_data) || !$shared_table_structure_changed ? 0 : 1))
$this->storage->expects($this->exactly(is_null($original_storage_has_data) || !$shared_table_structure_changed ? 0 : 1))
->method('hasData')
->willReturn($original_storage_has_data);
// Assert hasData() is never called on the new storage definition.
$this->storage->expects($this->never())
->method('hasData');
$connection = $this->getMockBuilder('Drupal\Core\Database\Connection')
->disableOriginalConstructor()
->getMock();
$this->entityTypeManager->expects($this->any())
->method('createHandlerInstance')
->willReturn($original_storage);
$this->entityLastInstalledSchemaRepository
->expects($this->any())
->method('getLastInstalledDefinition')
......@@ -1372,11 +1360,21 @@ protected function setUpStorageSchema(array $expected = []) {
->with($this->entityType->id())
->will($this->returnValue($this->entityType));
$this->entityTypeManager->expects($this->any())
->method('getActiveDefinition')
->with($this->entityType->id())
->will($this->returnValue($this->entityType));
$this->entityFieldManager->expects($this->any())
->method('getFieldStorageDefinitions')
->with($this->entityType->id())
->will($this->returnValue($this->storageDefinitions));
$this->entityFieldManager->expects($this->any())
->method('getActiveFieldStorageDefinitions')
->with($this->entityType->id())
->will($this->returnValue($this->storageDefinitions));
$this->dbSchemaHandler = $this->getMockBuilder('Drupal\Core\Database\Schema')
->disableOriginalConstructor()
->getMock();
......
......@@ -10,12 +10,11 @@
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Cache\MemoryCache\MemoryCache;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityFieldManager;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityLastInstalledSchemaRepositoryInterface;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Entity\EntityTypeManager;
use Drupal\Core\Entity\Query\QueryFactoryInterface;
use Drupal\Core\Entity\Sql\DefaultTableMapping;
use Drupal\Core\Entity\Sql\SqlContentEntityStorage;
......@@ -70,13 +69,6 @@ class SqlContentEntityStorageTest extends UnitTestCase {
*/
protected $entityFieldManager;
/**
* The mocked entity last installed schema repository used in this test.
*
* @var \Drupal\Core\Entity\EntityLastInstalledSchemaRepositoryInterface|\PHPUnit_Framework_MockObject_MockObject
*/
protected $entityLastInstalledSchemaRepository;
/**
* The entity type ID.
*
......@@ -131,10 +123,9 @@ protected function setUp() {
$this->container = new ContainerBuilder();
\Drupal::setContainer($this->container);
$this->entityTypeManager = $this->getMock(EntityTypeManagerInterface::class);
$this->entityTypeManager = $this->createMock(EntityTypeManager::class);
$this->entityTypeBundleInfo = $this->createMock(EntityTypeBundleInfoInterface::class);
$this->entityFieldManager = $this->getMock(EntityFieldManagerInterface::class);
$this->entityLastInstalledSchemaRepository = $this->createMock(EntityLastInstalledSchemaRepositoryInterface::class);
$this->entityFieldManager = $this->createMock(EntityFieldManager::class);
$this->moduleHandler = $this->getMock('Drupal\Core\Extension\ModuleHandlerInterface');
$this->cache = $this->getMock('Drupal\Core\Cache\CacheBackendInterface');
$this->languageManager = $this->getMock('Drupal\Core\Language\LanguageManagerInterface');
......@@ -147,7 +138,6 @@ protected function setUp() {
$this->container->set('entity_type.manager', $this->entityTypeMana