Change record status: 
Project: 
Introduced in version: 
8.x
Description: 

Summary

Field storage definitions define how the field data is stored per entity type. While field definitions may differ between different bundles for a given entity type, these field definitions will share the same field storage definition.

The per-bundle field definitions corresponding to a field storage definition may provide additional information; e.g., they may provide bundle-specific settings or constraints that are not present in the field storage definition. However, bundle field definitions may not override or alter any information provided by the field storage definition except for the label and the description. Any constraints and settings on the field storage definition must be present at the bundle level as well.

The relationship between field storage definitions and field definitions is described in the API change section below.

API changes

Configurable fields

The FieldStorageConfig entity is the field storage. \Drupal\field\FieldStorageConfigInterface now extends \Drupal\Core\Field\FieldStorageDefinitionInterface instead of \Drupal\Core\Field\FieldDefinitionInterface.

The FieldConfig entity is the field definition. \Drupal\field\FieldConfigInterface still extends \Drupal\Core\Field\FieldDefinitionInterface. Please note that the storage definition is not a field definition and cannot be used as such.

Base fields

\Drupal\Core\Field\BaseFieldDefinition represents both the field storage definition and the field definition. It implements both \Drupal\Core\Field\FieldDefinitionInterface and \Drupal\Core\Field\FieldStorageDefinitionInterface.

Working with fields

When working with fields it is important to work in a way that does not make assumptions about whether or not the field definition is from a base field or a configurable field. Therefore, to work with field storage definitions in widgets and formatters call FieldDefinitionInterface::getFieldStorageDefinition().

Method signatures

FieldItemInterface::propertyDefinitions() receives a definition object implementing FieldStorageDefinitionInterface instead of a FieldDefinitionInterface now.

-\Drupal\Core\Field\FieldItemInterface::propertyDefinitions(FieldDefinitionInterface $field_definition)
+\Drupal\Core\Field\FieldItemInterface::propertyDefinitions(FieldStorageDefinitionInterface $field_definition)

FieldItemInterface::schema() receives a definition object implementing FieldStorageDefinitionInterface instead of a FieldDefinitionInterface now.

-\Drupal\Core\Field\FieldItemInterface::schema(FieldDefinitionInterface $field_definition);
+\Drupal\Core\Field\FieldItemInterface::schema(FieldStorageDefinitionInterface $field_definition);

Method Additions

  • \Drupal\Core\Entity\EntityManagerInterface::getFieldStorageDefinitions($entity_type_id)
  • \Drupal\Core\Entity\EntityManager::buildFieldStorageDefinitions($entity_type_id)
    • This method builds an array of objects that implement FieldStorageDefinitionInterface from an entity type ID.

Hooks

Field storage definitions are provided through a module's implementation of hook_entity_field_storage_info(). The Field module implements this hook and returns an array of \Drupal\field\FieldStorageConfigInterface[]. It invokes the getFields() method of the field.info service. This service has a convenience wrapper \Drupal\field\Field::fieldInfo().

Bundle fields either have to override an existing base field, or need to provide a field storage definition via hook_entity_field_storage_info() unless the field is computed. The entity_reference field type is an example of a computed field.

Impacts: 
Module developers