diff --git a/core/lib/Drupal/Core/Config/Config.php b/core/lib/Drupal/Core/Config/Config.php index eed4f89..93e7898 100644 --- a/core/lib/Drupal/Core/Config/Config.php +++ b/core/lib/Drupal/Core/Config/Config.php @@ -70,6 +70,13 @@ class Config { protected $data; /** + * The original data of the configuration object. + * + * @var array + */ + protected $originalData; + + /** * The current runtime data. * * The configuration data from storage merged with language, module and @@ -160,6 +167,7 @@ public function initWithData(array $data) { $this->moduleOverrides = array(); $this->isNew = FALSE; $this->replaceData($data); + $this->originalData = $this->data; return $this; } @@ -467,6 +475,7 @@ public function load() { $this->isNew = FALSE; $this->replaceData($data); } + $this->originalData = $this->data; $this->isLoaded = TRUE; return $this; } @@ -496,7 +505,8 @@ public function save() { } $this->storage->write($this->name, $this->data); $this->isNew = FALSE; - $this->notify('save'); + $this->notify(ConfigEvents::SAVE); + $this->originalData = $this->data; return $this; } @@ -512,7 +522,8 @@ public function delete() { $this->storage->delete($this->name); $this->isNew = TRUE; $this->resetOverriddenData(); - $this->notify('delete'); + $this->notify(ConfigEvents::DELETE); + $this->originalData = $this->data; return $this; } @@ -533,7 +544,7 @@ public function getStorage() { * The configuration event name. */ protected function notify($config_event_name) { - $this->eventDispatcher->dispatch('config.' . $config_event_name, new ConfigEvent($this)); + $this->eventDispatcher->dispatch($config_event_name, new ConfigEvent($this)); } /** @@ -650,5 +661,44 @@ public function getRawData() { return $this->data; } + /** + * Gets original data from this configuration object. + * + * @see \Drupal\Core\Config\Config::get() + * + * @return mixed + * The data that was requested. + */ + public function getOriginal($key = '') { + if (!$this->isLoaded) { + $this->load(); + } + + // Apply overrides. + $original_data = $this->originalData; + if (isset($this->languageOverrides) && is_array($this->languageOverrides)) { + $original_data = NestedArray::mergeDeepArray(array($original_data, $this->languageOverrides), TRUE); + } + if (isset($this->moduleOverrides) && is_array($this->moduleOverrides)) { + $original_data = NestedArray::mergeDeepArray(array($original_data, $this->moduleOverrides), TRUE); + } + if (isset($this->settingsOverrides) && is_array($this->settingsOverrides)) { + $original_data = NestedArray::mergeDeepArray(array($original_data, $this->settingsOverrides), TRUE); + } + + if (empty($key)) { + return $original_data; + } + else { + $parts = explode('.', $key); + if (count($parts) == 1) { + return isset($original_data[$key]) ? $original_data[$key] : NULL; + } + else { + $value = NestedArray::getValue($original_data, $parts, $key_exists); + return $key_exists ? $value : NULL; + } + } + } } diff --git a/core/lib/Drupal/Core/Config/ConfigEvent.php b/core/lib/Drupal/Core/Config/ConfigEvent.php index 5b07098..07ef9ec 100644 --- a/core/lib/Drupal/Core/Config/ConfigEvent.php +++ b/core/lib/Drupal/Core/Config/ConfigEvent.php @@ -1,10 +1,15 @@ config; } + + /** + * {@inheritdoc} + */ + public function changed($key) { + return $this->config->get($key) === $this->config->getOriginal($key); + } } diff --git a/core/lib/Drupal/Core/Config/ConfigEventInterface.php b/core/lib/Drupal/Core/Config/ConfigEventInterface.php new file mode 100644 index 0000000..e047fa0 --- /dev/null +++ b/core/lib/Drupal/Core/Config/ConfigEventInterface.php @@ -0,0 +1,29 @@ +language); - $this->eventDispatcher->dispatch('config.module.overrides', $configOverridesEvent); + $this->eventDispatcher->dispatch(ConfigEvents::MODULE_OVERRIDES, $configOverridesEvent); return $configOverridesEvent->getOverrides(); } @@ -307,10 +307,11 @@ public function rename($old_name, $new_name) { unset($this->cache[$old_cache_key]); } - $new_cache_key = $this->getCacheKey($new_name); - $this->cache[$new_cache_key] = new Config($new_name, $this->storage, $this->eventDispatcher, $this->typedConfigManager, $this->language); - $this->cache[$new_cache_key]->load(); - return $this->cache[$new_cache_key]; + // Prime the cache and laod the configuration with the correct overrides. + $config = $this->get($new_name); + $this->eventDispatcher->dispatch(ConfigEvents::RENAME, new ConfigRenameEvent($config, $old_name)); + + return $config; } /** @@ -467,7 +468,7 @@ public function onConfigSave(ConfigEvent $event) { * {@inheritdoc} */ static function getSubscribedEvents() { - $events['config.save'][] = array('onConfigSave', 255); + $events[ConfigEvents::SAVE][] = array('onConfigSave', 255); return $events; } diff --git a/core/lib/Drupal/Core/Config/ConfigRenameEvent.php b/core/lib/Drupal/Core/Config/ConfigRenameEvent.php new file mode 100644 index 0000000..e4e4ffc --- /dev/null +++ b/core/lib/Drupal/Core/Config/ConfigRenameEvent.php @@ -0,0 +1,42 @@ +config = $confg; + $this->oldName = $old_name; + } + + /** + * Gets the old configuration object name. + * + * @return string + * The old configuration object name. + */ + public function getOldName() { + return $this->oldName; + } + +} diff --git a/core/modules/config/lib/Drupal/config/Tests/ConfigEventsTest.php b/core/modules/config/lib/Drupal/config/Tests/ConfigEventsTest.php new file mode 100644 index 0000000..38d2d31 --- /dev/null +++ b/core/modules/config/lib/Drupal/config/Tests/ConfigEventsTest.php @@ -0,0 +1,90 @@ + 'Config events', + 'description' => 'Tests events fired on configuration objects.', + 'group' => 'Configuration', + ); + } + + /** + * Tests configuration events. + */ + function testConfigEvents() { + + $name = 'config_events_test.test'; + + $config = new Config($name, \Drupal::service('config.storage'), \Drupal::service('event_dispatcher'), \Drupal::service('config.typed')); + $config->set('key', 'initial'); + \Drupal::state()->get('config_events_test.event', FALSE); + $this->assertIdentical(\Drupal::state()->get('config_events_test.event', array()), array(), 'No events fired by creating a new configuration object'); + $config->save(); + + $event = \Drupal::state()->get('config_events_test.event', array()); + $this->assertIdentical($event['event_name'], ConfigEvents::SAVE); + $this->assertIdentical($event['current_config_data'], array('key' => 'initial')); + $this->assertIdentical($event['raw_config_data'], array('key' => 'initial')); + $this->assertIdentical($event['original_config_data'], array()); + + $config->set('key', 'updated')->save(); + $event = \Drupal::state()->get('config_events_test.event', array()); + $this->assertIdentical($event['event_name'], ConfigEvents::SAVE); + $this->assertIdentical($event['current_config_data'], array('key' => 'updated')); + $this->assertIdentical($event['raw_config_data'], array('key' => 'updated')); + $this->assertIdentical($event['original_config_data'], array('key' => 'initial')); + + $config->delete(); + $event = \Drupal::state()->get('config_events_test.event', array()); + $this->assertIdentical($event['event_name'], ConfigEvents::DELETE); + $this->assertIdentical($event['current_config_data'], array()); + $this->assertIdentical($event['raw_config_data'], array()); + $this->assertIdentical($event['original_config_data'], array('key' => 'updated')); + } + + /** + * Tests configuration rename event that is fired from the ConfigFactory. + */ + function testConfigRenameEvent() { + $name = 'config_events_test.test'; + $new_name = 'config_events_test.test_rename'; + + $config = \Drupal::config($name); + $config->set('key', 'initial')->save(); + $event = \Drupal::state()->get('config_events_test.event', array()); + $this->assertIdentical($event['event_name'], ConfigEvents::SAVE); + + \Drupal::configFactory()->rename($name, $new_name); + $event = \Drupal::state()->get('config_events_test.event', array()); + $this->assertIdentical($event['event_name'], ConfigEvents::RENAME); + $this->assertIdentical($event['current_config_data'], array('key' => 'initial')); + $this->assertIdentical($event['raw_config_data'], array('key' => 'initial')); + $this->assertIdentical($event['original_config_data'], array('key' => 'initial')); + } + + +} diff --git a/core/modules/config/tests/config_events_test/config_events_test.info.yml b/core/modules/config/tests/config_events_test/config_events_test.info.yml new file mode 100644 index 0000000..6cb7504 --- /dev/null +++ b/core/modules/config/tests/config_events_test/config_events_test.info.yml @@ -0,0 +1,6 @@ +name: 'Configuration events test' +type: module +package: Testing +version: VERSION +core: 8.x +hidden: true diff --git a/core/modules/config/tests/config_events_test/config_events_test.module b/core/modules/config/tests/config_events_test/config_events_test.module new file mode 100644 index 0000000..aa52475 --- /dev/null +++ b/core/modules/config/tests/config_events_test/config_events_test.module @@ -0,0 +1,6 @@ +state = $state; + } + + /** + * Reacts to config event. + * + * @param \Drupal\Core\Config\ConfigEvent $event + * The configuration event. + */ + public function configEventRecorder(ConfigEvent $event) { + $config = $event->getConfig(); + $this->state->set('config_events_test.event', array( + 'event_name' => $event->getName(), + 'current_config_data' => $config->get(), + 'original_config_data' => $config->getOriginal(), + 'raw_config_data' => $config->getRawData() + )); + } + + /** + * {@inheritdoc} + */ + static function getSubscribedEvents() { + $events[ConfigEvents::SAVE][] = array('configEventRecorder'); + $events[ConfigEvents::DELETE][] = array('configEventRecorder'); + $events[ConfigEvents::RENAME][] = array('configEventRecorder'); + return $events; + } +} \ No newline at end of file diff --git a/core/modules/config/tests/config_override/lib/Drupal/config_override/EventSubscriber/ConfigModuleLowPriorityOverrideSubscriber.php b/core/modules/config/tests/config_override/lib/Drupal/config_override/EventSubscriber/ConfigModuleLowPriorityOverrideSubscriber.php index 1e1b5ef..fd7e26c 100644 --- a/core/modules/config/tests/config_override/lib/Drupal/config_override/EventSubscriber/ConfigModuleLowPriorityOverrideSubscriber.php +++ b/core/modules/config/tests/config_override/lib/Drupal/config_override/EventSubscriber/ConfigModuleLowPriorityOverrideSubscriber.php @@ -7,6 +7,7 @@ namespace Drupal\config_override\EventSubscriber; +use Drupal\Core\Config\ConfigEvents; use Drupal\Core\Config\ConfigModuleOverridesEvent; use Symfony\Component\EventDispatcher\EventSubscriberInterface; @@ -36,7 +37,7 @@ public function onConfigModuleOverride(ConfigModuleOverridesEvent $event) { * An array of event listener definitions. */ static function getSubscribedEvents() { - $events['config.module.overrides'][] = array('onConfigModuleOverride', 35); + $events[ConfigEvents::MODULE_OVERRIDES][] = array('onConfigModuleOverride', 35); return $events; } } diff --git a/core/modules/config/tests/config_override/lib/Drupal/config_override/EventSubscriber/ConfigModuleOverrideSubscriber.php b/core/modules/config/tests/config_override/lib/Drupal/config_override/EventSubscriber/ConfigModuleOverrideSubscriber.php index 54f0f64..e168111 100644 --- a/core/modules/config/tests/config_override/lib/Drupal/config_override/EventSubscriber/ConfigModuleOverrideSubscriber.php +++ b/core/modules/config/tests/config_override/lib/Drupal/config_override/EventSubscriber/ConfigModuleOverrideSubscriber.php @@ -7,6 +7,7 @@ namespace Drupal\config_override\EventSubscriber; +use Drupal\Core\Config\ConfigEvents; use Drupal\Core\Config\ConfigModuleOverridesEvent; use Symfony\Component\EventDispatcher\EventSubscriberInterface; @@ -34,7 +35,7 @@ public function onConfigModuleOverride(ConfigModuleOverridesEvent $event) { * An array of event listener definitions. */ static function getSubscribedEvents() { - $events['config.module.overrides'][] = array('onConfigModuleOverride', 40); + $events[ConfigEvents::MODULE_OVERRIDES][] = array('onConfigModuleOverride', 40); return $events; } }