function TypedConfigManager::buildDataDefinition

Same name and namespace in other branches
  1. 9 core/lib/Drupal/Core/Config/TypedConfigManager.php \Drupal\Core\Config\TypedConfigManager::buildDataDefinition()
  2. 8.9.x core/lib/Drupal/Core/Config/TypedConfigManager.php \Drupal\Core\Config\TypedConfigManager::buildDataDefinition()
  3. 11.x core/lib/Drupal/Core/Config/TypedConfigManager.php \Drupal\Core\Config\TypedConfigManager::buildDataDefinition()

Creates a new data definition object.

Since type definitions may contain variables to be replaced, we need the configuration value to create it.

Parameters

array $definition: The base type definition array, for which a data definition should be created.

$value: Optional value of the configuration element.

string $name: Optional name of the configuration element.

object $parent: Optional parent element.

Return value

\Drupal\Core\TypedData\DataDefinitionInterface A data definition for the given data type.

Overrides TypedConfigManagerInterface::buildDataDefinition

1 call to TypedConfigManager::buildDataDefinition()
TypedConfigManager::createFromNameAndData in core/lib/Drupal/Core/Config/TypedConfigManager.php
Gets typed data for a given configuration name and its values.

File

core/lib/Drupal/Core/Config/TypedConfigManager.php, line 93

Class

TypedConfigManager
Manages config schema type plugins.

Namespace

Drupal\Core\Config

Code

public function buildDataDefinition(array $definition, $value, $name = NULL, $parent = NULL) {
  // Add default values for data type and replace variables.
  $definition += [
    'type' => 'undefined',
  ];
  $replace = [];
  $type = $definition['type'];
  if (strpos($type, ']')) {
    // Replace variable names in definition.
    $replace = is_array($value) ? $value : [];
    if (isset($parent)) {
      $replace['%parent'] = $parent;
    }
    if (isset($name)) {
      $replace['%key'] = $name;
    }
    $type = TypeResolver::resolveDynamicTypeName($type, $replace);
    // Remove the type from the definition so that it is replaced with the
    // concrete type from schema definitions.
    unset($definition['type']);
  }
  // Add default values from type definition.
  $definition += $this->getDefinitionWithReplacements($type, $replace);
  $data_definition = $this->createDataDefinition($definition['type']);
  // Pass remaining values from definition array to data definition.
  foreach ($definition as $key => $value) {
    if (!isset($data_definition[$key])) {
      $data_definition[$key] = $value;
    }
  }
  // All values are optional by default (meaning they can be NULL), except for
  // mappings and sequences. A sequence can only be NULL when `nullable: true`
  // is set on the config schema type definition. This is unintuitive and
  // contradicts Drupal core's documentation.
  // @see https://www.drupal.org/node/2264179
  // @see https://www.drupal.org/node/1978714
  // To gradually evolve configuration schemas in the Drupal ecosystem to be
  // validatable, this needs to be clarified in a non-disruptive way. Any
  // config schema type definition — that is, a top-level entry in a
  // *.schema.yml file — can opt into stricter behavior, whereby a property
  // cannot be NULL unless it specifies `nullable: true`, by adding
  // `FullyValidatable` as a top-level validation constraint.
  // @see https://www.drupal.org/node/3364108
  // @see https://www.drupal.org/node/3364109
  // @see \Drupal\Core\TypedData\TypedDataManager::getDefaultConstraints()
  if ($parent) {
    $root_type = $parent->getRoot()
      ->getDataDefinition()
      ->getDataType();
    $root_type_has_opted_in = FALSE;
    foreach ($parent->getRoot()
      ->getConstraints() as $constraint) {
      if ($constraint instanceof FullyValidatableConstraint) {
        $root_type_has_opted_in = TRUE;
        break;

      }
    }
    // If this is a dynamically typed property path, then not only must the
    // (absolute) root type be considered, but also the (relative) static root
    // type: the resolved type.
    // For example, `block.block.*:settings` has a dynamic type defined:
    // `block.settings.[%parent.plugin]`, but `block.block.*:plugin` does not.
    // Consequently, the value at the `plugin` property path depends only on
    // the `block.block.*` config schema type and hence only that config
    // schema type must have the `FullyValidatable` constraint, because it
    // defines which value are required.
    // In contrast, the `block.block.*:settings` property path depends on
    // whichever dynamic type `block.settings.[%parent.plugin]` resolved to,
    // to be able to know which values are required. Therefore that resolved
    // type determines which values are required and whether it is fully
    // validatable.
    // So for example the `block.settings.system_branding_block` config schema
    // type would also need to have the `FullyValidatable` constraint to
    // consider its schema-defined keys to require values:
    // - use_site_logo
    // - use_site_name
    // - use_site_slogan
    $static_type_root = TypedConfigManager::getStaticTypeRoot($parent);
    $static_type_root_type = $static_type_root->getDataDefinition()
      ->getDataType();
    if ($root_type !== $static_type_root_type) {
      $root_type_has_opted_in = FALSE;
      foreach ($static_type_root->getConstraints() as $c) {
        if ($c instanceof FullyValidatableConstraint) {
          $root_type_has_opted_in = TRUE;
          break;

        }
      }
    }
    if ($root_type_has_opted_in) {
      $data_definition->setRequired(!isset($data_definition['nullable']) || $data_definition['nullable'] === FALSE);
    }
  }
  return $data_definition;
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.