Problem/Motivation
The simple component with null
type (without wrapping it in a string) produces an unhelpful PHP error.
TypeError: Drupal\Core\Theme\Component\ComponentValidator::Drupal\Core\Theme\Component\{closure}(): Argument #1 ($type) must be of type string, null given in Drupal\Core\Theme\Component\ComponentValidator::Drupal\Core\Theme\Component\{closure}() (line 278 of core/lib/Drupal/Core/Theme/Component/ComponentValidator.php).
Steps to reproduce
Create a component propert with type null
:
$schema: https://git.drupalcode.org/project/drupal/-/raw/HEAD/core/assets/schemas/v1/metadata.schema.json
name: Example
status: experimental
props:
type: object
properties:
foo:
type: [null, boolean]
It should be 'null'
, but if you miss that part and get back to component usage later, it is hard to understand which component is the problematic one, because the error doesn't have any hints to it.
private function getClassProps(array $props_schema): array {
$classes_per_prop = [];
foreach ($props_schema['properties'] ?? [] as $prop_name => $prop_def) {
$type = $prop_def['type'] ?? 'null';
$types = is_string($type) ? [$type] : $type;
// For each possible type, check if it is a class.
$class_types = array_filter($types, static fn(string $type) => !in_array(
$type,
['array', 'boolean', 'integer', 'null', 'number', 'object', 'string']
));
$classes_per_prop[$prop_name] = $class_types;
}
return array_filter($classes_per_prop);
}
This is the current code from \Drupal\Core\Theme\Component\ComponentValidator::getClassProps
. As you can see, the anonymous function expects $type
to be a strictly string
. But if it is NULL
, this leads to a PHP error with an useless message.
$type = $prop_def['type'] ?? 'null';
— this part also fails, because it is an array with a NULL value. https://3v4l.org/lfJ6e
Proposed resolution
- Add fool's protection and fix it for the developer by casting
NULL
into 'null'
. - Validate types before it enters
\Drupal\Core\Theme\Component\ComponentValidator::getClassProps
and throw a meaningful exception with mention of component ID and problem.
Remaining tasks
Decide how to handle this. The loop below also expects that all props will be strings, so maybe there should be a validation before that, to ensure that all property types are actual strings?
This is an edge case, but still causing same error:
$schema: https://git.drupalcode.org/project/drupal/-/raw/HEAD/core/assets/schemas/v1/metadata.schema.json
name: Example
status: experimental
props:
type: object
properties:
foo:
type: [!!float 12.3, boolean]