isNew = FALSE; $this->data = $data; $this->originalData = $this->data; return $this; } /** * Returns whether this configuration object is new. * * @return bool * TRUE if this configuration object does not exist in storage. */ public function isNew() { return $this->isNew; } /** * Retrieves the storage used to load and save this configuration object. * * @return \Drupal\Core\Config\StorageInterface * The configuration storage object. */ public function getStorage() { return $this->storage; } /** * Gets the schema wrapper for the whole configuration object. * * The schema wrapper is dependent on the configuration name and the whole * data structure, so if the name or the data changes in any way, the wrapper * should be reset. * * @return \Drupal\Core\Config\Schema\Element */ protected function getSchemaWrapper() { if (!isset($this->schemaWrapper)) { $this->schemaWrapper = $this->typedConfigManager->createFromNameAndData($this->name, $this->data); } return $this->schemaWrapper; } /** * Validate the values are allowed data types. * * @param string $key * A string that maps to a key within the configuration data. * @param string $value * Value to associate with the key. * * @return null * * @throws \Drupal\Core\Config\UnsupportedDataTypeConfigException * If the value is unsupported in configuration. */ protected function validateValue($key, $value) { // Minimal validation. Should not try to serialize resources or non-arrays. if (is_array($value)) { foreach ($value as $nested_value_key => $nested_value) { $this->validateValue($key . '.' . $nested_value_key, $nested_value); } } elseif ($value !== NULL && !is_scalar($value)) { throw new UnsupportedDataTypeConfigException("Invalid data type for config element {$this->getName()}:$key"); } } /** * Casts the value to correct data type using the configuration schema. * * @param string $key * A string that maps to a key within the configuration data. * @param string $value * Value to associate with the key. * * @return mixed * The value cast to the type indicated in the schema. * * @throws \Drupal\Core\Config\UnsupportedDataTypeConfigException * If the value is unsupported in configuration. */ 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; } }