diff --git a/core/lib/Drupal/Core/Entity/ContentEntityDatabaseStorage.php b/core/lib/Drupal/Core/Entity/ContentEntityDatabaseStorage.php index a81c05b..daebb52 100644 --- a/core/lib/Drupal/Core/Entity/ContentEntityDatabaseStorage.php +++ b/core/lib/Drupal/Core/Entity/ContentEntityDatabaseStorage.php @@ -717,7 +717,7 @@ protected function doLoadFieldItems($entities, $age) { $fields = array(); foreach ($bundles as $bundle => $v) { foreach ($this->fieldInfo->getBundleInstances($this->entityTypeId, $bundle) as $field_name => $instance) { - $fields[$field_name] = $instance->getField(); + $fields[$field_name] = $instance; } } @@ -782,9 +782,8 @@ protected function doSaveFieldItems(EntityInterface $entity, $update) { } foreach ($this->fieldInfo->getBundleInstances($entity_type, $bundle) as $field_name => $instance) { - $field = $instance->getField(); - $table_name = static::_fieldTableName($field); - $revision_name = static::_fieldRevisionTableName($field); + $table_name = static::_fieldTableName($instance); + $revision_name = static::_fieldRevisionTableName($instance); // Delete and insert, rather than update, in case a value was added. if ($update) { @@ -804,13 +803,13 @@ protected function doSaveFieldItems(EntityInterface $entity, $update) { // Prepare the multi-insert query. $do_insert = FALSE; $columns = array('entity_id', 'revision_id', 'bundle', 'delta', 'langcode'); - foreach ($field->getColumns() as $column => $attributes) { - $columns[] = static::_fieldColumnName($field, $column); + foreach ($instance->getColumns() as $column => $attributes) { + $columns[] = static::_fieldColumnName($instance, $column); } $query = $this->database->insert($table_name)->fields($columns); $revision_query = $this->database->insert($revision_name)->fields($columns); - $langcodes = $field->isTranslatable() ? $translation_langcodes : array($default_langcode); + $langcodes = $instance->isTranslatable() ? $translation_langcodes : array($default_langcode); foreach ($langcodes as $langcode) { $delta_count = 0; $items = $entity->getTranslation($langcode)->get($field_name); @@ -825,15 +824,15 @@ protected function doSaveFieldItems(EntityInterface $entity, $update) { 'delta' => $delta, 'langcode' => $langcode, ); - foreach ($field->getColumns() as $column => $attributes) { - $column_name = static::_fieldColumnName($field, $column); + foreach ($instance->getColumns() as $column => $attributes) { + $column_name = static::_fieldColumnName($instance, $column); // Serialize the value if specified in the column schema. $record[$column_name] = !empty($attributes['serialize']) ? serialize($item->$column) : $item->$column; } $query->values($record); $revision_query->values($record); - if ($field->getCardinality() != FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED && ++$delta_count == $field->getCardinality()) { + if ($instance->getCardinality() != FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED && ++$delta_count == $instance->getCardinality()) { break; } } @@ -856,9 +855,8 @@ protected function doSaveFieldItems(EntityInterface $entity, $update) { */ protected function doDeleteFieldItems(EntityInterface $entity) { foreach ($this->fieldInfo->getBundleInstances($entity->getEntityTypeId(), $entity->bundle()) as $instance) { - $field = $instance->getField(); - $table_name = static::_fieldTableName($field); - $revision_name = static::_fieldRevisionTableName($field); + $table_name = static::_fieldTableName($instance); + $revision_name = static::_fieldRevisionTableName($instance); $this->database->delete($table_name) ->condition('entity_id', $entity->id()) ->execute(); @@ -875,7 +873,7 @@ protected function doDeleteFieldItemsRevision(EntityInterface $entity) { $vid = $entity->getRevisionId(); if (isset($vid)) { foreach ($this->fieldInfo->getBundleInstances($entity->getEntityTypeId(), $entity->bundle()) as $instance) { - $revision_name = static::_fieldRevisionTableName($instance->getField()); + $revision_name = static::_fieldRevisionTableName($instance); $this->database->delete($revision_name) ->condition('entity_id', $entity->id()) ->condition('revision_id', $vid) @@ -1006,9 +1004,8 @@ public function onFieldDelete(FieldStorageDefinitionInterface $storage_definitio * {@inheritdoc} */ public function onInstanceDelete(FieldDefinitionInterface $field_definition) { - $field = $field_definition->getField(); - $table_name = static::_fieldTableName($field); - $revision_name = static::_fieldRevisionTableName($field); + $table_name = static::_fieldTableName($field_definition); + $revision_name = static::_fieldRevisionTableName($field_definition); $this->database->update($table_name) ->fields(array('deleted' => 1)) ->condition('bundle', $field_definition->bundle) @@ -1028,9 +1025,8 @@ public function onBundleRename($bundle, $bundle_new) { // using the old bundle name. $instances = entity_load_multiple_by_properties('field_instance_config', array('entity_type' => $this->entityTypeId, 'bundle' => $bundle, 'include_deleted' => TRUE)); foreach ($instances as $instance) { - $field = $instance->getField(); - $table_name = static::_fieldTableName($field); - $revision_name = static::_fieldRevisionTableName($field); + $table_name = static::_fieldTableName($instance); + $revision_name = static::_fieldRevisionTableName($instance); $this->database->update($table_name) ->fields(array('bundle' => $bundle_new)) ->condition('bundle', $bundle) @@ -1046,13 +1042,12 @@ public function onBundleRename($bundle, $bundle_new) { * {@inheritdoc} */ protected function readFieldItemsToPurge(EntityInterface $entity, FieldDefinitionInterface $field_definition) { - $field = $field_definition->getField(); - $table_name = static::_fieldTableName($field); + $table_name = static::_fieldTableName($field_definition); $query = $this->database->select($table_name, 't', array('fetch' => \PDO::FETCH_ASSOC)) ->condition('entity_id', $entity->id()) ->orderBy('delta'); - foreach ($field->getColumns() as $column_name => $data) { - $query->addField('t', static::_fieldColumnName($field, $column_name), $column_name); + foreach ($field_definition->getColumns() as $column_name => $data) { + $query->addField('t', static::_fieldColumnName($field_definition, $column_name), $column_name); } return $query->execute()->fetchAll(); } @@ -1061,9 +1056,8 @@ protected function readFieldItemsToPurge(EntityInterface $entity, FieldDefinitio * {@inheritdoc} */ public function purgeFieldItems(EntityInterface $entity, FieldDefinitionInterface $field_definition) { - $field = $field_definition->getField(); - $table_name = static::_fieldTableName($field); - $revision_name = static::_fieldRevisionTableName($field); + $table_name = static::_fieldTableName($field_definition); + $revision_name = static::_fieldRevisionTableName($field_definition); $this->database->delete($table_name) ->condition('entity_id', $entity->id()) ->execute(); @@ -1102,8 +1096,8 @@ public function onFieldPurge(FieldStorageDefinitionInterface $storage_definition */ public static function _fieldSqlSchema(FieldStorageDefinitionInterface $storage_definition, array $schema = NULL) { if ($storage_definition->deleted) { - $description_current = "Data storage for deleted field {$storage_definition->uuid()} ({$storage_definition->getTargetEntityTypeId()}, {$storage_definition->getName()})."; - $description_revision = "Revision archive storage for deleted field {$storage_definition->uuid()} ({$storage_definition->getTargetEntityTypeId()}, {$storage_definition->getName()})."; + $description_current = "Data storage for deleted field {$storage_definition->getUniqueStorageIdentifier()} ({$storage_definition->getTargetEntityTypeId()}, {$storage_definition->getName()})."; + $description_revision = "Revision archive storage for deleted field {$storage_definition->getUniqueStorageIdentifier()} ({$storage_definition->getTargetEntityTypeId()}, {$storage_definition->getName()})."; } else { $description_current = "Data storage for {$storage_definition->getTargetEntityTypeId()} field {$storage_definition->getName()}."; @@ -1269,9 +1263,10 @@ static public function _fieldTableName(FieldStorageDefinitionInterface $storage_ if ($storage_definition->deleted) { // When a field is a deleted, the table is renamed to // {field_deleted_data_FIELD_UUID}. To make sure we don't end up with - // table names longer than 64 characters, we hash the uuid and return the - // first 10 characters so we end up with a short unique ID. - return "field_deleted_data_" . substr(hash('sha256', $storage_definition->uuid()), 0, 10); + // table names longer than 64 characters, we hash the unique storage + // identifier and return the first 10 characters so we end up with a short + // unique ID. + return "field_deleted_data_" . substr(hash('sha256', $storage_definition->getUniqueStorageIdentifier()), 0, 10); } else { return static::_generateFieldTableName($storage_definition, FALSE); @@ -1298,9 +1293,10 @@ static public function _fieldRevisionTableName(FieldStorageDefinitionInterface $ if ($storage_definition->deleted) { // When a field is a deleted, the table is renamed to // {field_deleted_revision_FIELD_UUID}. To make sure we don't end up with - // table names longer than 64 characters, we hash the uuid and return the - // first 10 characters so we end up with a short unique ID. - return "field_deleted_revision_" . substr(hash('sha256', $storage_definition->uuid()), 0, 10); + // table names longer than 64 characters, we hash the unique storage + // identifier and return the first 10 characters so we end up with a short + // unique ID. + return "field_deleted_revision_" . substr(hash('sha256', $storage_definition->getUniqueStorageIdentifier()), 0, 10); } else { return static::_generateFieldTableName($storage_definition, TRUE); @@ -1332,7 +1328,7 @@ static protected function _generateFieldTableName(FieldStorageDefinitionInterfac $separator = $revision ? '_r__' : '__'; // Truncate to the same length for the current and revision tables. $entity_type = substr($storage_definition->getTargetEntityTypeId(), 0, 34); - $field_hash = substr(hash('sha256', $storage_definition->uuid), 0, 10); + $field_hash = substr(hash('sha256', $storage_definition->getUniqueStorageIdentifier()), 0, 10); $table_name = $entity_type . $separator . $field_hash; } return $table_name; diff --git a/core/lib/Drupal/Core/Field/FieldDefinition.php b/core/lib/Drupal/Core/Field/FieldDefinition.php index 8d36fba..6d27e11 100644 --- a/core/lib/Drupal/Core/Field/FieldDefinition.php +++ b/core/lib/Drupal/Core/Field/FieldDefinition.php @@ -539,4 +539,12 @@ public function setCustomStorage($custom_storage) { return $this; } + /** + * {@inheritdoc} + */ + public function getUniqueStorageIdentifier() { + return $this->getTargetEntityTypeId() . '-' . $this->getName(); + } + + } diff --git a/core/lib/Drupal/Core/Field/FieldStorageDefinitionInterface.php b/core/lib/Drupal/Core/Field/FieldStorageDefinitionInterface.php index aa1d90e..c6e7384 100644 --- a/core/lib/Drupal/Core/Field/FieldStorageDefinitionInterface.php +++ b/core/lib/Drupal/Core/Field/FieldStorageDefinitionInterface.php @@ -285,4 +285,7 @@ public function getProvider(); */ public function hasCustomStorage(); + + public function getUniqueStorageIdentifier(); + } diff --git a/core/modules/field/lib/Drupal/field/Entity/FieldConfig.php b/core/modules/field/lib/Drupal/field/Entity/FieldConfig.php index 5ec5f0c..28745ec 100644 --- a/core/modules/field/lib/Drupal/field/Entity/FieldConfig.php +++ b/core/modules/field/lib/Drupal/field/Entity/FieldConfig.php @@ -790,6 +790,14 @@ public function getMainPropertyName() { } /** + * {@inheritdoc} + */ + public function getUniqueStorageIdentifier() { + return $this->uuid(); + } + + + /** * Helper to retrieve the field item class. */ protected function getFieldItemClass() { diff --git a/core/modules/field/lib/Drupal/field/Entity/FieldInstanceConfig.php b/core/modules/field/lib/Drupal/field/Entity/FieldInstanceConfig.php index ff6217d..f084800 100644 --- a/core/modules/field/lib/Drupal/field/Entity/FieldInstanceConfig.php +++ b/core/modules/field/lib/Drupal/field/Entity/FieldInstanceConfig.php @@ -808,4 +808,11 @@ public function isDeleted() { return $this->deleted; } + /** + * {@inheritdoc} + */ + public function getUniqueStorageIdentifier() { + return $this->field->uuid(); + } + } diff --git a/core/tests/Drupal/Tests/Core/Entity/ContentEntityDatabaseStorageTest.php b/core/tests/Drupal/Tests/Core/Entity/ContentEntityDatabaseStorageTest.php index 41358a6..0cbb108 100644 --- a/core/tests/Drupal/Tests/Core/Entity/ContentEntityDatabaseStorageTest.php +++ b/core/tests/Drupal/Tests/Core/Entity/ContentEntityDatabaseStorageTest.php @@ -80,15 +80,17 @@ public function testFieldSqlSchemaForEntityWithStringIdentifier() { ->with('test_entity') ->will($this->returnValue($fields)); - // Define a field definition for a test_field field. - $field = $this->getMock('\Drupal\field\FieldConfigInterface'); + // Define a field definition for a test_field fuuidield. + $field = $this->getMock('\Drupal\Core\Field\FieldStorageDefinitionInterface'); $field->deleted = FALSE; - $field->entity_type = 'test_entity'; - $field->name = 'test_field'; $field->expects($this->any()) ->method('getName') - ->will($this->returnValue('test')); + ->will($this->returnValue('test_field')); + + $field->expects($this->any()) + ->method('getTargetEntityTypeId') + ->will($this->returnValue('test_entity')); $field_schema = array( 'columns' => array(