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 handleNULL:
$values = $map->getValue() ?? []; - Custom data types that extend
Mapdirectly, not throughFieldItemBase, and treat$this->valuesas an array, should check forNULLor override the default:
protected $values = [];
Generated with the help of an LLM.