diff --git a/core/lib/Drupal/Core/Config/Schema/Element.php b/core/lib/Drupal/Core/Config/Schema/Element.php index c492d42..6f4fe9d 100644 --- a/core/lib/Drupal/Core/Config/Schema/Element.php +++ b/core/lib/Drupal/Core/Config/Schema/Element.php @@ -22,6 +22,13 @@ protected $value; /** + * The parent element object. + * + * @var Element + */ + protected $parent; + + /** * Create typed config object. */ protected function parseElement($key, $data, $definition) { @@ -37,4 +44,23 @@ protected function buildDataDefinition($definition, $value, $key) { return \Drupal::service('config.typed')->buildDataDefinition($definition, $value, $key, $this); } + /** + * Get the full config path of the element. + * + * @return string + * The full config path of the element starting with the top element key + * followed by a colon followed by element names separated with dots. + * For example: views.view.content:display.default.display_options. + */ + public function getFullName() { + if (isset($this->parent)) { + // Ensure if the parent was the root element, we do not add a dot after. + return str_replace(':.', ':', $this->parent->getFullName() . '.' . $this->getName()); + } + else { + // If there is no parent, this is the root element, add a colon. + return $this->getName() . ':'; + } + } + } diff --git a/core/lib/Drupal/Core/Config/Schema/Mapping.php b/core/lib/Drupal/Core/Config/Schema/Mapping.php index a85fac4..a8d6c53 100644 --- a/core/lib/Drupal/Core/Config/Schema/Mapping.php +++ b/core/lib/Drupal/Core/Config/Schema/Mapping.php @@ -63,7 +63,7 @@ public function get($property_name) { return $element; } else { - throw new \InvalidArgumentException(String::format("The configuration property @key doesn't exist.", array('@key' => $property_name))); + throw new \InvalidArgumentException(String::format("The configuration property @key.@element doesn't exist.", array('@key' => $this->getFullName(), '@element' => $property_name))); } } @@ -131,6 +131,11 @@ public function getPropertyDefinitions() { $this->propertyDefinitions = array(); foreach ($this->getAllKeys() as $key) { $definition = isset($this->definition['mapping'][$key]) ? $this->definition['mapping'][$key] : array(); + if (empty($definition)) { + debug($this->definition['type']); + debug($this->definition['debug']); + throw new \InvalidArgumentException(String::format("The configuration property @key.@element doesn't have schema.", array('@key' => $this->getFullName(), '@element' => $key))); + } $this->propertyDefinitions[$key] = $this->buildDataDefinition($definition, $this->value[$key], $key); } } diff --git a/core/lib/Drupal/Core/Config/Schema/SchemaCheckTrait.php b/core/lib/Drupal/Core/Config/Schema/SchemaCheckTrait.php index 0fccd47..e8debe2 100644 --- a/core/lib/Drupal/Core/Config/Schema/SchemaCheckTrait.php +++ b/core/lib/Drupal/Core/Config/Schema/SchemaCheckTrait.php @@ -55,7 +55,7 @@ public function checkConfigSchema(TypedConfigManagerInterface $typed_config, $co } $definition = $typed_config->getDefinition($config_name); $data_definition = $typed_config->buildDataDefinition($definition, $config_data); - $this->schema = $typed_config->create($data_definition, $config_data); + $this->schema = $typed_config->create($data_definition, $config_data, $config_name); $errors = array(); foreach ($config_data as $key => $value) { $errors = array_merge($errors, $this->checkValue($key, $value)); diff --git a/core/lib/Drupal/Core/Config/StorableConfigBase.php b/core/lib/Drupal/Core/Config/StorableConfigBase.php index 5c6e8b3..5eab003 100644 --- a/core/lib/Drupal/Core/Config/StorableConfigBase.php +++ b/core/lib/Drupal/Core/Config/StorableConfigBase.php @@ -128,7 +128,7 @@ protected function getSchemaWrapper() { if (!isset($this->schemaWrapper)) { $definition = $this->typedConfigManager->getDefinition($this->name); $data_definition = $this->typedConfigManager->buildDataDefinition($definition, $this->data); - $this->schemaWrapper = $this->typedConfigManager->create($data_definition, $this->data); + $this->schemaWrapper = $this->typedConfigManager->create($data_definition, $this->data, $this->name); } return $this->schemaWrapper; } @@ -178,7 +178,10 @@ protected function validateValue($key, $value) { 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)) { + if ($element && ($element instanceof Undefined)) { + throw new ConfigException(String::format("The configuration property @key is undefined.", array('@key' => $element->getFullName()))); + } + elseif ($element && ($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); diff --git a/core/lib/Drupal/Core/Config/TypedConfigManager.php b/core/lib/Drupal/Core/Config/TypedConfigManager.php index d775cc2..1943307 100644 --- a/core/lib/Drupal/Core/Config/TypedConfigManager.php +++ b/core/lib/Drupal/Core/Config/TypedConfigManager.php @@ -71,7 +71,7 @@ public function get($name) { $data = $this->configStorage->read($name); $type_definition = $this->getDefinition($name); $data_definition = $this->buildDataDefinition($type_definition, $data); - return $this->create($data_definition, $data); + return $this->create($data_definition, $data, $name); } /** @@ -91,7 +91,9 @@ public function buildDataDefinition(array $definition, $value, $name = NULL, $pa if (isset($name)) { $replace['%key'] = $name; } + $definition['debug']['dynamic_type'] = $type; $type = $this->replaceName($type, $replace); + $definition['debug']['resolved_type'] = $type; // Remove the type from the definition so that it is replaced with the // concrete type from schema definitions. unset($definition['type']); @@ -135,6 +137,7 @@ public function getDefinition($base_plugin_id, $exception_on_invalid = TRUE) { unset($definition['type']); $this->definitions[$type] = $definition; } + $definition['debug']['generic_type'] = $base_plugin_id; // Add type and default definition class. return $definition + array( 'definition_class' => '\Drupal\Core\TypedData\DataDefinition',