diff --git a/core/lib/Drupal/Core/Config/Schema/Element.php b/core/lib/Drupal/Core/Config/Schema/Element.php index c492d42..9f49100 100644 --- a/core/lib/Drupal/Core/Config/Schema/Element.php +++ b/core/lib/Drupal/Core/Config/Schema/Element.php @@ -7,6 +7,7 @@ namespace Drupal\Core\Config\Schema; +use Drupal\Core\Config\TypedConfigManagerInterface; use Drupal\Core\TypedData\TypedData; /** @@ -15,6 +16,20 @@ abstract class Element extends TypedData { /** + * The typed config manager. + * + * @var \Drupal\Core\Config\TypedConfigManagerInterface + */ + protected $typedConfig; + + /** + * @param \Drupal\Core\Config\TypedConfigManagerInterface $typed_config + */ + public function setTypedConfig(TypedConfigManagerInterface $typed_config) { + $this->typedConfig = $typed_config; + } + + /** * The configuration value. * * @var mixed @@ -25,7 +40,7 @@ * Create typed config object. */ protected function parseElement($key, $data, $definition) { - return \Drupal::service('config.typed')->create($definition, $data, $key, $this); + return $this->typedConfig->create($definition, $data, $key, $this); } /** @@ -34,7 +49,14 @@ protected function parseElement($key, $data, $definition) { * @return \Drupal\Core\TypedData\DataDefinitionInterface */ protected function buildDataDefinition($definition, $value, $key) { - return \Drupal::service('config.typed')->buildDataDefinition($definition, $value, $key, $this); + return $this->typedConfig->buildDataDefinition($definition, $value, $key, $this); } +// protected function getTypedConfig() { +// if (!isset($this->typedConfig)) { +// return \Drupal::service('config.typed'); +// } +// return $this->typedConfig; +// } + } diff --git a/core/lib/Drupal/Core/Config/TypedConfigManager.php b/core/lib/Drupal/Core/Config/TypedConfigManager.php index fb1c198..2592ac4 100644 --- a/core/lib/Drupal/Core/Config/TypedConfigManager.php +++ b/core/lib/Drupal/Core/Config/TypedConfigManager.php @@ -10,6 +10,7 @@ use Drupal\Component\Utility\NestedArray; use Drupal\Core\Cache\CacheBackendInterface; use Drupal\Core\Config\Schema\ConfigSchemaDiscovery; +use Drupal\Core\Config\Schema\Element; use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\TypedData\TypedDataManager; @@ -295,4 +296,21 @@ public function hasConfigSchema($name) { return is_array($definition) && ($definition['class'] != '\Drupal\Core\Config\Schema\Undefined'); } + protected function alterDefinitions(&$definitions) { + $existing = array_keys($definitions); + parent::alterDefinitions($definitions); // TODO: Change the autogenerated stub + if ($existing !== array_keys($definitions)) { + // Throw an exception. + } + } + + public function createInstance($data_type, array $configuration = array()) { + $instance = parent::createInstance($data_type, $configuration); + if ($instance instanceof Element) { + $instance->setTypedConfig($this); + } + return $instance; + } + + } diff --git a/core/lib/Drupal/Core/EventSubscriber/ConfigImportSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/ConfigImportSubscriber.php index f17d5bd..8e7b885 100644 --- a/core/lib/Drupal/Core/EventSubscriber/ConfigImportSubscriber.php +++ b/core/lib/Drupal/Core/EventSubscriber/ConfigImportSubscriber.php @@ -7,15 +7,21 @@ namespace Drupal\Core\EventSubscriber; +use Drupal\Core\Cache\MemoryBackend; +use Drupal\Core\Cache\NullBackend; use Drupal\Core\Config\Config; use Drupal\Core\Config\ConfigImporterEvent; use Drupal\Core\Config\ConfigImportValidateEventSubscriberBase; use Drupal\Core\Config\ConfigNameException; +use Drupal\Core\Config\Schema\SchemaCheckTrait; +use Drupal\Core\Config\TypedConfigManager; +use Drupal\Core\Config\InstallStorage; /** * Config import subscriber for config import events. */ class ConfigImportSubscriber extends ConfigImportValidateEventSubscriberBase { + use SchemaCheckTrait; /** * Validates the configuration to be imported. @@ -26,6 +32,13 @@ class ConfigImportSubscriber extends ConfigImportValidateEventSubscriberBase { * @throws \Drupal\Core\Config\ConfigNameException */ public function onConfigImporterValidate(ConfigImporterEvent $event) { + $schema_storage = new InstallStorage(InstallStorage::CONFIG_SCHEMA_DIRECTORY); + $typed_config = new TypedConfigManager( + $event->getConfigImporter()->getStorageComparer()->getSourceStorage(), + $schema_storage, + new MemoryBackend('ConfigImportSubscriber'), + \Drupal::moduleHandler() + ); foreach (array('delete', 'create', 'update') as $op) { foreach ($event->getConfigImporter()->getUnprocessedConfiguration($op) as $name) { try { @@ -35,6 +48,26 @@ public function onConfigImporterValidate(ConfigImporterEvent $event) { $message = $this->t('The config name @config_name is invalid.', array('@config_name' => $name)); $event->getConfigImporter()->logError($message); } + if ($op != 'delete') { + $config_data = $event->getConfigImporter() + ->getStorageComparer() + ->getSourceStorage() + ->read($name); + $errors = $this->checkConfigSchema($typed_config, $name, $config_data); + if ($errors === FALSE) { + $event->getConfigImporter() + ->logError($this->t('No schema for !config_name', array('!config_name' => $name))); + } + elseif (is_array($errors)) { + foreach ($errors as $key => $error) { + $event->getConfigImporter() + ->logError($this->t('Schema key @key failed with: @error', array( + '@key' => $key, + '@error' => $error + ))); + } + } + } } } } diff --git a/core/lib/Drupal/Core/Plugin/DefaultPluginManager.php b/core/lib/Drupal/Core/Plugin/DefaultPluginManager.php index 95928e4..4f1efaf 100644 --- a/core/lib/Drupal/Core/Plugin/DefaultPluginManager.php +++ b/core/lib/Drupal/Core/Plugin/DefaultPluginManager.php @@ -224,9 +224,7 @@ protected function findDefinitions() { foreach ($definitions as $plugin_id => &$definition) { $this->processDefinition($definition, $plugin_id); } - if ($this->alterHook) { - $this->moduleHandler->alter($this->alterHook, $definitions); - } + $this->alterDefinitions($definitions); // If this plugin was provided by a module that does not exist, remove the // plugin definition. foreach ($definitions as $plugin_id => $plugin_definition) { @@ -242,4 +240,16 @@ protected function findDefinitions() { return $definitions; } + /** + * Invokes the alter hook if set. + * + * @param $definitions + * The array of definitions found during discovery. + */ + protected function alterDefinitions(&$definitions) { + if ($this->alterHook) { + $this->moduleHandler->alter($this->alterHook, $definitions); + } + } + }