function TypeResolver::resolveExpression

Same name and namespace in other branches
  1. 11.x 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.

3 calls to TypeResolver::resolveExpression()
TypedConfigManager::replaceVariable in core/lib/Drupal/Core/Config/TypedConfigManager.php
Resolves a dynamic type expression using configuration data.
TypedConfigManager::resolveExpression in core/lib/Drupal/Core/Config/TypedConfigManager.php
Resolves a dynamic expression.
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\Schema

Code

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.