Typed Data API

Same name in other branches
  1. 9 core/core.api.php \typed_data
  2. 8.9.x core/core.api.php \typed_data
  3. 10 core/core.api.php \typed_data

API for describing data based on a set of available data types.

PHP has data types, such as int, string, float, array, etc., and it is an object-oriented language that lets you define classes and interfaces. However, in some cases, it is useful to be able to define an abstract type (as in an interface, free of implementation details), that still has properties (which an interface cannot) as well as meta-data. The Typed Data API provides this abstraction.

Overview

Each data type in the Typed Data API is a plugin class (annotation class example: \Drupal\Core\TypedData\Annotation\DataType); these plugins are managed by the typed_data_manager service (by default \Drupal\Core\TypedData\TypedDataManager). Each data object encapsulates a single piece of data, provides access to the metadata, and provides validation capability. Also, the typed data plugins have a shorthand for easily accessing data values, described in Tree handling.

The metadata of a data object is defined by an object based on a class called the definition class (see \Drupal\Core\TypedData\DataDefinitionInterface). The class used can vary by data type and can be specified in the data type's plugin definition, while the default is set in the $definition_class property of the annotation class. The default class is \Drupal\Core\TypedData\DataDefinition. For data types provided by a plugin deriver, the plugin deriver can set the definition_class property too. The metadata object provides information about the data, such as the data type, whether it is translatable, the names of its properties (for complex types), and who can access it.

See https://www.drupal.org/node/1794140 for more information about the Typed Data API.

Varieties of typed data

There are three kinds of typed data: primitive, complex, and list.

Primitive data types

Primitive data types wrap PHP data types and also serve as building blocks for complex and list typed data. Each primitive data type has an interface that extends \Drupal\Core\TypedData\PrimitiveInterface, with getValue() and setValue() methods for accessing the data value, and a default plugin implementation. Here's a list:

Complex data

Complex data types, with interface \Drupal\Core\TypedData\ComplexDataInterface, represent data with named properties; the properties can be accessed with get() and set() methods. The value of each property is itself a typed data object, which can be primitive, complex, or list data.

The base type for most complex data is the \Drupal\Core\TypedData\Plugin\DataType\Map class, which represents an associative array. Map provides its own definition class in the annotation, \Drupal\Core\TypedData\MapDataDefinition, and most complex data classes extend this class. The getValue() and setValue() methods on the Map class enforce the data definition and its property structure.

The Drupal Field API uses complex typed data for its field items, with definition class \Drupal\Core\Field\TypedData\FieldItemDataDefinition.

Lists

List data types, with interface \Drupal\Core\TypedData\ListInterface, represent data that is an ordered list of typed data, all of the same type. More precisely, the plugins in the list must have the same base plugin ID; however, some types (for example field items and entities) are provided by plugin derivatives and the sub IDs can be different.

Tree handling

Typed data allows you to use shorthand to get data values nested in the implicit tree structure of the data. For example, to get the value from an entity field item, the Entity Field API allows you to call:

$value = $entity->fieldName->propertyName;

This is really shorthand for:

$field_item_list = $entity->get('fieldName');
$field_item = $field_item_list->get(0);
$property = $field_item->get('propertyName');
$value = $property->getValue();

Some notes:

  • $property, $field_item, and $field_item_list are all typed data objects, while $value is a raw PHP value.
  • You can call $property->getParent() to get $field_item, $field_item->getParent() to get $field_item_list, or $field_item_list->getParent() to get $typed_entity ($entity wrapped in a typed data object). $typed_entity->getParent() is NULL.
  • For all of these ->getRoot() returns $typed_entity.
  • The langcode property is on $field_item_list, but you can access it on $property as well, so that all items will report the same langcode.
  • When the value of $property is changed by calling $property->setValue(), $property->onChange() will fire, which in turn calls the parent object's onChange() method and so on. This allows parent objects to react upon changes of contained properties or list items.

Defining data types

