Commit 1c179cb7 authored by bircher's avatar bircher
Browse files

Issue #3117135 by claudiu.cristea, mpp: TypeError: Argument 1 passed to...

Issue #3117135 by claudiu.cristea, mpp: TypeError: Argument 1 passed to NestedArray::unsetValue() must be of the type array, null given
parent 498063a9
......@@ -106,7 +106,7 @@ class ConfigIgnoreEventSubscriber implements EventSubscriberInterface {
* The active storage on import. The sync storage on export.
*/
protected function transformStorage(StorageInterface $transformation_storage, StorageInterface $destination_storage) {
$ignored_configs = $this->getIgnoredConfigs();
$ignored_configs = $this->getIgnoredConfigs($transformation_storage);
$collection_names = $transformation_storage->getAllCollectionNames();
array_unshift($collection_names, StorageInterface::DEFAULT_COLLECTION);
......@@ -147,9 +147,9 @@ class ConfigIgnoreEventSubscriber implements EventSubscriberInterface {
else {
$source_data = $transformation_storage->read($config_name);
foreach ($keys as $key) {
NestedArray::unsetValue($import_data, $key);
NestedArray::unsetValue($source_data, $key);
}
$transformation_storage->write($config_name, $import_data);
$transformation_storage->write($config_name, $source_data);
}
}
}
......@@ -159,6 +159,9 @@ class ConfigIgnoreEventSubscriber implements EventSubscriberInterface {
/**
* Returns the list of all ignored configs by expanding the wildcards.
*
* @param \Drupal\Core\Config\StorageInterface $transformation_storage
* The transformation config storage.
*
* @return array
* An associative array keyed by config name and having the values either
* NULL, if the whole config is ignored, or an array of keys to be ignored.
......@@ -173,7 +176,7 @@ class ConfigIgnoreEventSubscriber implements EventSubscriberInterface {
* ]
* @endcode
*/
protected function getIgnoredConfigs() {
protected function getIgnoredConfigs(StorageInterface $transformation_storage) {
/** @var string[] $ignored_configs_patterns */
$ignored_configs_patterns = $this->configFactory->get('config_ignore.settings')->get('ignored_config_entities');
$this->moduleHandler->invokeAll('config_ignore_settings_alter', [&$ignored_configs_patterns]);
......@@ -191,7 +194,7 @@ class ConfigIgnoreEventSubscriber implements EventSubscriberInterface {
}
$ignored_configs = [];
foreach ($this->configFactory->listAll() as $config_name) {
foreach ($transformation_storage->listAll() as $config_name) {
foreach ($ignored_configs_patterns as $ignored_config_pattern) {
if (strpos($ignored_config_pattern, ':') !== FALSE) {
// Some patterns are defining also a key.
......
......@@ -41,8 +41,9 @@ class ConfigWithTranslationTest extends BrowserTestBase {
ConfigurableLanguage::createFromLangcode('ro')->save();
// Add a translation to user.role.anonymous.
// Add a translation to user.role.anonymous and user.role.authenticated.
$this->translateConfig('user.role.anonymous', 'label', 'Utilizator anonim', 'ro');
$this->translateConfig('user.role.authenticated', 'label', 'Utilizator autentificat', 'ro');
// Export the default configuration.
$this->drush('config:export', [], ['yes' => NULL]);
......@@ -51,9 +52,17 @@ class ConfigWithTranslationTest extends BrowserTestBase {
$this->assertExportedValue('user.settings', 'anonymous', 'Anonymous');
$this->assertExportedValue('user.role.anonymous', 'label', 'Anonymous user');
$this->assertExportedValue('user.role.anonymous', 'label', 'Utilizator anonim', 'ro');
$this->assertExportedValue('user.role.authenticated', 'label', 'Authenticated user');
$this->assertExportedValue('user.role.authenticated', 'weight', 1);
$this->assertExportedValue('user.role.authenticated', 'is_admin', FALSE);
$this->assertExportedValue('user.role.authenticated', 'label', 'Utilizator autentificat', 'ro');
// Ignore user.role.anonymous.
$this->config('config_ignore.settings')->set('ignored_config_entities', ['user.role.anonymous'])->save();
// Ignore user.role.anonymous and two keys from user.role.authenticated.
$this->config('config_ignore.settings')->set('ignored_config_entities', [
'user.role.anonymous',
'user.role.authenticated:weight',
'user.role.authenticated:is_admin',
])->save();
}
/**
......@@ -63,19 +72,27 @@ class ConfigWithTranslationTest extends BrowserTestBase {
// Change configurations in the active store.
$this->config('user.settings')->set('anonymous', 'Visitor')->save();
$this->config('user.role.anonymous')->set('label', 'Visitor')->save();
// Change also the translation of user.role.anonymous.
$this->config('user.role.authenticated')
->set('label', 'Authenticated')
->set('weight', 2)
->set('is_admin', TRUE)
->save();
// Change translations of user.role.anonymous and user.role.authenticated.
$this->translateConfig('user.role.anonymous', 'label', 'Vizitator', 'ro');
$this->translateConfig('user.role.authenticated', 'label', 'Logat', 'ro');
// Get config status.
$this->drush('config:status', [], ['format' => 'json']);
$diff = (array) $this->getOutputFromJSON();
// Check that only config_ignore.settings and user.settings are shown.
$this->assertCount(2, $diff);
$this->assertCount(3, $diff);
$this->assertArrayHasKey('config_ignore.settings', $diff);
$this->assertSame(['name' => 'config_ignore.settings', 'state' => 'Different'], $diff['config_ignore.settings']);
$this->assertArrayHasKey('user.settings', $diff);
$this->assertSame(['name' => 'user.settings', 'state' => 'Different'], $diff['user.settings']);
$this->assertArrayHasKey('user.role.authenticated', $diff);
$this->assertSame(['name' => 'user.role.authenticated', 'state' => 'Different'], $diff['user.role.authenticated']);
}
/**
......@@ -85,8 +102,14 @@ class ConfigWithTranslationTest extends BrowserTestBase {
// Change configurations in the active store.
$this->config('user.settings')->set('anonymous', 'Visitor')->save();
$this->config('user.role.anonymous')->set('label', 'Visitor')->save();
// Change also the translation of user.role.anonymous.
$this->config('user.role.authenticated')
->set('label', 'Authenticated')
->set('weight', 2)
->set('is_admin', TRUE)
->save();
// Change translations of user.role.anonymous and user.role.authenticated.
$this->translateConfig('user.role.anonymous', 'label', 'Vizitator', 'ro');
$this->translateConfig('user.role.authenticated', 'label', 'Logat', 'ro');
// Export changes.
$this->drush('config:export', [], ['yes' => NULL]);
......@@ -97,17 +120,51 @@ class ConfigWithTranslationTest extends BrowserTestBase {
$this->assertExportedValue('user.role.anonymous', 'label', 'Anonymous user');
// Check that the translated version was not overridden.
$this->assertExportedValue('user.role.anonymous', 'label', 'Utilizator anonim', 'ro');
// Check that user.role.authenticated changes were exported.
$this->assertExportedValue('user.role.authenticated', 'label', 'Authenticated');
$this->assertExportedValue('user.role.authenticated', 'weight', 1);
$this->assertExportedValue('user.role.authenticated', 'is_admin', FALSE);
// Check that the translated version has been exported too.
$this->assertExportedValue('user.role.authenticated', 'label', 'Logat', 'ro');
// Delete user.role.authenticated from sync storage in order to test again
// when the destination is missed.
$sync_storage = $this->getSyncStorage();
$sync_storage->delete('user.role.authenticated');
// Re-export changes.
$this->drush('config:export', [], ['yes' => NULL]);
$data = $sync_storage->read('user.role.authenticated');
// Check that weight & is_admin keys were ignored on the new created config.
$this->assertArrayNotHasKey('weight', $data);
$this->assertArrayNotHasKey('is_admin', $data);
}
/**
* Tests config import.
*/
public function testConfigImport() {
// Add the config_ignore.settings changes in the sync store. Remember that
// the ignore patterns were added only in the active store, in ::setUp(),
// but were never exported in sync. Otherwise the values will be reverted,
// later, in the first config import.
// @see self::setUp()
$this->setConfigSyncValue('config_ignore.settings', 'ignored_config_entities', [
'user.role.anonymous',
'user.role.authenticated:weight',
'user.role.authenticated:is_admin',
]);
// Change configurations in the sync store.
$this->setConfigSyncValue('user.settings', 'anonymous', 'Visitor');
$this->setConfigSyncValue('user.role.anonymous', 'label', 'Visitor');
// Change also the translation of user.role.anonymous.
$this->setConfigSyncValue('user.role.authenticated', 'label', 'Authenticated');
$this->setConfigSyncValue('user.role.authenticated', 'weight', 2);
$this->setConfigSyncValue('user.role.authenticated', 'is_admin', TRUE);
// Change translations of user.role.anonymous and user.role.authenticated.
$this->setConfigSyncValue('user.role.anonymous', 'label', 'Vizitator', 'ro');
$this->setConfigSyncValue('user.role.authenticated', 'label', 'Logat', 'ro');
// Check that user.settings was changed in the sync store.
$this->assertExportedValue('user.settings', 'anonymous', 'Visitor');
......@@ -115,21 +172,47 @@ class ConfigWithTranslationTest extends BrowserTestBase {
$this->assertExportedValue('user.role.anonymous', 'label', 'Visitor');
// Check that the translated override was changed in the sync store.
$this->assertExportedValue('user.role.anonymous', 'label', 'Vizitator', 'ro');
$this->assertExportedValue('user.role.authenticated', 'label', 'Authenticated');
$this->assertExportedValue('user.role.authenticated', 'weight', 2);
$this->assertExportedValue('user.role.authenticated', 'is_admin', TRUE);
// Import changes.
$this->drush('config:import', [], ['yes' => NULL]);
// As the tests are running in the same request we manually clear the static
// cache of the config objects.
\Drupal::configFactory()->reset();
// Check that user.settings has been overridden by import.
$this->assertSame('Visitor', $this->config('user.settings')->get('anonymous'));
// Check that user.role.anonymous has been preserved.
$this->assertSame('Anonymous user', $this->config('user.role.anonymous')->get('label'));
// Check that user.role.authenticated has been overridden by import.
$this->assertSame('Authenticated', $this->config('user.role.authenticated')->get('label'));
$this->assertEquals(1, $this->config('user.role.authenticated')->get('weight'));
$this->assertFalse($this->config('user.role.authenticated')->get('is_admin'));
// Check that the user.role.anonymous translation has been also preserved.
$language_manager = \Drupal::languageManager();
$original_language = $language_manager->getConfigOverrideLanguage();
/** @var \Drupal\language\Config\LanguageConfigOverride $translated */
$translated = $language_manager->getLanguageConfigOverride('ro', 'user.role.anonymous');
$this->assertSame('Utilizator anonim', $translated->get('label'));
$translated = $language_manager->getLanguageConfigOverride('ro', 'user.role.authenticated');
$this->assertSame('Logat', $translated->get('label'));
$language_manager->setConfigOverrideLanguage($original_language);
/** @var \Drupal\Core\Config\StorageInterface $active_storage */
$active_storage = \Drupal::service('config.storage');
// Remove the config in order to test again when the destination is missed.
$active_storage->delete('user.role.authenticated');
// Re-import changes.
$this->drush('config:import', [], ['yes' => NULL]);
\Drupal::configFactory()->reset('user.role.authenticated');
$this->assertSame('Authenticated', $this->config('user.role.authenticated')->get('label'));
$this->assertEquals(1, $this->config('user.role.authenticated')->get('weight'));
$this->assertFalse((bool) $this->config('user.role.authenticated')->get('is_admin'));
}
/**
......@@ -205,12 +288,13 @@ class ConfigWithTranslationTest extends BrowserTestBase {
* Returns the config sync storage.
*
* @param string|null $langcode
* The language collection language code or NULL for teh default collection.
* (optional) The language collection language code or NULL for the default
* collection.
*
* @return \Drupal\Core\Config\StorageInterface
* The config sync storage.
*/
protected function getSyncStorage($langcode) {
protected function getSyncStorage($langcode = NULL) {
$sync_storage = \Drupal::service('config.storage.sync');
if ($langcode) {
$sync_storage = $sync_storage->createCollection("language.{$langcode}");
......
......@@ -162,7 +162,9 @@ class ConfigIgnorePatternResolverTest extends UnitTestCase {
$configFactory = $this->prophesize(ConfigFactoryInterface::class);
$configFactory->get('config_ignore.settings')->willReturn($configIgnoreSettings->reveal());
$configFactory->listAll()->willReturn($all_configs);
$transformation_storage = $this->prophesize(StorageInterface::class);
$transformation_storage->listAll()->willReturn($all_configs);
$subscriber = new ConfigIgnoreEventSubscriber(
$configFactory->reveal(),
......@@ -176,7 +178,7 @@ class ConfigIgnorePatternResolverTest extends UnitTestCase {
$getIgnoredConfigsMethod = $class->getMethod('getIgnoredConfigs');
$getIgnoredConfigsMethod->setAccessible(TRUE);
return $getIgnoredConfigsMethod->invokeArgs($subscriber, []);
return $getIgnoredConfigsMethod->invokeArgs($subscriber, [$transformation_storage->reveal()]);
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment