You are here

protected function StorableConfigBase::castValue in Drupal 8

Same name and namespace in other branches
  1. 9 core/lib/Drupal/Core/Config/StorableConfigBase.php \Drupal\Core\Config\StorableConfigBase::castValue()

Casts the value to correct data type using the configuration schema.

Parameters

string $key: A string that maps to a key within the configuration data.

string $value: Value to associate with the key.

Return value

mixed The value cast to the type indicated in the schema.

Throws

\Drupal\Core\Config\UnsupportedDataTypeConfigException If the value is unsupported in configuration.

1 call to StorableConfigBase::castValue()
Config::save in core/lib/Drupal/Core/Config/Config.php
Saves the configuration object.

File

core/lib/Drupal/Core/Config/StorableConfigBase.php, line 178

Class

StorableConfigBase
Provides a base class for configuration objects with storage support.

Namespace

Drupal\Core\Config

Code

protected function castValue($key, $value) {
  $element = $this
    ->getSchemaWrapper()
    ->get($key);

  // Do not cast value if it is unknown or defined to be ignored.
  if ($element && ($element instanceof Undefined || $element instanceof Ignore)) {

    // Do validate the value (may throw UnsupportedDataTypeConfigException)
    // to ensure unsupported types are not supported in this case either.
    $this
      ->validateValue($key, $value);
    return $value;
  }
  if (is_scalar($value) || $value === NULL) {
    if ($element && $element instanceof PrimitiveInterface) {

      // Special handling for integers and floats since the configuration
      // system is primarily concerned with saving values from the Form API
      // we have to special case the meaning of an empty string for numeric
      // types. In PHP this would be casted to a 0 but for the purposes of
      // configuration we need to treat this as a NULL.
      $empty_value = $value === '' && ($element instanceof IntegerInterface || $element instanceof FloatInterface);
      if ($value === NULL || $empty_value) {
        $value = NULL;
      }
      else {
        $value = $element
          ->getCastedValue();
      }
    }
  }
  else {

    // Throw exception on any non-scalar or non-array value.
    if (!is_array($value)) {
      throw new UnsupportedDataTypeConfigException("Invalid data type for config element {$this->getName()}:{$key}");
    }

    // Recurse into any nested keys.
    foreach ($value as $nested_value_key => $nested_value) {
      $value[$nested_value_key] = $this
        ->castValue($key . '.' . $nested_value_key, $nested_value);
    }
    if ($element instanceof Sequence) {
      $data_definition = $element
        ->getDataDefinition();
      if ($data_definition instanceof SequenceDataDefinition) {

        // Apply any sorting defined on the schema.
        switch ($data_definition
          ->getOrderBy()) {
          case 'key':
            ksort($value);
            break;
          case 'value':

            // The PHP documentation notes that "Be careful when sorting
            // arrays with mixed types values because sort() can produce
            // unpredictable results". There is no risk here because
            // \Drupal\Core\Config\StorableConfigBase::castValue() has
            // already cast all values to the same type using the
            // configuration schema.
            sort($value);
            break;
        }
      }
    }
  }
  return $value;
}