To define a new data type:

  • Create a class that implements one of the Typed Data interfaces. Typically, you will want to extend one of the classes listed in the sections above as a starting point.
  • Make your class into a DataType plugin. To do that, put it in namespace \Drupal\your_module\Plugin\DataType (where "your_module" is your module's short name), and add annotation of type \Drupal\Core\TypedData\Annotation\DataType to the documentation header. See the Plugin API topic and the Annotations topic for more information.

Using data types

The data types of the Typed Data API can be used in several ways, once they have been defined:

  • In the Field API, data types can be used as the class in the property definition of the field. See the Field API topic for more information.
  • In configuration schema files, you can use the unique ID ('id' annotation) from any DataType plugin class as the 'type' value for an entry. See the Configuration API topic for more information.
  • If you need to create a typed data object in code, first get the typed_data_manager service from the container or by calling \Drupal::typedDataManager(). Then pass the plugin ID to $manager::createDataDefinition() to create an appropriate data definition object. Then pass the data definition object and the value of the data to $manager::create() to create a typed data object.

See also

Plugin API

Services and Dependency Injection Container

File

core/core.api.php, line 926

Classes

Title Sort descending File name Summary
DataType core/lib/Drupal/Core/TypedData/Attribute/DataType.php Defines a data type attribute.
DataType core/lib/Drupal/Core/TypedData/Annotation/DataType.php Defines a data type annotation object.
ItemList core/lib/Drupal/Core/TypedData/Plugin/DataType/ItemList.php A generic list class.
Map core/lib/Drupal/Core/TypedData/Plugin/DataType/Map.php The "map" data type.
TypedData core/lib/Drupal/Core/TypedData/TypedData.php The abstract base class for typed data.

Interfaces

Title Sort descending File name Summary
BinaryInterface core/lib/Drupal/Core/TypedData/Type/BinaryInterface.php Interface for binary data.
ComplexDataDefinitionInterface core/lib/Drupal/Core/TypedData/ComplexDataDefinitionInterface.php Interface for complex data definitions.
ComplexDataInterface core/lib/Drupal/Core/TypedData/ComplexDataInterface.php Interface for complex data; i.e. data containing named and typed properties.
DataDefinitionInterface core/lib/Drupal/Core/TypedData/DataDefinitionInterface.php Interface for data definitions.
DataReferenceDefinitionInterface core/lib/Drupal/Core/TypedData/DataReferenceDefinitionInterface.php Interface for typed data references.
DateTimeInterface core/lib/Drupal/Core/TypedData/Type/DateTimeInterface.php Interface for dates, optionally including a time.
DecimalInterface core/lib/Drupal/Core/TypedData/Type/DecimalInterface.php Interface for decimal numbers.
DurationInterface core/lib/Drupal/Core/TypedData/Type/DurationInterface.php Interface for durations.
FieldItemDataDefinitionInterface core/lib/Drupal/Core/Field/TypedData/FieldItemDataDefinitionInterface.php Interface for field item data definitions.
FloatInterface core/lib/Drupal/Core/TypedData/Type/FloatInterface.php Interface for floating-point numbers.
IntegerInterface core/lib/Drupal/Core/TypedData/Type/IntegerInterface.php Interface for integer numbers.
ListDataDefinitionInterface core/lib/Drupal/Core/TypedData/ListDataDefinitionInterface.php Interface for data definitions of lists.
ListInterface core/lib/Drupal/Core/TypedData/ListInterface.php Interface for a list of typed data.
PrimitiveInterface core/lib/Drupal/Core/TypedData/PrimitiveInterface.php Interface for primitive data.
StringInterface core/lib/Drupal/Core/TypedData/Type/StringInterface.php Interface for strings.
TypedDataInterface core/lib/Drupal/Core/TypedData/TypedDataInterface.php Interface for typed data objects.
UriInterface core/lib/Drupal/Core/TypedData/Type/UriInterface.php Interface for URIs.

Traits

Title Sort descending File name Summary
ComputedItemListTrait core/lib/Drupal/Core/TypedData/ComputedItemListTrait.php Provides common functionality for computed item lists.

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.