diff --git a/core/core.services.yml b/core/core.services.yml index 32881da..a37caf4 100644 --- a/core/core.services.yml +++ b/core/core.services.yml @@ -206,6 +206,8 @@ services: arguments: ['@container.namespaces', '@service_container', '@module_handler', '@cache.cache', '@language_manager', '@string_translation'] tags: - { name: plugin_manager_cache_clear } + entity.schema_builder: + class: Drupal\Core\Entity\Schema\EntitySchemaBuilder entity.form_builder: class: Drupal\Core\Entity\EntityFormBuilder arguments: ['@entity.manager', '@form_builder'] diff --git a/core/lib/Drupal/Core/Entity/ContentEntityBase.php b/core/lib/Drupal/Core/Entity/ContentEntityBase.php index 82e5241..d8ad815 100644 --- a/core/lib/Drupal/Core/Entity/ContentEntityBase.php +++ b/core/lib/Drupal/Core/Entity/ContentEntityBase.php @@ -205,7 +205,7 @@ public function isTranslatable() { /** * {@inheritdoc} */ - public function preSaveRevision(EntityStorageControllerInterface $storage_controller, \stdClass $record) { + public function preSaveRevision(EntityStorageControllerInterface $storage_controller, array $record) { } /** diff --git a/core/lib/Drupal/Core/Entity/FieldableDatabaseStorageController.php b/core/lib/Drupal/Core/Entity/FieldableDatabaseStorageController.php index 37ba3ee..4228b70 100644 --- a/core/lib/Drupal/Core/Entity/FieldableDatabaseStorageController.php +++ b/core/lib/Drupal/Core/Entity/FieldableDatabaseStorageController.php @@ -248,12 +248,12 @@ public function load($id) { */ protected function mapFromStorageRecords(array $records) { $entities = array(); - foreach ($records as $id => $record) { + foreach ($records as $id => $values) { $entities[$id] = array(); // Skip the item delta and item value levels (if possible) but let the // field assign the value as suiting. This avoids unnecessary array // hierarchies and saves memory here. - foreach ($record as $name => $value) { + foreach ($values as $name => $value) { // Handle columns named [field_name]__[column_name] (e.g for field types // that store several properties). if ($field_name = strstr($name, '__', TRUE)) { @@ -269,7 +269,7 @@ protected function mapFromStorageRecords(array $records) { // If we have no multilingual values we can instantiate entity objecs // right now, otherwise we need to collect all the field values first. if (!$this->dataTable) { - $bundle = $this->bundleKey ? $record->{$this->bundleKey} : FALSE; + $bundle = $this->bundleKey ? $values[$this->bundleKey] : FALSE; // Turn the record into an entity class. $entities[$id] = new $this->entityClass($entities[$id], $this->entityTypeId, $bundle); } @@ -587,14 +587,16 @@ public function save(EntityInterface $entity) { $this->invokeHook('presave', $entity); // Create the storage record to be saved. - $record = $this->mapToStorageRecord($entity); + $values = $this->mapToStorageRecord($entity); if (!$entity->isNew()) { if ($entity->isDefaultRevision()) { - $return = $this->database - ->update($this->baseTable, array('return' => Database::RETURN_INSERT_ID)) - ->fields($record) + $this->database + ->update($this->baseTable) + ->fields($values) + ->condition($this->idKey, $values[$this->idKey]) ->execute(); + $return = SAVED_UPDATED; } else { // @todo, should a different value be returned when saving an entity @@ -602,7 +604,7 @@ public function save(EntityInterface $entity) { $return = FALSE; } if ($this->revisionTable) { - $record->{$this->revisionKey} = $this->saveRevision($entity); + $values[$this->revisionKey] = $this->saveRevision($entity); } if ($this->dataTable) { $this->savePropertyData($entity); @@ -624,14 +626,15 @@ public function save(EntityInterface $entity) { // Ensure the entity is still seen as new after assigning it an id, // while storing its data. $entity->enforceIsNew(); - $return = $this->database + $values[$this->idKey] = $this->database ->insert($this->baseTable, array('return' => Database::RETURN_INSERT_ID)) - ->values($record) + ->fields($values) ->execute(); - $entity->{$this->idKey}->value = (string) $record[$this->idKey]; + $return = SAVED_NEW; + $entity->{$this->idKey}->value = (string) $values[$this->idKey]; if ($this->revisionTable) { $entity->setNewRevision(); - $record->{$this->revisionKey} = $this->saveRevision($entity); + $values[$this->revisionKey] = $this->saveRevision($entity); } if ($this->dataTable) { $this->savePropertyData($entity); @@ -640,7 +643,6 @@ public function save(EntityInterface $entity) { $this->savePropertyData($entity, 'revision_data_table'); } - $entity->enforceIsNew(FALSE); $this->invokeFieldMethod('insert', $entity); $this->saveFieldItems($entity, FALSE); @@ -689,8 +691,7 @@ protected function savePropertyData(EntityInterface $entity, $table_key = 'data_ foreach ($entity->getTranslationLanguages() as $langcode => $language) { $translation = $entity->getTranslation($langcode); - $record = $this->mapToDataStorageRecord($translation, $table_key); - $values = (array) $record; + $values = $this->mapToDataStorageRecord($translation, $table_key); $query ->fields(array_keys($values)) ->values($values); @@ -714,9 +715,11 @@ protected function savePropertyData(EntityInterface $entity, $table_key = 'data_ protected function mapToStorageRecord(ContentEntityInterface $entity, $table_key = 'base_table') { $values = array(); $definitions = $entity->getFieldDefinitions(); + $schema = $this->schemaBuilder->getTableSchema($this->entityType, $definitions, $table_key); + $is_new = $entity->isNew(); $multi_column_fields = array(); - foreach (array_keys($definitions) as $name) { + foreach (array_keys($schema['fields']) as $name) { // Check for fields which store data in multiple columns and process them // separately. if ($field = strstr($name, '__', TRUE)) { @@ -733,11 +736,21 @@ protected function mapToStorageRecord(ContentEntityInterface $entity, $table_key $field_items = $entity->get($field_name); $field_value = $field_items->getValue(); foreach (array_keys($field_items->getFieldDefinition()->getColumns()) as $field_schema_column) { - $values[$field_name . '__' . $field_schema_column] = isset($field_value[0][$field_schema_column]) ? $field_value[0][$field_schema_column] : NULL; + if (isset($schema['fields'][$field_name . '__' . $field_schema_column])) { + $values[$field_name . '__' . $field_schema_column] = isset($field_value[0][$field_schema_column]) ? $field_value[0][$field_schema_column] : NULL; + } } } - return $values; + foreach ($values as $field_name => $value) { + // If we are creating a new entity, we must not populate the record with + // NULL values otherwise defaults would not be applied. + if (isset($value) || !$is_new) { + $record[$field_name] = drupal_schema_get_field_value($schema['fields'][$field_name], $value); + } + } + + return $record; } /** @@ -753,10 +766,10 @@ protected function mapToStorageRecord(ContentEntityInterface $entity, $table_key * An array of values to store. */ protected function mapToDataStorageRecord(ContentEntityInterface $entity, $table_key = 'data_table') { - $record = $this->mapToStorageRecord($entity, $table_key); - $record['langcode'] = $entity->language()->id; - $record['default_langcode'] = intval($record['langcode'] == $entity->getUntranslated()->language()->id); - return $record; + $values = $this->mapToStorageRecord($entity, $table_key); + $values['langcode'] = $entity->language()->id; + $values['default_langcode'] = intval($values['langcode'] == $entity->getUntranslated()->language()->id); + return $values; } /** @@ -769,40 +782,40 @@ protected function mapToDataStorageRecord(ContentEntityInterface $entity, $table * The revision id. */ protected function saveRevision(ContentEntityInterface $entity) { - $record = $this->mapToStorageRecord($entity, 'revision_table'); + $values = $this->mapToStorageRecord($entity, 'revision_table'); // When saving a new revision, set any existing revision ID to NULL so as to // ensure that a new revision will actually be created. - if ($entity->isNewRevision() && isset($record[$this->revisionKey])) { - $record[$this->revisionKey] = NULL; + if ($entity->isNewRevision() && isset($values[$this->revisionKey])) { + $values[$this->revisionKey] = NULL; } - $entity->preSaveRevision($this, $record); + $entity->preSaveRevision($this, $values); if ($entity->isNewRevision()) { - $this->database - ->insert($this->revisionTable) - ->fields($record) + $values[$this->revisionKey] = $this->database + ->insert($this->revisionTable, array('return' => Database::RETURN_INSERT_ID)) + ->fields($values) ->execute(); if ($entity->isDefaultRevision()) { $this->database->update($this->entityType->getBaseTable()) - ->fields(array($this->revisionKey => $record->{$this->revisionKey})) - ->condition($this->idKey, $record->{$this->idKey}) + ->fields(array($this->revisionKey => $values[$this->revisionKey])) + ->condition($this->idKey, $values[$this->idKey]) ->execute(); } } else { $this->database ->update($this->revisionTable) - ->fields($record) - ->condition($this->revisionKey, $record[$this->revisionKey]) + ->fields($values) + ->condition($this->revisionKey, $values[$this->revisionKey]) ->execute(); } // Make sure to update the new revision key for the entity. - $entity->{$this->revisionKey}->value = $record[$this->revisionKey]q; + $entity->{$this->revisionKey}->value = $values[$this->revisionKey]; - return $record[$this->revisionKey]; + return $values[$this->revisionKey]; } /** @@ -933,7 +946,7 @@ protected function doSaveFieldItems(EntityInterface $entity, $update) { foreach ($items as $delta => $item) { // We now know we have someting to insert. $do_insert = TRUE; - $record = array( + $values = array( 'entity_id' => $id, 'revision_id' => $vid, 'bundle' => $bundle, @@ -943,10 +956,10 @@ protected function doSaveFieldItems(EntityInterface $entity, $update) { foreach ($field->getColumns() as $column => $attributes) { $column_name = static::_fieldColumnName($field, $column); // Serialize the value if specified in the column schema. - $record[$column_name] = !empty($attributes['serialize']) ? serialize($item->$column) : $item->$column; + $values[$column_name] = !empty($attributes['serialize']) ? serialize($item->$column) : $item->$column; } - $query->values($record); - $revision_query->values($record); + $query->values($values); + $revision_query->values($values); if ($field->getCardinality() != FieldConfigInterface::CARDINALITY_UNLIMITED && ++$delta_count == $field->getCardinality()) { break; diff --git a/core/lib/Drupal/Core/Entity/Query/Sql/Query.php b/core/lib/Drupal/Core/Entity/Query/Sql/Query.php index 04388aa..cf8eb39 100644 --- a/core/lib/Drupal/Core/Entity/Query/Sql/Query.php +++ b/core/lib/Drupal/Core/Entity/Query/Sql/Query.php @@ -11,7 +11,6 @@ use Drupal\Core\Database\Query\SelectInterface; use Drupal\Core\Entity\EntityManagerInterface; use Drupal\Core\Entity\EntityTypeInterface; -use Drupal\Core\Entity\FieldableDatabaseStorageController; use Drupal\Core\Entity\Query\QueryBase; use Drupal\Core\Entity\Query\QueryException; use Drupal\Core\Entity\Query\QueryInterface; @@ -54,6 +53,13 @@ class Query extends QueryBase implements QueryInterface { protected $connection; /** + * Stores the entity manager used by the query. + * + * @var \Drupal\Core\Entity\EntityManagerInterface + */ + protected $entityManager; + + /** * Constructs a query object. * * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type @@ -101,12 +107,6 @@ protected function prepare() { if ($this->entityType->getDataTable()) { $simple_query = FALSE; } - - $storage_controller = \Drupal::entityManager()->getStorageController($this->entityTypeId); - if ($storage_controller instanceof FieldableDatabaseStorageController) { - $storage_controller->ensureSchema(); - } - $this->sqlQuery = $this->connection->select($base_table, 'base_table', array('conjunction' => $this->conjunction)); $this->sqlQuery->addMetaData('entity_type', $this->entityTypeId); $id_field = $this->entityType->getKey('id'); diff --git a/core/lib/Drupal/Core/Entity/RevisionableInterface.php b/core/lib/Drupal/Core/Entity/RevisionableInterface.php index d246d24..b329ab3 100644 --- a/core/lib/Drupal/Core/Entity/RevisionableInterface.php +++ b/core/lib/Drupal/Core/Entity/RevisionableInterface.php @@ -58,9 +58,9 @@ public function isDefaultRevision($new_value = NULL); * * @param EntityStorageControllerInterface $storage_controller * The entity storage controller object. - * @param \stdClass $record - * The revision object. + * @param array $values + * An array of values to save, keyed by field name. */ - public function preSaveRevision(EntityStorageControllerInterface $storage_controller, \stdClass $record); + public function preSaveRevision(EntityStorageControllerInterface $storage_controller, array $values); } diff --git a/core/lib/Drupal/Core/Entity/Schema/EntitySchemaBuilder.php b/core/lib/Drupal/Core/Entity/Schema/EntitySchemaBuilder.php index 296ea22..a6ac5dc 100644 --- a/core/lib/Drupal/Core/Entity/Schema/EntitySchemaBuilder.php +++ b/core/lib/Drupal/Core/Entity/Schema/EntitySchemaBuilder.php @@ -14,103 +14,158 @@ class EntitySchemaBuilder implements EntitySchemaBuilderInterface { /** + * A static cache of the generated schema arrays. + * + * @var array + */ + protected $schema; + + /** * {@inheritdoc} */ - public function getSchema(ContentEntityType $entity_type, array $field_definitions) { + public function getAllSchema(ContentEntityType $entity_type, array $field_definitions) { // Prepare basic information about the entity type. - $tables = array_filter(array( - 'base_table' => $entity_type->getBaseTable(), - 'revision_table' => $entity_type->getRevisionTable(), - 'data_table' => $entity_type->getDataTable(), - 'revision_data_table' => $entity_type->getRevisionDataTable(), - )); - + $tables = $this->getTables($entity_type); // If this entity type does not support storage, no schema information can // be collected. if (empty($tables)) { - return; - } - - $entity_keys = array_filter(array( - 'id' => $entity_type->getKey('id'), - 'revision' => $entity_type->getKey('revision'), - 'bundle' => $entity_type->getKey('bundle'), - 'uuid' => $entity_type->getKey('uuid'), - )); - // @todo This will become unnecessary once https://drupal.org/node/2143729 - // has landed. - if (isset($tables['data_table'])) { - $entity_keys['language'] = 'langcode'; - $entity_keys['default_language'] = 'default_langcode'; + $this->schema[$entity_type->id()] = NULL; } - // Initialize the table schema. - $schema[$tables['base_table']] = $this->initializeBaseTable($entity_type, $tables, $entity_keys); - if (isset($tables['revision_table'])) { - $schema[$tables['revision_table']] = $this->initializeRevisionTable($entity_type, $tables, $entity_keys); - } - if (isset($tables['data_table'])) { - $schema[$tables['data_table']] = $this->initializeDataTable($entity_type, $tables, $entity_keys); - } - if (isset($tables['revision_data_table'])) { - $schema[$tables['revision_data_table']] = $this->initializeRevisionDataTable($entity_type, $tables, $entity_keys); - } - - // Add the schema from field definitions. - foreach ($field_definitions as $field_name => $field_definition) { - // Computed fields are not stored at all. Fields can also have a custom - // storage that is handled manually by the storage controller or by - // contributed modules, so ignore those as well. - if ($field_definition->isComputed() || ($field_definition->getStorageType() == FieldDefinitionInterface::CUSTOM_STORAGE)) { - continue; + if (!isset($this->schema[$entity_type->id()])) { + // @todo Remove this. This is currently needed because some entity types + // declare a schema that does not match their field definitions. + // Therefore we use the legacy schema if it's still declared. This + // allows to iteratively enable the automatic schema generation for + // all entity types. + if ($base_schema = drupal_get_schema($tables['base_table'])) { + $schema[$tables['base_table']] = $base_schema; + unset($tables['base_table']); + foreach ($tables as $table) { + $schema[$table] = drupal_get_schema($table); + } } - // The entity key fields need to be handled separately. - if (FALSE !== $key = array_search($field_name, $entity_keys)) { - if ($key !== 'default_language') { - $this->addFieldSchema($schema[$tables['base_table']], $field_name, $field_definition); + else { + $entity_keys = array_filter(array( + 'id' => $entity_type->getKey('id'), + 'revision' => $entity_type->getKey('revision'), + 'bundle' => $entity_type->getKey('bundle'), + 'uuid' => $entity_type->getKey('uuid'), + )); + // @todo This will become unnecessary once https://drupal.org/node/2143729 + // has landed. + if (isset($tables['data_table'])) { + $entity_keys['language'] = 'langcode'; + $entity_keys['default_language'] = 'default_langcode'; } - if (isset($tables['revision_table']) && in_array($key, array('id', 'revision', 'language'))) { - $this->addFieldSchema($schema[$tables['revision_table']], $field_name, $field_definition); + + // Initialize the table schema. + $schema[$tables['base_table']] = $this->initializeBaseTable($entity_type, $tables, $entity_keys); + if (isset($tables['revision_table'])) { + $schema[$tables['revision_table']] = $this->initializeRevisionTable($entity_type, $tables, $entity_keys); } - if (isset($tables['revision_table']) && in_array($key, array('id', 'revision', 'language', 'default_language'))) { - $this->addFieldSchema($schema[$tables['data_table']], $field_name, $field_definition); + if (isset($tables['data_table'])) { + $schema[$tables['data_table']] = $this->initializeDataTable($entity_type, $tables, $entity_keys); } - if (isset($tables['revision_data_table']) && in_array($key, array('id', 'revision', 'language', 'default_language'))) { - $this->addFieldSchema($schema[$tables['revision_data_table']], $field_name, $field_definition); + if (isset($tables['revision_data_table'])) { + $schema[$tables['revision_data_table']] = $this->initializeRevisionDataTable($entity_type, $tables, $entity_keys); } - } - // For all other fields, the storage depends on their translatability. - else { - if (!isset($tables['data_table']) || !$field_definition->isTranslatable()) { - $this->addFieldSchema($schema[$tables['base_table']], $field_name, $field_definition); - if ($tables['revision_table']) { - $this->addFieldSchema($schema[$tables['revision_table']], $field_name, $field_definition); + + // Add the schema from field definitions. + foreach ($field_definitions as $field_name => $field_definition) { + // Computed fields are not stored at all. Fields can also have a custom + // storage that is handled manually by the storage controller or by + // contributed modules, so ignore those as well. + // @todo Check for custom storage when https://drupal.org/node/2143069 + // lands. + if ($field_definition->isComputed()) { + continue; } - } - else { - $this->addFieldSchema($schema[$tables['data_table']], $field_name, $field_definition); - if ($tables['revision_data_table']) { - $this->addFieldSchema($schema[$tables['revision_data_table']], $field_name, $field_definition); + + // The entity key fields need to be handled separately. + if (FALSE !== $key = array_search($field_name, $entity_keys)) { + if ($key !== 'default_language') { + $this->addFieldSchema($schema[$tables['base_table']], $field_name, $field_definition); + } + if (isset($tables['revision_table']) && in_array($key, array('id', 'revision', 'language'))) { + $this->addFieldSchema($schema[$tables['revision_table']], $field_name, $field_definition); + } + if (isset($tables['revision_table']) && in_array($key, array('id', 'revision', 'language', 'default_language'))) { + $this->addFieldSchema($schema[$tables['data_table']], $field_name, $field_definition); + } + if (isset($tables['revision_data_table']) && in_array($key, array('id', 'revision', 'language', 'default_language'))) { + $this->addFieldSchema($schema[$tables['revision_data_table']], $field_name, $field_definition); + } + } + // For all other fields, the storage depends on their translatability. + else { + if (!isset($tables['data_table']) || !$field_definition->isTranslatable()) { + $this->addFieldSchema($schema[$tables['base_table']], $field_name, $field_definition); + if ($tables['revision_table']) { + $this->addFieldSchema($schema[$tables['revision_table']], $field_name, $field_definition); + } + } + else { + $this->addFieldSchema($schema[$tables['data_table']], $field_name, $field_definition); + if ($tables['revision_data_table']) { + $this->addFieldSchema($schema[$tables['revision_data_table']], $field_name, $field_definition); + } + } } } + + // Process tables after having gathered field information. + $this->processBaseTable($schema[$tables['base_table']], $entity_type, $entity_keys); + if (isset($tables['revision_table'])) { + $this->processRevisionTable($schema[$tables['revision_table']], $entity_type, $entity_keys); + } + if (isset($tables['data_table'])) { + $this->processDataTable($schema[$tables['data_table']], $entity_type, $entity_keys); + } + if (isset($tables['revision_data_table'])) { + $this->processRevisionDataTable($schema[$tables['revision_data_table']], $entity_type, $entity_keys); + } } - } - // Process tables after having gathered field information. - $this->processBaseTable($schema[$tables['base_table']], $entity_type, $entity_keys); - if (isset($tables['revision_table'])) { - $this->processRevisionTable($schema[$tables['revision_table']], $entity_type, $entity_keys); - } - if (isset($tables['data_table'])) { - $this->processDataTable($schema[$tables['data_table']], $entity_type, $entity_keys); + $this->schema[$entity_type->id()] = $schema; } - if (isset($tables['revision_data_table'])) { - $this->processRevisionDataTable($schema[$tables['revision_data_table']], $entity_type, $entity_keys); + + return $this->schema[$entity_type->id()]; + } + + /** + * {@inheritdoc} + */ + public function getTableSchema(ContentEntityType $entity_type, array $field_definitions, $table_key) { + $tables = $this->getTables($entity_type); + if (isset($tables[$table_key])) { + $schema = $this->getAllSchema($entity_type, $field_definitions); + if (isset($schema[$tables[$table_key]])) { + return $schema[$tables[$table_key]]; + } } } /** + * Gets a list of entity type tables. + * + * @param \Drupal\Core\Entity\ContentEntityType $entity_type + * The entity type. + * + * @return array + * A list of entity type tables, keyed by table key. + */ + protected function getTables(ContentEntityType $entity_type) { + return array_filter(array( + 'base_table' => $entity_type->getBaseTable(), + 'revision_table' => $entity_type->getRevisionTable(), + 'data_table' => $entity_type->getDataTable(), + 'revision_data_table' => $entity_type->getRevisionDataTable(), + )); + } + + /** * Returns the schema for a single field definition. * * @param array $schema @@ -135,6 +190,7 @@ protected function addFieldSchema(array &$schema, $field_name, FieldDefinitionIn $schema['indexes'][$field_name] = array($field_name); } if (!empty($field_schema['foreign keys'])) { + $schema += array('foreign keys' => array()); $schema['foreign keys'] += $field_schema['foreign keys']; } } diff --git a/core/lib/Drupal/Core/Entity/Schema/EntitySchemaBuilderInterface.php b/core/lib/Drupal/Core/Entity/Schema/EntitySchemaBuilderInterface.php index 995f5e3..fbbe01f 100644 --- a/core/lib/Drupal/Core/Entity/Schema/EntitySchemaBuilderInterface.php +++ b/core/lib/Drupal/Core/Entity/Schema/EntitySchemaBuilderInterface.php @@ -16,7 +16,7 @@ interface EntitySchemaBuilderInterface { /** - * Gets the schema array for a given entity type. + * Gets the full schema array for a given entity type. * * @param \Drupal\Core\Entity\ContentEntityType $entity_type * The entity type to return the schema for. @@ -26,6 +26,22 @@ * @return array * A schema array for the entity type's tables. */ - public function getSchema(ContentEntityType $entity_type, array $field_definitions); + public function getAllSchema(ContentEntityType $entity_type, array $field_definitions); + + /** + * Gets the schema array for a single table of a given entity type. + * + * @param \Drupal\Core\Entity\ContentEntityType $entity_type + * The entity type to return the schema for. + * @param \Drupal\Core\Field\FieldDefinitionInterface[] $field_definitions + * The field definitions of the entity type, keyed by field name. + * @param string $table_key + * The table key of the table to get the schema for. + * + * @return array|null + * A schema array for the entity type table, or NULL if the given entity + * type has no schema for the given table key. + */ + public function getTableSchema(ContentEntityType $entity_type, array $field_definitions, $table_key); } diff --git a/core/modules/block/custom_block/lib/Drupal/custom_block/Entity/CustomBlock.php b/core/modules/block/custom_block/lib/Drupal/custom_block/Entity/CustomBlock.php index 84afa71..3a21001 100644 --- a/core/modules/block/custom_block/lib/Drupal/custom_block/Entity/CustomBlock.php +++ b/core/modules/block/custom_block/lib/Drupal/custom_block/Entity/CustomBlock.php @@ -118,8 +118,8 @@ public function getInstances() { /** * {@inheritdoc} */ - public function preSaveRevision(EntityStorageControllerInterface $storage_controller, \stdClass $record) { - parent::preSaveRevision($storage_controller, $record); + public function preSaveRevision(EntityStorageControllerInterface $storage_controller, array $values) { + parent::preSaveRevision($storage_controller, $values); if ($this->isNewRevision()) { // When inserting either a new custom block or a new custom_block @@ -130,14 +130,14 @@ public function preSaveRevision(EntityStorageControllerInterface $storage_contro // that it is at least an empty string in that case. // @todo: Make the {block_custom_revision}.log column nullable so that we // can remove this check. - if (!isset($record['log'])) { - $record['log'] = ''; + if (!isset($values['log'])) { + $values['log'] = ''; } } - elseif (isset($this->original) && (!isset($record['log']) || $record['log'] === '')) { + elseif (isset($this->original) && (!isset($values['log']) || $values['log'] === '')) { // If we are updating an existing custom_block without adding a new // revision and the user did not supply a log, keep the existing one. - $record['log'] = $this->original->getRevisionLog(); + $values['log'] = $this->original->getRevisionLog(); } } diff --git a/core/modules/node/lib/Drupal/node/Entity/Node.php b/core/modules/node/lib/Drupal/node/Entity/Node.php index 1716a0c..7c8aad0 100644 --- a/core/modules/node/lib/Drupal/node/Entity/Node.php +++ b/core/modules/node/lib/Drupal/node/Entity/Node.php @@ -78,8 +78,8 @@ public function getRevisionId() { /** * {@inheritdoc} */ - public function preSaveRevision(EntityStorageControllerInterface $storage_controller, \stdClass $record) { - parent::preSaveRevision($storage_controller, $record); + public function preSaveRevision(EntityStorageControllerInterface $storage_controller, array $values) { + parent::preSaveRevision($storage_controller, $values); if ($this->newRevision) { // When inserting either a new node or a new node revision, $node->log @@ -90,16 +90,16 @@ public function preSaveRevision(EntityStorageControllerInterface $storage_contro // an empty string in that case. // @todo Make the {node_field_revision}.log column nullable so that we // can remove this check. - if (!isset($record['log'])) { - $record['log'] = ''; + if (!isset($values['log'])) { + $values['log'] = ''; } } - elseif (isset($this->original) && (!isset($record['log']) || $record['log'] === '')) { + elseif (isset($this->original) && (!isset($values['log']) || $values['log'] === '')) { // If we are updating an existing node without adding a new revision, we // need to make sure $entity->log is reset whenever it is empty. // Therefore, this code allows us to avoid clobbering an existing log // entry with an empty one. - $record['log'] = $this->original->log->value; + $values['log'] = $this->original->log->value; } } diff --git a/core/modules/user/lib/Drupal/user/UserStorageController.php b/core/modules/user/lib/Drupal/user/UserStorageController.php index 0694019..aca9838 100644 --- a/core/modules/user/lib/Drupal/user/UserStorageController.php +++ b/core/modules/user/lib/Drupal/user/UserStorageController.php @@ -9,7 +9,9 @@ use Drupal\Component\Uuid\UuidInterface; use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Entity\EntityManagerInterface; use Drupal\Core\Entity\EntityTypeInterface; +use Drupal\Core\Entity\Schema\EntitySchemaBuilderInterface; use Drupal\Core\Password\PasswordInterface; use Drupal\Core\Database\Connection; use Drupal\field\FieldInfo; @@ -48,15 +50,17 @@ class UserStorageController extends FieldableDatabaseStorageController implement * The database connection to be used. * @param \Drupal\field\FieldInfo $field_info * The field info service. - * @param \Drupal\Component\Uuid\UuidInterface $uuid_service - * The UUID Service. + * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager + * The entity manager. + * @param \Drupal\Core\Entity\Schema\EntitySchemaBuilderInterface $schema_builder + * The entity schema builder. * @param \Drupal\Core\Password\PasswordInterface $password * The password hashing service. * @param \Drupal\user\UserDataInterface $user_data * The user data service. */ - public function __construct(EntityTypeInterface $entity_type, Connection $database, FieldInfo $field_info, UuidInterface $uuid_service, PasswordInterface $password, UserDataInterface $user_data) { - parent::__construct($entity_type, $database, $field_info, $uuid_service); + public function __construct(EntityTypeInterface $entity_type, Connection $database, FieldInfo $field_info, EntityManagerInterface $entity_manager, EntitySchemaBuilderInterface $schema_builder, PasswordInterface $password, UserDataInterface $user_data) { + parent::__construct($entity_type, $database, $field_info, $entity_manager, $schema_builder); $this->password = $password; $this->userData = $user_data; @@ -70,7 +74,8 @@ public static function createInstance(ContainerInterface $container, EntityTypeI $entity_type, $container->get('database'), $container->get('field.info'), - $container->get('uuid'), + $container->get('entity.manager'), + $container->get('entity.schema_builder'), $container->get('password'), $container->get('user.data') );