function ComponentValidator::validateProps
Same name in this branch
- 11.x core/modules/sdc/src/Component/ComponentValidator.php \Drupal\sdc\Component\ComponentValidator::validateProps()
Same name in other branches
- 10 core/modules/sdc/src/Component/ComponentValidator.php \Drupal\sdc\Component\ComponentValidator::validateProps()
- 10 core/lib/Drupal/Core/Theme/Component/ComponentValidator.php \Drupal\Core\Theme\Component\ComponentValidator::validateProps()
Validates that the props provided to the component.
Valid props are compliant with the schema definition in the component metadata file.
Parameters
array $context: The Twig context that contains the prop data.
\Drupal\Core\Plugin\Component $component: The component to validate the props against.
Return value
bool TRUE if the props adhere to the component definition.
Throws
\Drupal\Core\Render\Component\Exception\InvalidComponentException
File
-
core/
lib/ Drupal/ Core/ Theme/ Component/ ComponentValidator.php, line 140
Class
- ComponentValidator
- Validates a component based on its definition and the component schema.
Namespace
Drupal\Core\Theme\ComponentCode
public function validateProps(array $context, Component $component) : bool {
// If the validator isn't set, then the validation library is not installed.
if (!$this->validator) {
return TRUE;
}
$component_id = $component->getPluginId();
$schema = $component->metadata->schema;
if (!$schema) {
if ($component->metadata->mandatorySchemas) {
throw new InvalidComponentException(sprintf('The component "%s" does not provide schema information. Schema definitions are mandatory for components declared in modules. For components declared in themes, schema definitions are only mandatory if the "enforce_prop_schemas" key is set to "true" in the theme info file.', $component_id));
}
return TRUE;
}
if (empty($schema['properties'])) {
// If there are no properties in the schema there is nothing to validate.
return TRUE;
}
$prop_names = array_keys($schema['properties']);
$props_raw = array_intersect_key($context, array_flip($prop_names));
// Validator::arrayToObjectRecursive stringifies the props using the JSON
// encoder. Before that happens, we want to validate classes. Once the
// classes are validated, we remove them as potential problems for the JSON
// Schema validation.
[
$schema,
$props_raw,
] = $this->validateClassProps($schema, $props_raw, $component_id);
$schema = Validator::arrayToObjectRecursive($schema);
$props = Validator::arrayToObjectRecursive($props_raw);
$validator = new Validator();
$validator->validate($props, $schema, Constraint::CHECK_MODE_TYPE_CAST);
$validator->getErrors();
if ($validator->isValid()) {
return TRUE;
}
// Dismiss type errors if the prop received a render array.
$errors = array_filter($validator->getErrors(), function (array $error) use ($context) : bool {
if (($error['constraint'] ?? '') !== 'type') {
return TRUE;
}
return !Element::isRenderArray($context[$error['property']] ?? NULL);
});
if (empty($errors)) {
return TRUE;
}
$message_parts = array_map(static function (array $error) : string {
// We check the error message instead of values and definitions here
// because it's hard to access both given the possible complexity of a
// schema. Since this is a small non critical DX improvement error
// message checking should be sufficient.
if (str_contains($error['message'], 'NULL value found, but a ')) {
$error['message'] .= '. This may be because the property is empty instead of having data present. If possible fix the source data, use the |default() twig filter, or update the schema to allow multiple types.';
}
return sprintf("[%s] %s", $error['property'], $error['message']);
}, $errors);
$message = implode("/n", $message_parts);
throw new InvalidComponentException($message);
}
Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.