diff --git a/core/config/schema/core.data_types.schema.yml b/core/config/schema/core.data_types.schema.yml index f1f9563..41332e3 100644 --- a/core/config/schema/core.data_types.schema.yml +++ b/core/config/schema/core.data_types.schema.yml @@ -273,7 +273,7 @@ config_entity: type: sequence label: 'Third party settings' sequence: - - type: '[%parent.%parent_type].third_party.[%key]' + - type: '[%parent.%parent.%type].third_party.[%key]' block_settings: type: mapping diff --git a/core/lib/Drupal/Core/Config/ConfigManager.php b/core/lib/Drupal/Core/Config/ConfigManager.php index 827f9ef..7f4a534 100644 --- a/core/lib/Drupal/Core/Config/ConfigManager.php +++ b/core/lib/Drupal/Core/Config/ConfigManager.php @@ -220,7 +220,7 @@ public function uninstall($type, $name) { if (isset($entity_dependencies[$type]) && in_array($name, $entity_dependencies[$type])) { $affected_dependencies[$type] = array($name); } - // Inform the entity. + // Inform the entity and, if the entity is changed, re-save it. if ($entity->onDependencyRemoval($affected_dependencies)) { $entity->save(); } diff --git a/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php b/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php index 0f21a02..9c8a5e2 100644 --- a/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php +++ b/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php @@ -30,8 +30,6 @@ addDependency as addDependencyTrait; } - use ThirdPartySettingsTrait; - /** * The original ID of the configuration entity. * @@ -90,6 +88,15 @@ protected $langcode = LanguageInterface::LANGCODE_NOT_SPECIFIED; /** + * Third party entity settings. + * + * An array of key/value pairs keyed by provider. + * + * @var array + */ + protected $third_party_settings = array(); + + /** * Overrides Entity::__construct(). */ public function __construct(array $values, $entity_type) { @@ -464,4 +471,51 @@ protected static function invalidateTagsOnDelete(EntityTypeInterface $entity_typ Cache::invalidateTags($entity_type->getListCacheTags()); } + /** + * {@inheritdoc} + */ + public function setThirdPartySetting($module, $key, $value) { + $this->third_party_settings[$module][$key] = $value; + return $this; + } + + /** + * {@inheritdoc} + */ + public function getThirdPartySetting($module, $key, $default = NULL) { + if (isset($this->third_party_settings[$module][$key])) { + return $this->third_party_settings[$module][$key]; + } + else { + return $default; + } + } + + /** + * {@inheritdoc} + */ + public function getThirdPartySettings($module) { + return isset($this->third_party_settings[$module]) ? $this->third_party_settings[$module] : array(); + } + + /** + * {@inheritdoc} + */ + public function unsetThirdPartySetting($module, $key) { + unset($this->third_party_settings[$module][$key]); + // If the third party is no longer storing any information, completely + // remove the array holding the settings for this module. + if (empty($this->third_party_settings[$module])) { + unset($this->third_party_settings[$module]); + } + return $this; + } + + /** + * {@inheritdoc} + */ + public function getThirdPartyProviders() { + return array_keys($this->third_party_settings); + } + } diff --git a/core/lib/Drupal/Core/Config/Entity/ConfigEntityInterface.php b/core/lib/Drupal/Core/Config/Entity/ConfigEntityInterface.php index 2a59b39..22f15b1 100644 --- a/core/lib/Drupal/Core/Config/Entity/ConfigEntityInterface.php +++ b/core/lib/Drupal/Core/Config/Entity/ConfigEntityInterface.php @@ -171,7 +171,8 @@ public function calculateDependencies(); * Dependency types are, for example, entity, module and theme. * * @return bool - * TRUE if the entity has changed, FALSE if not. + * TRUE if the entity has changed, FALSE if not. If this method returns TRUE + * then the entity needs to be re-saved for the changes to take effect. * * @see \Drupal\Core\Config\Entity\ConfigDependencyManager * @see \Drupal\Core\Config\ConfigManager::uninstall() diff --git a/core/lib/Drupal/Core/Config/Entity/ThirdPartySettingsTrait.php b/core/lib/Drupal/Core/Config/Entity/ThirdPartySettingsTrait.php deleted file mode 100644 index cc12885..0000000 --- a/core/lib/Drupal/Core/Config/Entity/ThirdPartySettingsTrait.php +++ /dev/null @@ -1,114 +0,0 @@ -third_party_settings[$module][$key] = $value; - return $this; - } - - /** - * Gets the value of a third-party setting. - * - * @param string $module - * The module providing the third-party setting. - * @param string $key - * The setting name. - * @param mixed $default - * The default value - * - * @return mixed - * The value. - */ - public function getThirdPartySetting($module, $key, $default = NULL) { - if (isset($this->third_party_settings[$module][$key])) { - return $this->third_party_settings[$module][$key]; - } - else { - return $default; - } - } - - /** - * Gets all third-party settings of a given module. - * - * @param string $module - * The module providing the third-party settings. - * - * @return array - * An array of key-value pairs. - */ - public function getThirdPartySettings($module) { - return isset($this->third_party_settings[$module]) ? $this->third_party_settings[$module] : array(); - } - - /** - * Unsets a third-party setting. - * - * @param string $module - * The module providing the third-party setting. - * @param string $key - * The setting name. - * - * @return mixed - * The value. - */ - public function unsetThirdPartySetting($module, $key) { - unset($this->third_party_settings[$module][$key]); - // If the third party is no longer storing any information, completely - // remove the array holding the settings for this module. - if (empty($this->third_party_settings[$module])) { - unset($this->third_party_settings[$module]); - } - return $this; - } - - /** - * Gets the list of third parties that store information. - * - * @return array - * The list of third parties. - */ - public function getThirdPartyProviders() { - return array_keys($this->third_party_settings); - } - -} diff --git a/core/lib/Drupal/Core/Config/TypedConfigManager.php b/core/lib/Drupal/Core/Config/TypedConfigManager.php index f4c39f6..42bb8cb 100644 --- a/core/lib/Drupal/Core/Config/TypedConfigManager.php +++ b/core/lib/Drupal/Core/Config/TypedConfigManager.php @@ -238,8 +238,8 @@ protected function replaceName($name, $data) { * their value or some of these special strings: * - '%key', will be replaced by the element's key. * - '%parent', to reference the parent element. - * - '%parent_type', to reference the schema definition type of the parent. - * Can only be used in combination with %parent. + * - '%type', to reference the schema definition type. Can only be used in + * combination with %parent. * * There may be nested configuration keys separated by dots or more complex * patterns like '%parent.name' which references the 'name' value of the @@ -249,8 +249,8 @@ protected function replaceName($name, $data) { * - 'name.subkey', indicates a nested value of the current element. * - '%parent.name', will be replaced by the 'name' value of the parent. * - '%parent.%key', will be replaced by the parent element's key. - * - '%parent_type', will be replaced by the schema type of the parent. - * - '%parent.%parent_type', will be replaced by the schema type of the + * - '%parent.%type', will be replaced by the schema type of the parent. + * - '%parent.%parent.%type', will be replaced by the schema type of the * parent's parent. * * @param string $value @@ -265,13 +265,6 @@ protected function replaceVariable($value, $data) { $parts = explode('.', $value); // Process each value part, one at a time. while ($name = array_shift($parts)) { - if ($name == '%parent_type') { - if ($data['%parent']) { - /** @var \Drupal\Core\Config\Schema\ArrayElement $parent */ - $parent = $data['%parent']; - return $parent->getDataDefinition()->getDataType(); - } - } if (!is_array($data) || !isset($data[$name])) { // Key not found, return original value return $value; @@ -283,9 +276,11 @@ protected function replaceVariable($value, $data) { else { // Get nested value and continue processing. if ($name == '%parent') { + /** @var \Drupal\Core\Config\Schema\ArrayElement $parent */ // Switch replacement values with values from the parent. $parent = $data['%parent']; $data = $parent->getValue(); + $data['%type'] = $parent->getDataDefinition()->getDataType(); // The special %parent and %key values now need to point one level up. if ($new_parent = $parent->getParent()) { $data['%parent'] = $new_parent; diff --git a/core/modules/config/src/Tests/ConfigSchemaTest.php b/core/modules/config/src/Tests/ConfigSchemaTest.php index b999daf..ffacdde 100644 --- a/core/modules/config/src/Tests/ConfigSchemaTest.php +++ b/core/modules/config/src/Tests/ConfigSchemaTest.php @@ -171,7 +171,7 @@ function testSchemaMapping() { $expected['mapping']['effects']['sequence'][0]['mapping']['uuid']['type'] = 'string'; $expected['mapping']['third_party_settings']['type'] = 'sequence'; $expected['mapping']['third_party_settings']['label'] = 'Third party settings'; - $expected['mapping']['third_party_settings']['sequence'][0]['type'] = '[%parent.%parent_type].third_party.[%key]'; + $expected['mapping']['third_party_settings']['sequence'][0]['type'] = '[%parent.%parent.%type].third_party.[%key]'; $expected['type'] = 'image.style.*'; $this->assertEqual($definition, $expected); diff --git a/core/modules/node/src/Tests/NodeTranslationUITest.php b/core/modules/node/src/Tests/NodeTranslationUITest.php index 60d5c33..01185b5 100644 --- a/core/modules/node/src/Tests/NodeTranslationUITest.php +++ b/core/modules/node/src/Tests/NodeTranslationUITest.php @@ -11,6 +11,7 @@ use Drupal\content_translation\Tests\ContentTranslationUITest; use Drupal\Core\Language\LanguageInterface; use Drupal\Core\Url; +use Drupal\node\Entity\Node; /** * Tests the Node Translation UI. @@ -49,6 +50,14 @@ protected function setUp() { } /** + * Tests the basic translation UI. + */ + function testTranslationUI() { + parent::testTranslationUI(); + $this->doUninstallTest(); + } + + /** * Overrides \Drupal\content_translation\Tests\ContentTranslationUITest::getTranslatorPermission(). */ protected function getTranslatorPermissions() { @@ -348,4 +357,20 @@ protected function getFormSubmitSuffix(EntityInterface $entity, $langcode) { } return ''; } + + /** + * Tests uninstalling content_translation. + */ + protected function doUninstallTest() { + // Delete all the nodes so there is no data. + $nodes = Node::loadMultiple(); + foreach ($nodes as $node) { + $node->delete(); + } + $language_count = count(\Drupal::configFactory()->listAll('language.content_settings.')); + \Drupal::service('module_installer')->uninstall(['content_translation']); + $this->rebuildContainer(); + $this->assertEqual($language_count, count(\Drupal::configFactory()->listAll('language.content_settings.')), 'Languages have been fixed rather than deleted during content_translation uninstall.'); + } + } diff --git a/core/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityBaseUnitTest.php b/core/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityBaseUnitTest.php index c3a04bf..9456d33 100644 --- a/core/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityBaseUnitTest.php +++ b/core/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityBaseUnitTest.php @@ -291,6 +291,7 @@ public function providerCalculateDependenciesWithPluginCollections() { /** * @covers ::calculateDependencies + * @covers ::onDependencyRemoval */ public function testCalculateDependenciesWithThirdPartySettings() { $this->entity = $this->getMockForAbstractClass('\Drupal\Core\Config\Entity\ConfigEntityBase', array(array(), $this->entityTypeId)); @@ -472,4 +473,38 @@ public function testToArrayFallback() { $this->entity->toArray(); } + /** + * @covers ::getThirdPartySetting + * @covers ::setThirdPartySetting + * @covers ::getThirdPartySettings + * @covers ::unsetThirdPartySetting + * @covers ::getThirdPartyProviders + */ + public function testThirdPartySettings() { + $key = 'test'; + $third_party = 'test_provider'; + $value = $this->getRandomGenerator()->string(); + + // Test getThirdPartySetting() with no settings. + $this->assertEquals($value, $this->entity->getThirdPartySetting($third_party, $key, $value)); + $this->assertNull($this->entity->getThirdPartySetting($third_party, $key)); + + // Test setThirdPartySetting(). + $this->entity->setThirdPartySetting($third_party, $key, $value); + $this->assertEquals($value, $this->entity->getThirdPartySetting($third_party, $key)); + $this->assertEquals($value, $this->entity->getThirdPartySetting($third_party, $key, $this->randomGenerator->string())); + + // Test getThirdPartySettings(). + $this->entity->setThirdPartySetting($third_party, 'test2', 'value2'); + $this->assertEquals(array($key => $value, 'test2' => 'value2'), $this->entity->getThirdPartySettings($third_party)); + + // Test getThirdPartyProviders(). + $this->entity->setThirdPartySetting('test_provider2', $key, $value); + $this->assertEquals(array($third_party, 'test_provider2'), $this->entity->getThirdPartyProviders()); + + // Test unsetThirdPartyProviders(). + $this->entity->unsetThirdPartySetting('test_provider2', $key); + $this->assertEquals(array($third_party), $this->entity->getThirdPartyProviders()); + } + } diff --git a/core/tests/Drupal/Tests/Core/Config/Entity/ThirdPartySettingsTraitTest.php b/core/tests/Drupal/Tests/Core/Config/Entity/ThirdPartySettingsTraitTest.php deleted file mode 100644 index bcbe12b..0000000 --- a/core/tests/Drupal/Tests/Core/Config/Entity/ThirdPartySettingsTraitTest.php +++ /dev/null @@ -1,60 +0,0 @@ -getRandomGenerator()->string(); - - $trait_object = new TestThirdPartySettingsTrait(); - - // Test getThirdPartySetting() with no settings. - $this->assertEquals($value, $trait_object->getThirdPartySetting($third_party, $key, $value)); - $this->assertNull($trait_object->getThirdPartySetting($third_party, $key)); - - // Test setThirdPartySetting(). - $trait_object->setThirdPartySetting($third_party, $key, $value); - $this->assertEquals($value, $trait_object->getThirdPartySetting($third_party, $key)); - $this->assertEquals($value, $trait_object->getThirdPartySetting($third_party, $key, $this->randomGenerator->string())); - - // Test getThirdPartySettings(). - $trait_object->setThirdPartySetting($third_party, 'test2', 'value2'); - $this->assertEquals(array($key => $value, 'test2' => 'value2'), $trait_object->getThirdPartySettings($third_party)); - - // Test getThirdPartyProviders(). - $trait_object->setThirdPartySetting('test_provider2', $key, $value); - $this->assertEquals(array($third_party, 'test_provider2'), $trait_object->getThirdPartyProviders()); - - // Test unsetThirdPartyProviders(). - $trait_object->unsetThirdPartySetting('test_provider2', $key); - $this->assertEquals(array($third_party), $trait_object->getThirdPartyProviders()); - } -} - -class TestThirdPartySettingsTrait { - - use ThirdPartySettingsTrait; - -}