diff --git a/core/lib/Drupal/Core/Config/Schema/Element.php b/core/lib/Drupal/Core/Config/Schema/Element.php index c492d42..6606e0e 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. + */ + protected 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 5729390..a626b92 100644 --- a/core/lib/Drupal/Core/Config/Schema/Mapping.php +++ b/core/lib/Drupal/Core/Config/Schema/Mapping.php @@ -46,6 +46,10 @@ protected function parse() { * * Since all configuration objects are mappings the function will except a dot * delimited key to access nested values, for example, 'page.front'. + * + * @throws \Drupal\Core\Config\Schema\SchemaIncompleteException + * If a property is requested that does not have schema or does not exist in + * the data. */ public function get($property_name) { $parts = explode('.', $property_name); @@ -55,14 +59,14 @@ public function get($property_name) { $element = $elements[$root_key]; } else { - throw new SchemaIncompleteException(String::format("The configuration property @key doesn't exist.", array('@key' => $property_name))); + throw new SchemaIncompleteException(String::format("@key.@element does not exist or does not have schema defined.", array('@key' => $this->getFullName(), '@element' => $property_name))); } // If $property_name contained a dot recurse into the keys. foreach ($parts as $key) { if (!is_object($element) || !method_exists($element, 'get')) { - throw new SchemaIncompleteException(String::format("The configuration property @key does not exist.", array('@key' => $property_name))); - } + throw new SchemaIncompleteException(String::format("@key.@element does not exist or does not have schema defined.", array('@key' => $this->getFullName(), '@element' => $property_name))); + } $element = $element->get($key); } return $element; diff --git a/core/lib/Drupal/Core/Config/Schema/SchemaCheckTrait.php b/core/lib/Drupal/Core/Config/Schema/SchemaCheckTrait.php index 4348316..893fc6c 100644 --- a/core/lib/Drupal/Core/Config/Schema/SchemaCheckTrait.php +++ b/core/lib/Drupal/Core/Config/Schema/SchemaCheckTrait.php @@ -54,7 +54,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 b2610f7..8700106 100644 --- a/core/lib/Drupal/Core/Config/StorableConfigBase.php +++ b/core/lib/Drupal/Core/Config/StorableConfigBase.php @@ -129,7 +129,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; } @@ -170,16 +170,7 @@ protected function validateValue($key, $value) { * Exception on unsupported/undefined data type deducted. */ protected function castValue($key, $value) { - $element = FALSE; - try { - $element = $this->getSchemaWrapper()->get($key); - } - catch (SchemaIncompleteException $e) { - // @todo Consider making schema handling more strict by throwing - // SchemaIncompleteException for all incomplete schema conditions *and* - // throwing it forward. See https://drupal.org/node/2183983. - // Until then, we need to handle the Undefined case below. - } + $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)) { return $value; diff --git a/core/modules/menu_ui/config/schema/menu_ui.schema.yml b/core/modules/menu_ui/config/schema/menu_ui.schema.yml index ce6be8b..7625f0d 100644 --- a/core/modules/menu_ui/config/schema/menu_ui.schema.yml +++ b/core/modules/menu_ui/config/schema/menu_ui.schema.yml @@ -24,3 +24,6 @@ menu.entity.node.*: sequence: - type: string label: 'Menu machine name' + parent: + type: string + label: 'Parent'