Commit b4f282a5 authored by catch's avatar catch

Issue #2144263 by fago, yched, alexpott, Berdir, plach, andypost,...

Issue #2144263 by fago, yched, alexpott, Berdir, plach, andypost, effulgentsia, michaelfavia: Decouple entity field storage from configurable fields.
parent da5ea416
......@@ -57,16 +57,22 @@ function entity_get_bundles($entity_type = NULL) {
* NULL.
*/
function entity_invoke_bundle_hook($hook, $entity_type, $bundle, $bundle_new = NULL) {
\Drupal::entityManager()->clearCachedBundles();
$entity_manager = \Drupal::entityManager();
$entity_manager->clearCachedBundles();
// Notify the entity storage.
$method = 'onBundle' . ucfirst($hook);
$storage = \Drupal::entityManager()->getStorage($entity_type);
$storage = $entity_manager->getStorage($entity_type);
if (method_exists($storage, $method)) {
$storage->$method($bundle, $bundle_new);
}
// Invoke hook_entity_bundle_*() hooks.
\Drupal::moduleHandler()->invokeAll('entity_bundle_' . $hook, array($entity_type, $bundle, $bundle_new));
// Clear the cached field definitions (not needed in case of 'create').
if ($hook == 'rename' || $hook == 'delete') {
$entity_manager->clearCachedFieldDefinitions();
}
}
/**
......
......@@ -8,7 +8,7 @@
namespace Drupal\Core\Entity;
use Drupal\Core\Entity\Query\QueryException;
use Drupal\field\FieldInstanceConfigInterface;
use Drupal\Core\Field\FieldDefinitionInterface;
/**
* Defines a null entity storage.
......@@ -109,13 +109,14 @@ protected function doDeleteFieldItemsRevision(EntityInterface $entity) {
/**
* {@inheritdoc}
*/
protected function readFieldItemsToPurge(EntityInterface $entity, FieldInstanceConfigInterface $instance) {
protected function readFieldItemsToPurge(FieldDefinitionInterface $field_definition, $batch_size) {
return array();
}
/**
* {@inheritdoc}
*/
protected function purgeFieldItems(EntityInterface $entity, FieldInstanceConfigInterface $instance) {
protected function purgeFieldItems(ContentEntityInterface $entity, FieldDefinitionInterface $field_definition) {
}
/**
......@@ -130,4 +131,11 @@ protected function doSave($id, EntityInterface $entity) {
protected function has($id, EntityInterface $entity) {
}
/**
* {@inheritdoc}
*/
public function countFieldData($storage_definition, $as_bool = FALSE) {
return $as_bool ? FALSE : 0;
}
}
......@@ -8,8 +8,9 @@
namespace Drupal\Core\Entity;
use Drupal\Component\Utility\String;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\Cache\Cache;
use Drupal\field\FieldConfigInterface;
use Drupal\field\FieldInstanceConfigInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
......@@ -267,32 +268,32 @@ protected function deleteFieldItemsRevision(EntityInterface $entity) {
/**
* {@inheritdoc}
*/
public function onFieldCreate(FieldConfigInterface $field) { }
public function onFieldStorageDefinitionCreate(FieldStorageDefinitionInterface $storage_definition) { }
/**
* {@inheritdoc}
*/
public function onFieldUpdate(FieldConfigInterface $field) { }
public function onFieldStorageDefinitionUpdate(FieldStorageDefinitionInterface $storage_definition, FieldStorageDefinitionInterface $original) { }
/**
* {@inheritdoc}
*/
public function onFieldDelete(FieldConfigInterface $field) { }
public function onFieldStorageDefinitionDelete(FieldStorageDefinitionInterface $storage_definition) { }
/**
* {@inheritdoc}
*/
public function onInstanceCreate(FieldInstanceConfigInterface $instance) { }
public function onFieldDefinitionCreate(FieldDefinitionInterface $field_definition) { }
/**
* {@inheritdoc}
*/
public function onInstanceUpdate(FieldInstanceConfigInterface $instance) { }
public function onFieldDefinitionUpdate(FieldDefinitionInterface $field_definition, FieldDefinitionInterface $original) { }
/**
* {@inheritdoc}
*/
public function onInstanceDelete(FieldInstanceConfigInterface $instance) { }
public function onFieldDefinitionDelete(FieldDefinitionInterface $field_definition) { }
/**
* {@inheritdoc}
......@@ -312,45 +313,46 @@ public function onBundleDelete($bundle) { }
/**
* {@inheritdoc}
*/
public function onFieldItemsPurge(EntityInterface $entity, FieldInstanceConfigInterface $instance) {
if ($values = $this->readFieldItemsToPurge($entity, $instance)) {
$items = \Drupal::typedDataManager()->create($instance, $values, $instance->getName(), $entity);
public function purgeFieldData(FieldDefinitionInterface $field_definition, $batch_size) {
$items_by_entity = $this->readFieldItemsToPurge($field_definition, $batch_size);
foreach ($items_by_entity as $items) {
$items->delete();
$this->purgeFieldItems($items->getEntity(), $field_definition);
}
$this->purgeFieldItems($entity, $instance);
return count($items_by_entity);
}
/**
* Reads values to be purged for a single field of a single entity.
* Reads values to be purged for a single field.
*
* This method is called during field data purge, on fields for which
* onFieldDelete() or onFieldInstanceDelete() has previously run.
*
* @param \Drupal\Core\Entity\EntityInterface $entity
* The entity.
* @param \Drupal\field\FieldInstanceConfigInterface $instance
* The field instance.
* @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition
* The field definition.
* @param $batch_size
* The maximum number of field data records to purge before returning.
*
* @return array
* The field values, in their canonical array format (numerically indexed
* array of items, each item being a property/value array).
* @return \Drupal\Core\Field\FieldItemListInterface[]
* An array of field item lists, keyed by entity revision id.
*/
abstract protected function readFieldItemsToPurge(EntityInterface $entity, FieldInstanceConfigInterface $instance);
abstract protected function readFieldItemsToPurge(FieldDefinitionInterface $field_definition, $batch_size);
/**
* Removes field data from storage during purge.
* Removes field items from storage per entity during purge.
*
* @param EntityInterface $entity
* The entity whose values are being purged.
* @param FieldInstanceConfigInterface $instance
* @param ContentEntityInterface $entity
* The entity revision, whose values are being purged.
* @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition
* The field whose values are bing purged.
*/
abstract protected function purgeFieldItems(EntityInterface $entity, FieldInstanceConfigInterface $instance);
abstract protected function purgeFieldItems(ContentEntityInterface $entity, FieldDefinitionInterface $field_definition);
/**
* {@inheritdoc}
*/
public function onFieldPurge(FieldConfigInterface $field) { }
public function finalizePurge(FieldStorageDefinitionInterface $storage_definition) { }
/**
* Checks translation statuses and invoke the related hooks if needed.
......
......@@ -394,11 +394,13 @@ protected function buildBaseFieldDefinitions($entity_type_id) {
}
}
// Automatically set the field name for non-configurable fields.
// Automatically set the field name, target entity type and bundle
// for non-configurable fields.
foreach ($base_field_definitions as $field_name => $base_field_definition) {
if ($base_field_definition instanceof FieldDefinition) {
$base_field_definition->setName($field_name);
$base_field_definition->setTargetEntityTypeId($entity_type_id);
$base_field_definition->setBundle(NULL);
}
}
......@@ -491,11 +493,13 @@ protected function buildBundleFieldDefinitions($entity_type_id, $bundle, array $
}
}
// Automatically set the field name for non-configurable fields.
// Automatically set the field name, target entity type and bundle
// for non-configurable fields.
foreach ($bundle_field_definitions as $field_name => $field_definition) {
if ($field_definition instanceof FieldDefinition) {
$field_definition->setName($field_name);
$field_definition->setTargetEntityTypeId($entity_type_id);
$field_definition->setBundle($bundle);
}
}
......
<?php
/**
* @file
* Contains \Drupal\Core\Entity\Exception\StorageDefinitionUpdateForbiddenException.
*/
namespace Drupal\Core\Entity\Exception;
/**
* Exception thrown when a storage definition update is forbidden.
*/
class FieldStorageDefinitionUpdateForbiddenException extends \Exception { }
......@@ -7,71 +7,78 @@
namespace Drupal\Core\Entity;
use Drupal\field\FieldConfigInterface;
use Drupal\field\FieldInstanceConfigInterface;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
interface FieldableEntityStorageInterface extends EntityStorageInterface {
/**
* Allows reaction to the creation of a configurable field.
* Reacts to the creation of a field storage definition.
*
* @param \Drupal\field\FieldConfigInterface $field
* The field being created.
* @param \Drupal\Core\Field\FieldStorageDefinitionInterface $storage_definition
* The definition being created.
*/
public function onFieldCreate(FieldConfigInterface $field);
public function onFieldStorageDefinitionCreate(FieldStorageDefinitionInterface $storage_definition);
/**
* Allows reaction to the update of a configurable field.
* Reacts to the update of a field storage definition.
*
* @param \Drupal\field\FieldConfigInterface $field
* @param \Drupal\Core\Field\FieldStorageDefinitionInterface $storage_definition
* The field being updated.
* @param \Drupal\Core\Field\FieldStorageDefinitionInterface $original
* The original storage definition; i.e., the definition before the update.
*
* @throws \Drupal\Core\Entity\Exception\FieldStorageDefinitionUpdateForbiddenException
* Thrown when the update to the field is forbidden.
*/
public function onFieldUpdate(FieldConfigInterface $field);
public function onFieldStorageDefinitionUpdate(FieldStorageDefinitionInterface $storage_definition, FieldStorageDefinitionInterface $original);
/**
* Allows reaction to the deletion of a configurable field.
* Reacts to the deletion of a field storage definition.
*
* Stored values should not be wiped at once, but marked as 'deleted' so that
* they can go through a proper purge process later on.
*
* @param \Drupal\field\FieldConfigInterface $field
* @param \Drupal\Core\Field\FieldStorageDefinitionInterface $storage_definition
* The field being deleted.
*
* @see fieldPurgeData()
* @see purgeFieldData()
*/
public function onFieldDelete(FieldConfigInterface $field);
public function onFieldStorageDefinitionDelete(FieldStorageDefinitionInterface $storage_definition);
/**
* Allows reaction to the creation of a configurable field instance.
* Reacts to the creation of a field.
*
* @param \Drupal\field\FieldInstanceConfigInterface $instance
* The instance being created.
* @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition
* The field definition created.
*/
public function onInstanceCreate(FieldInstanceConfigInterface $instance);
public function onFieldDefinitionCreate(FieldDefinitionInterface $field_definition);
/**
* Allows reaction to the update of a configurable field instance.
* Reacts to the update of a field.
*
* @param \Drupal\field\FieldInstanceConfigInterface $instance
* The instance being updated.
* @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition
* The field definition being updated.
* @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition
* The original field definition; i.e., the definition before the update.
*/
public function onInstanceUpdate(FieldInstanceConfigInterface $instance);
public function onFieldDefinitionUpdate(FieldDefinitionInterface $field_definition, FieldDefinitionInterface $original);
/**
* Allows reaction to the deletion of a configurable field instance.
* Reacts to the deletion of a field.
*
* Stored values should not be wiped at once, but marked as 'deleted' so that
* they can go through a proper purge process later on.
*
* @param \Drupal\field\FieldInstanceConfigInterface $instance
* The instance being deleted.
* @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition
* The field definition being deleted.
*
* @see fieldPurgeData()
* @see purgeFieldData()
*/
public function onInstanceDelete(FieldInstanceConfigInterface $instance);
public function onFieldDefinitionDelete(FieldDefinitionInterface $field_definition);
/**
* Allows reaction to a bundle being created.
* Reacts to a bundle being created.
*
* @param string $bundle
* The name of the bundle created.
......@@ -79,10 +86,9 @@ public function onInstanceDelete(FieldInstanceConfigInterface $instance);
public function onBundleCreate($bundle);
/**
* Allows reaction to a bundle being renamed.
* Reacts to a bundle being renamed.
*
* This method runs before field instance definitions are updated with the new
* bundle name.
* This method runs before fields are updated with the new bundle name.
*
* @param string $bundle
* The name of the bundle being renamed.
......@@ -92,9 +98,9 @@ public function onBundleCreate($bundle);
public function onBundleRename($bundle, $bundle_new);
/**
* Allows reaction to a bundle being deleted.
* Reacts to a bundle being deleted.
*
* This method runs before field and instance definitions are deleted.
* This method runs before fields are deleted.
*
* @param string $bundle
* The name of the bundle being deleted.
......@@ -102,24 +108,43 @@ public function onBundleRename($bundle, $bundle_new);
public function onBundleDelete($bundle);
/**
* Purges the field data for a single field on a single entity.
* Purges a batch of field data.
*
* @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition
* The deleted field whose data is being purged.
* @param $batch_size
* The maximum number of field data records to purge before returning,
* relating to the count of field data records returned by
* \Drupal\Core\Entity\FieldableEntityStorageInterface::countFieldData().
*
* @return int
* The number of field data records that have been purged.
*/
public function purgeFieldData(FieldDefinitionInterface $field_definition, $batch_size);
/**
* Determines the number of entities with values for a given field.
*
* @param \Drupal\Core\Field\FieldStorageDefinitionInterface $storage_definition
* The field for which to count data records.
* @param bool $as_bool
* (Optional) Optimises the query for checking whether there are any records
* or not. Defaults to FALSE.
*
* The entity itself is not being deleted, and it is quite possible that
* other field data will remain attached to it.
* @return bool|int
* The number of entities. If $as_bool parameter is TRUE then the
* value will either be TRUE or FALSE.
*
* @param \Drupal\Core\Entity\EntityInterface $entity
* The entity whose field data is being purged.
* @param \Drupal\field\FieldInstanceConfigInterface $instance
* The deleted field instance whose data is being purged.
* @see \Drupal\Core\Entity\FieldableEntityStorageInterface::purgeFieldData()
*/
public function onFieldItemsPurge(EntityInterface $entity, FieldInstanceConfigInterface $instance);
public function countFieldData($storage_definition, $as_bool = FALSE);
/**
* Performs final cleanup after all data on all instances has been purged.
* Performs final cleanup after all data of a field has been purged.
*
* @param \Drupal\field\FieldConfigInterface $instance
* @param \Drupal\Core\Field\FieldStorageDefinitionInterface $storage_definition
* The field being purged.
*/
public function onFieldPurge(FieldConfigInterface $field);
public function finalizePurge(FieldStorageDefinitionInterface $storage_definition);
}
......@@ -106,15 +106,7 @@ public function addField($field, $type, $langcode) {
// This can either be the name of an entity base field or a configurable
// field.
$specifier = $specifiers[$key];
// Normally it is a field name, but field_purge_batch() is passing in
// id:$field_id so check that first.
/* @var \Drupal\Core\Field\FieldDefinitionInterface $field */
if (substr($specifier, 0, 3) == 'id:') {
if ($fields = entity_load_multiple_by_properties('field_config', array('uuid' => substr($specifier, 3), 'include_deleted' => TRUE))) {
$field = current($fields);
}
}
elseif (isset($field_storage_definitions[$specifier])) {
if (isset($field_storage_definitions[$specifier])) {
$field = $field_storage_definitions[$specifier];
}
else {
......
......@@ -509,14 +509,33 @@ public function getTargetEntityTypeId() {
* @param string $entity_type_id
* The name of the target entity type to set.
*
* @return static
* The object itself for chaining.
* @return $this
*/
public function setTargetEntityTypeId($entity_type_id) {
$this->definition['entity_type'] = $entity_type_id;
return $this;
}
/**
* {@inheritdoc}
*/
public function getBundle() {
return isset($this->definition['bundle']) ? $this->definition['bundle'] : NULL;
}
/**
* Sets the bundle this field is defined for.
*
* @param string|null $bundle
* The bundle, or NULL if the field is not bundle-specific.
*
* @return $this
*/
public function setBundle($bundle) {
$this->definition['bundle'] = $bundle;
return $this;
}
/**
* {@inheritdoc}
*/
......@@ -576,7 +595,7 @@ public static function getReservedColumns() {
* {@inheritdoc}
*/
public function hasCustomStorage() {
return !empty($this->definition['custom_storage']);
return !empty($this->definition['custom_storage']) || $this->isComputed();
}
/**
......@@ -587,8 +606,14 @@ public function hasCustomStorage() {
* TRUE otherwise.
*
* @return $this
*
* @throws \LogicException
* Thrown if custom storage is to be set to FALSE for a computed field.
*/
public function setCustomStorage($custom_storage) {
if (!$custom_storage && $this->isComputed()) {
throw new \LogicException("Entity storage cannot store a computed field.");
}
$this->definition['custom_storage'] = $custom_storage;
return $this;
}
......@@ -600,4 +625,11 @@ public function getFieldStorageDefinition() {
return $this;
}
/**
* {@inheritdoc}
*/
public function getUniqueStorageIdentifier() {
return $this->getTargetEntityTypeId() . '-' . $this->getName();
}
}
......@@ -75,6 +75,15 @@ public function getName();
*/
public function getType();
/**
* Gets the bundle the field is defined for.
*
* @return string|null
* The bundle the field is defined for, or NULL if it is a base field; i.e.,
* it is not bundle-specific.
*/
public function getBundle();
/**
* Returns whether the display for the field can be configured.
*
......
......@@ -297,4 +297,11 @@ public function getProvider();
*/
public function hasCustomStorage();
/**
* Returns a unique identifier for the field.
*
* @return string
*/
public function getUniqueStorageIdentifier();
}
......@@ -85,9 +85,6 @@ function testCommentInstallAfterContentModule() {
// Purge field data now to allow comment module to be uninstalled once the
// field has been deleted.
field_purge_batch(10);
// Call again as field_purge_batch() won't remove both the instances and
// field in a single pass.
field_purge_batch(10);
// Disable the comment module.
$edit = array();
......
......@@ -6,7 +6,6 @@
*/
use Drupal\Component\Utility\NestedArray;
use Drupal\field\FieldConfigUpdateForbiddenException;
/**
* @defgroup field_types Field Types API
......@@ -248,7 +247,7 @@ function hook_field_info_max_weight($entity_type, $bundle, $context, $context_mo
* that cannot be updated.
*
* To forbid the update from occurring, throw a
* Drupal\field\FieldConfigUpdateForbiddenException.
* \Drupal\Core\Entity\Exception\StorageDefinitionUpdateForbiddenException.
*
* @param \Drupal\field\FieldConfigInterface $field
* The field as it will be post-update.
......@@ -270,7 +269,7 @@ function hook_field_config_update_forbid(\Drupal\field\FieldConfigInterface $fie
->range(0, 1)
->execute();
if ($found) {
throw new FieldConfigUpdateForbiddenException("Cannot update a list field not to include keys with existing data");
throw new \Drupal\Core\Entity\Exception\FieldStorageDefinitionUpdateForbiddenException("Cannot update a list field not to include keys with existing data");
}
}
}
......
......@@ -198,20 +198,27 @@ function field_entity_bundle_field_info(EntityTypeInterface $entity_type, $bundl
}
}
/**
* Implements hook_entity_bundle_rename().
*/
function field_entity_bundle_rename($entity_type, $bundle_old, $bundle_new) {
$instances = entity_load_multiple_by_properties('field_instance_config', array('entity_type' => $entity_type, 'bundle' => $bundle_old));
$instances = entity_load_multiple_by_properties('field_instance_config', array('entity_type' => $entity_type, 'bundle' => $bundle_old, 'include_deleted' => TRUE));
foreach ($instances as $instance) {
if ($instance->entity_type == $entity_type && $instance->bundle == $bundle_old) {
$id_new = $instance->entity_type . '.' . $bundle_new . '.' . $instance->field_name;
$instance->set('id', $id_new);
$instance->bundle = $bundle_new;
$id_new = $instance->entity_type . '.' . $bundle_new . '.' . $instance->field_name;
$instance->set('id', $id_new);
$instance->bundle = $bundle_new;
// Save non-deleted instances.
if (!$instance->isDeleted()) {
$instance->allowBundleRename();
$instance->save();
}
// Update deleted instances directly in the state storage.
else {
$state = \Drupal::state();
$deleted_instances = $state->get('field.instance.deleted') ?: array();
$deleted_instances[$instance->uuid] = $instance->toArray();
$state->set('field.instance.deleted', $deleted_instances);
}
}
}
......
......@@ -80,7 +80,6 @@ function field_purge_batch($batch_size, $field_uuid = NULL) {
else {
$instances = entity_load_multiple_by_properties('field_instance_config', array('deleted' => TRUE, 'include_deleted' => TRUE));
}
$factory = \Drupal::service('entity.query');
$info = \Drupal::entityManager()->getDefinitions();
foreach ($instances as $instance) {
$entity_type = $instance->entity_type;
......@@ -92,36 +91,16 @@ function field_purge_batch($batch_size, $field_uuid = NULL) {
continue;
}
$ids = (object) array(
'entity_type' => $entity_type,
'bundle' => $instance->bundle,
);
// Retrieve some entities.
$query = $factory->get($entity_type)
->condition('id:' . $instance->getFieldStorageDefinition()->uuid() . '.deleted', 1)
->range(0, $batch_size);
// If there's no bundle key, all results will have the same bundle.
if ($bundle_key = $info[$entity_type]->getKey('bundle')) {
$query->condition($bundle_key, $ids->bundle);
}
$results = $query->execute();
if ($results) {
foreach ($results as $revision_id => $entity_id) {
$ids->revision_id = $revision_id;
$ids->entity_id = $entity_id;
$entity = _field_create_entity_from_ids($ids);
\Drupal::entityManager()->getStorage($entity_type)->onFieldItemsPurge($entity, $instance);
$batch_size--;
}
// Only delete up to the maximum number of records.
if ($batch_size == 0) {
break;
}
}
else {
$count_purged = \Drupal::entityManager()->getStorage($entity_type)->purgeFieldData($instance, $batch_size);
if ($count_purged < $batch_size || $count_purged == 0) {
// No field data remains for the instance, so we can remove it.
field_purge_instance($instance);
}
$batch_size -= $count_purged;
// Only delete up to the maximum number of records.
if ($batch_size == 0) {
break;
}
}
// Retrieve all deleted fields. Any that have no instances can be purged.
......@@ -187,7 +166,7 @@ function field_purge_field($field) {
$state->set('field.field.deleted', $deleted_fields);
// Notify the storage layer.
\Drupal::entityManager()->getStorage($field->entity_type)->onFieldPurge($field);
\Drupal::entityManager()->getStorage($field->entity_type)->finalizePurge($field);
// Invoke external hooks after the cache is cleared for API consistency.
\Drupal::moduleHandler()->invokeAll('field_purge_field', array($field));
......
......@@ -75,7 +75,8 @@ protected static function initializeSandbox(array &$context, ConfigImporter $con
$context['sandbox']['field']['steps_to_delete'] = 0;
$fields = static::getFieldsToPurge($context['sandbox']['field']['extensions'], $config_importer->getUnprocessedConfiguration('delete'));
foreach ($fields as $field) {
$row_count = $field->entityCount();
$row_count = \Drupal::entityManager()->getStorage($field->getTargetEntityTypeId())
->countFieldData($field);
if ($row_count > 0) {
// The number of steps to delete each field is determined by the
// purge_batch_size setting. For example if the field has 9 rows and the
......@@ -84,8 +85,8 @@ protected static function initializeSandbox(array &$context, ConfigImporter $con
$context['sandbox']['field']['steps_to_delete'] += $how_many_steps;
}
}
// Each field needs one last field_purge_batch() call to remove the last
// instance and the field itself.
// Each field possibly needs one last field_purge_batch() call to remove the
// last instance and the field itself.
$context['sandbox']['field']['steps_to_delete'] += count($fields);
$context['sandbox']['field']['current_progress'] = 0;
......
......@@ -293,7 +293,7 @@ protected function preSaveNew(EntityStorageInterface $storage) {
$this->settings += $field_type_manager->getDefaultSettings($this->type);
// Notify the entity storage.
$entity_manager->getStorage($this->entity_type)->onFieldCreate($this);
$entity_manager->getStorage($this->entity_type)->onFieldStorageDefinitionCreate($this);
}
/**
......@@ -339,7 +339,7 @@ protected function preSaveUpdated(EntityStorageInterface $storage) {
// Notify the storage. The controller can reject the definition
// update as invalid by raising an exception, which stops execution before
// the definition is written to config.
$entity_manager->getStorage($this->entity_type)->onFieldUpdate($this);
$entity_manager->getStorage($this->entity_type)->onFieldStorageDefinitionUpdate($this, $this->original);
}
/**
......@@ -408,7 +408,7 @@ public static function postDelete(EntityStorageInterface $storage, array $fields
// Notify the storage.
foreach ($fields as $field) {
if (!$field->deleted) {
\Drupal::entityManager()->getStorage($field->entity_type)->onFieldDelete($field);
\Drupal::entityManager()->getStorage($field->entity_type)->onFieldStorageDefinitionDelete($field);
$field->deleted = TRUE;