Change record status: 
Project: 
Introduced in branch: 
main
Description: 

Drupal\Core\TypedData\Plugin\DataType\Map now separates a map that was never given a value from a map given an empty array.

Map::$values defaults to NULL instead of []. TypedDataManager::create() and getPropertyInstance() skip setValue() for NULL, so a map created without a value now returns NULL from getValue():

$definition = MapDataDefinition::create()
  ->setPropertyDefinition('foo', DataDefinition::create('string')->setRequired(TRUE));

// Before: []
// After: NULL
$typed_data_manager->create($definition)->getValue();

// Unchanged: []
$typed_data_manager->create($definition, [])->getValue();

Field items are not affected. FieldItemBase keeps protected $values = [];. Maps nested inside field items are affected, such as the options property on LinkItem. They return NULL when no value was set.

Validation

An empty map given a value ([]) now validates its properties. Before, the validator skipped every empty map, so missing required properties were never reported:

// Before: 0 violations
// After: 1 violation, "foo: This value should not be null."
$typed_data_manager->create($definition, [])->validate();

// Unchanged: 0 violations
$typed_data_manager->create($definition, NULL)->validate();

An optional map that is left out of its parent is still not validated. If you pass [] for an optional map, you now get violations for its required properties. Pass NULL or leave the key out instead.

What to update

  • Code that calls getValue() on a plain map and expects an array should handle NULL:
    $values = $map->getValue() ?? [];
    
  • Custom data types that extend Map directly, not through FieldItemBase, and treat $this->values as an array, should check for NULL or override the default:
    protected $values = [];
    

Generated with the help of an LLM.

Impacts: 
Module developers