function TypeResolver::resolveExpression
Same name in other branches
- 10 core/lib/Drupal/Core/Config/Schema/TypeResolver.php \Drupal\Core\Config\Schema\TypeResolver::resolveExpression()
Resolves a dynamic type expression using configuration data.
Dynamic type names are nested configuration keys containing expressions to be replaced by the value at the property path that the expression is pointing at. The expression may contain the following special strings:
- '%key', will be replaced by the element's key.
- '%parent', to reference the parent element.
- '%type', to reference the schema definition type. Can only be used in combination with %parent.
There may be nested configuration keys separated by dots or more complex patterns like '%parent.name' which references the 'name' value of the parent element.
Example expressions:
- 'name.subkey', indicates a nested value of the current element.
- '%parent.name', will be replaced by the 'name' value of the parent.
- '%parent.%key', will be replaced by the parent element's key.
- '%parent.%type', will be replaced by the schema type of the parent.
- '%parent.%parent.%type', will be replaced by the schema type of the parent's parent.
Parameters
string $expression: Expression to be resolved.
array|\Drupal\Core\TypedData\TypedDataInterface $data: Configuration data for the element.
Return value
string The value the expression resolves to, or the given expression if it cannot be resolved.
Throws
\LogicException Exception thrown if $expression is not a valid dynamic type expression.
1 call to TypeResolver::resolveExpression()
- TypeResolver::resolveDynamicTypeName in core/
lib/ Drupal/ Core/ Config/ Schema/ TypeResolver.php - Replaces dynamic type expressions in configuration type.
File
-
core/
lib/ Drupal/ Core/ Config/ Schema/ TypeResolver.php, line 81
Class
- TypeResolver
- Provides helper methods for resolving config schema types.
Namespace
Drupal\Core\Config\SchemaCode
public static function resolveExpression(string $expression, array|TypedDataInterface $data) : string {
if ($data instanceof TypedDataInterface) {
$data = [
'%parent' => $data->getParent(),
'%key' => $data->getName(),
'%type' => $data->getDataDefinition()
->getDataType(),
];
}
$parts = explode('.', $expression);
$previous_name = NULL;
// Process each value part, one at a time.
while ($name = array_shift($parts)) {
if (str_starts_with($name, '%') && !in_array($name, [
'%parent',
'%key',
'%type',
], TRUE)) {
throw new \LogicException('`' . $expression . '` is not a valid dynamic type expression. Dynamic type expressions must contain at least `%parent`, `%key`, or `%type`.`');
}
if ($name === '%type' && $previous_name !== '%parent') {
throw new \LogicException('`%type` can only used when immediately preceded by `%parent` in `' . $expression . '`');
}
$previous_name = $name;
if (!is_array($data) || !isset($data[$name])) {
// Key not found, return original value
return $expression;
}
if (!$parts) {
$expression = $data[$name];
if (is_bool($expression)) {
$expression = (int) $expression;
}
// If no more parts left, this is the final property.
return (string) $expression;
}
// Get nested value and continue processing.
if ($name == '%parent') {
/** @var \Drupal\Core\Config\Schema\ArrayElement $parent */
// Switch replacement values with values from the parent.
$parent = $data['%parent'];
$data = $parent->getValue();
$data['%type'] = $parent->getDataDefinition()
->getDataType();
// The special %parent and %key values now need to point one level up.
if ($new_parent = $parent->getParent()) {
$data['%parent'] = $new_parent;
$data['%key'] = $new_parent->getName();
}
continue;
}
$data = $data[$name];
}
// Return the original value
return $expression;
}
Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.