diff --git a/core/config/schema/core.data_types.schema.yml b/core/config/schema/core.data_types.schema.yml index 0c9ad70..41332e3 100644 --- a/core/config/schema/core.data_types.schema.yml +++ b/core/config/schema/core.data_types.schema.yml @@ -269,6 +269,11 @@ config_entity: dependencies: type: config_dependencies label: 'Dependencies' + third_party_settings: + type: sequence + label: 'Third party settings' + sequence: + - type: '[%parent.%parent.%type].third_party.[%key]' block_settings: type: mapping @@ -393,11 +398,6 @@ field_config_base: label: 'Default value callback' settings: type: field.field_settings.[%parent.field_type] - third_party_settings: - type: sequence - label: 'Third party settings' - sequence: - - type: field_config.third_party.[%key] field_type: type: string label: 'Field type' diff --git a/core/config/schema/core.entity.schema.yml b/core/config/schema/core.entity.schema.yml index ee3d5d7..de9530d 100644 --- a/core/config/schema/core.entity.schema.yml +++ b/core/config/schema/core.entity.schema.yml @@ -93,11 +93,6 @@ core.entity_view_display.*.*.*: sequence: - type: boolean label: 'Value' - third_party_settings: - type: sequence - label: 'Third party settings' - sequence: - - type: entity_view_display.third_party.[%key] # Overview configuration information for form mode displays. core.entity_form_display.*.*.*: @@ -146,11 +141,6 @@ core.entity_form_display.*.*.*: sequence: - type: boolean label: 'Component' - third_party_settings: - type: sequence - label: 'Third party settings' - sequence: - - type: entity_form_display.third_party.[%key] # Default schema for entity display field with undefined type. field.formatter.settings.*: diff --git a/core/lib/Drupal/Core/Config/ConfigManager.php b/core/lib/Drupal/Core/Config/ConfigManager.php index e3fcaf8..7f4a534 100644 --- a/core/lib/Drupal/Core/Config/ConfigManager.php +++ b/core/lib/Drupal/Core/Config/ConfigManager.php @@ -220,8 +220,10 @@ public function uninstall($type, $name) { if (isset($entity_dependencies[$type]) && in_array($name, $entity_dependencies[$type])) { $affected_dependencies[$type] = array($name); } - // Inform the entity. - $entity->onDependencyRemoval($affected_dependencies); + // Inform the entity and, if the entity is changed, re-save it. + if ($entity->onDependencyRemoval($affected_dependencies)) { + $entity->save(); + } } // Recalculate the dependencies, some config entities may have fixed their diff --git a/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php b/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php index 12a4543..9c8a5e2 100644 --- a/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php +++ b/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php @@ -7,12 +7,12 @@ namespace Drupal\Core\Config\Entity; -use Drupal\Component\Plugin\ConfigurablePluginInterface; use Drupal\Component\Utility\String; use Drupal\Core\Cache\Cache; use Drupal\Core\Config\Schema\SchemaIncompleteException; use Drupal\Core\Entity\Entity; use Drupal\Core\Config\ConfigDuplicateUUIDException; +use Drupal\Core\Config\Entity\ThirdPartySettingsTrait; use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Entity\EntityWithPluginCollectionInterface; @@ -24,7 +24,7 @@ * * @ingroup entity_api */ -abstract class ConfigEntityBase extends Entity implements ConfigEntityInterface { +abstract class ConfigEntityBase extends Entity implements ConfigEntityInterface, ThirdPartySettingsInterface { use PluginDependencyTrait { addDependency as addDependencyTrait; @@ -88,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) { @@ -259,6 +268,9 @@ public function toArray() { $properties[$name] = $this->get($name); } } + if (empty($this->third_party_settings)) { + unset($properties['third_party_settings']); + } return $properties; } @@ -430,6 +442,13 @@ public function getConfigTarget() { * {@inheritdoc} */ public function onDependencyRemoval(array $dependencies) { + $changed = FALSE; + if (!empty($this->third_party_settings)) { + $old_count = count($this->third_party_settings); + $this->third_party_settings = array_diff_key($this->third_party_settings, array_flip($dependencies['module'])); + $changed = $old_count != count($this->third_party_settings); + } + return $changed; } /** @@ -452,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 15347e3..1db3b42 100644 --- a/core/lib/Drupal/Core/Config/Entity/ConfigEntityInterface.php +++ b/core/lib/Drupal/Core/Config/Entity/ConfigEntityInterface.php @@ -157,10 +157,13 @@ public function calculateDependencies(); * This method allows configuration entities to remove dependencies instead * of being deleted themselves. Configuration entities can use this method to * avoid being unnecessarily deleted during an extension uninstallation. - * Implementations should save the entity if dependencies have been - * successfully removed. For example, entity displays remove references to - * widgets and formatters if the plugin that supplies them depends on a - * module that is being uninstalled. + * For example, entity displays remove references to widgets and formatters if + * the plugin that supplies them depends on a module that is being + * uninstalled. + * + * If this method returns TRUE then the entity needs to be re-saved by the + * caller for the changes to take effect. Implementations should not save the + * entity. * * @todo https://www.drupal.org/node/2336727 this method is only fired during * extension uninstallation but it could be used during config entity @@ -170,6 +173,9 @@ public function calculateDependencies(); * An array of dependencies that will be deleted keyed by dependency type. * Dependency types are, for example, entity, module and theme. * + * @return bool + * TRUE if the entity has changed, FALSE if not. + * * @see \Drupal\Core\Config\Entity\ConfigDependencyManager * @see \Drupal\Core\Config\ConfigManager::uninstall() * @see \Drupal\Core\Entity\EntityDisplayBase::onDependencyRemoval() 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 a784364..42bb8cb 100644 --- a/core/lib/Drupal/Core/Config/TypedConfigManager.php +++ b/core/lib/Drupal/Core/Config/TypedConfigManager.php @@ -238,6 +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. + * - '%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 @@ -247,6 +249,9 @@ 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's parent. * * @param string $value * Variable value to be replaced. @@ -271,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/lib/Drupal/Core/Entity/EntityDisplayBase.php b/core/lib/Drupal/Core/Entity/EntityDisplayBase.php index 05c0144..90d5955 100644 --- a/core/lib/Drupal/Core/Entity/EntityDisplayBase.php +++ b/core/lib/Drupal/Core/Entity/EntityDisplayBase.php @@ -8,7 +8,6 @@ namespace Drupal\Core\Entity; use Drupal\Core\Config\Entity\ConfigEntityBase; -use Drupal\Core\Config\Entity\ThirdPartySettingsTrait; use Drupal\Core\Field\FieldDefinitionInterface; use Drupal\Core\Entity\Display\EntityDisplayInterface; use Drupal\field\Entity\FieldConfig; @@ -20,8 +19,6 @@ */ abstract class EntityDisplayBase extends ConfigEntityBase implements EntityDisplayInterface { - use ThirdPartySettingsTrait; - /** * The 'mode' for runtime EntityDisplay objects used to render entities with * arbitrary display options rather than a configured view mode or form mode. @@ -418,7 +415,7 @@ private function fieldHasDisplayOptions(FieldDefinitionInterface $definition) { * {@inheritdoc} */ public function onDependencyRemoval(array $dependencies) { - $changed = FALSE; + $changed = parent::onDependencyRemoval($dependencies); foreach ($dependencies['config'] as $entity) { if ($entity instanceof FieldConfigInterface) { // Remove components for fields that are being deleted. @@ -437,9 +434,7 @@ public function onDependencyRemoval(array $dependencies) { } } } - if ($changed) { - $this->save(); - } + return $changed; } /** diff --git a/core/lib/Drupal/Core/Field/FieldConfigBase.php b/core/lib/Drupal/Core/Field/FieldConfigBase.php index af1c399..7388b4b 100644 --- a/core/lib/Drupal/Core/Field/FieldConfigBase.php +++ b/core/lib/Drupal/Core/Field/FieldConfigBase.php @@ -9,7 +9,6 @@ use Drupal\Component\Plugin\DependentPluginInterface; use Drupal\Core\Config\Entity\ConfigEntityBase; -use Drupal\Core\Config\Entity\ThirdPartySettingsTrait; use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\Entity\FieldableEntityInterface; use Drupal\Core\Field\TypedData\FieldItemDataDefinition; @@ -20,8 +19,6 @@ */ abstract class FieldConfigBase extends ConfigEntityBase implements FieldConfigInterface { - use ThirdPartySettingsTrait; - /** * The field ID. * diff --git a/core/modules/config/src/Tests/ConfigSchemaTest.php b/core/modules/config/src/Tests/ConfigSchemaTest.php index c7a6f55..ffacdde 100644 --- a/core/modules/config/src/Tests/ConfigSchemaTest.php +++ b/core/modules/config/src/Tests/ConfigSchemaTest.php @@ -25,7 +25,7 @@ class ConfigSchemaTest extends KernelTestBase { * * @var array */ - public static $modules = array('system', 'language', 'locale', 'field', 'image', 'config_schema_test'); + public static $modules = array('system', 'language', 'locale', 'field', 'image', 'config_test', 'config_schema_test'); /** * {@inheritdoc} @@ -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'] = 'image_style.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); @@ -202,6 +202,19 @@ function testSchemaMapping() { $this->assertEqual($definition, $expected, 'Retrieved the right metadata for the first effect of image.style.medium'); + $test = \Drupal::service('config.typed')->get('config_test.dynamic.third_party')->get('third_party_settings.config_schema_test'); + $definition = $test->getDataDefinition()->toArray(); + $expected = array(); + $expected['type'] = 'config_test.dynamic.*.third_party.config_schema_test'; + $expected['label'] = 'Mapping'; + $expected['class'] = '\Drupal\Core\Config\Schema\Mapping'; + $expected['definition_class'] = '\Drupal\Core\TypedData\MapDataDefinition'; + $expected['mapping'] = [ + 'integer' => ['type' => 'integer'], + 'string' => ['type' => 'string'], + ]; + $this->assertEqual($definition, $expected, 'Retrieved the right metadata for config_test.dynamic.third_party:third_party_settings.config_schema_test'); + // More complex, several level deep test. $definition = \Drupal::service('config.typed')->getDefinition('config_schema_test.someschema.somemodule.section_one.subsection'); // This should be the schema of config_schema_test.someschema.somemodule.*.*. diff --git a/core/modules/config/tests/config_schema_test/config/install/config_test.dynamic.third_party.yml b/core/modules/config/tests/config_schema_test/config/install/config_test.dynamic.third_party.yml new file mode 100644 index 0000000..3db9b1d --- /dev/null +++ b/core/modules/config/tests/config_schema_test/config/install/config_test.dynamic.third_party.yml @@ -0,0 +1,8 @@ +id: third_party +label: Default +weight: 0 +protected_property: Default +third_party_settings: + config_schema_test: + integer: 1 + string: 'string' diff --git a/core/modules/config/tests/config_schema_test/config/schema/config_schema_test.schema.yml b/core/modules/config/tests/config_schema_test/config/schema/config_schema_test.schema.yml index cbc3c61..26dbdaf 100644 --- a/core/modules/config/tests/config_schema_test/config/schema/config_schema_test.schema.yml +++ b/core/modules/config/tests/config_schema_test/config/schema/config_schema_test.schema.yml @@ -207,3 +207,10 @@ test_with_parents.plugin_types.*: value: type: string +config_test.dynamic.*.third_party.config_schema_test: + type: mapping + mapping: + integer: + type: integer + string: + type: string diff --git a/core/modules/config/tests/config_test/src/Entity/ConfigTest.php b/core/modules/config/tests/config_test/src/Entity/ConfigTest.php index 4357597..d1c9a57 100644 --- a/core/modules/config/tests/config_test/src/Entity/ConfigTest.php +++ b/core/modules/config/tests/config_test/src/Entity/ConfigTest.php @@ -122,7 +122,7 @@ public static function postDelete(EntityStorageInterface $storage, array $entiti * {@inheritdoc} */ public function onDependencyRemoval(array $dependencies) { - $changed = FALSE; + $changed = parent::onDependencyRemoval($dependencies); $fix_deps = \Drupal::state()->get('config_test.fix_dependencies', array()); foreach ($dependencies['config'] as $entity) { if (in_array($entity->getConfigDependencyName(), $fix_deps)) { @@ -133,9 +133,7 @@ public function onDependencyRemoval(array $dependencies) { } } } - if ($changed) { - $this->save(); - } + return $changed; } /** diff --git a/core/modules/contact/config/schema/contact.schema.yml b/core/modules/contact/config/schema/contact.schema.yml index 011ae37..7ebb6f4 100644 --- a/core/modules/contact/config/schema/contact.schema.yml +++ b/core/modules/contact/config/schema/contact.schema.yml @@ -22,11 +22,6 @@ contact.form.*: weight: type: integer label: 'Weight' - third_party_settings: - type: sequence - label: 'Third party settings' - sequence: - - type: contact_form.third_party.[%key] contact.settings: type: mapping diff --git a/core/modules/contact/src/Entity/ContactForm.php b/core/modules/contact/src/Entity/ContactForm.php index d4be3de..c0cf26a 100644 --- a/core/modules/contact/src/Entity/ContactForm.php +++ b/core/modules/contact/src/Entity/ContactForm.php @@ -9,7 +9,6 @@ use Drupal\Core\Config\Entity\ConfigEntityBundleBase; use Drupal\contact\ContactFormInterface; -use Drupal\Core\Config\Entity\ThirdPartySettingsTrait; /** * Defines the contact form entity. @@ -42,8 +41,6 @@ */ class ContactForm extends ConfigEntityBundleBase implements ContactFormInterface { - use ThirdPartySettingsTrait; - /** * The form ID. * diff --git a/core/modules/contact/tests/modules/contact_storage_test/config/schema/contact_storage_test.schema.yml b/core/modules/contact/tests/modules/contact_storage_test/config/schema/contact_storage_test.schema.yml index e421214..489301e 100644 --- a/core/modules/contact/tests/modules/contact_storage_test/config/schema/contact_storage_test.schema.yml +++ b/core/modules/contact/tests/modules/contact_storage_test/config/schema/contact_storage_test.schema.yml @@ -1,6 +1,6 @@ # Schema for configuration files of the Contact Storage Test module. -contact_form.third_party.contact_storage_test: +contact.form.*.third_party.contact_storage_test: type: mapping label: 'Per-contact form storage settings' mapping: diff --git a/core/modules/content_translation/config/schema/content_translation.schema.yml b/core/modules/content_translation/config/schema/content_translation.schema.yml index 1e724d8..ddccb5b 100644 --- a/core/modules/content_translation/config/schema/content_translation.schema.yml +++ b/core/modules/content_translation/config/schema/content_translation.schema.yml @@ -1,6 +1,6 @@ # Schema for the Content Translation module. -field_config.third_party.content_translation: +field.field.*.*.*.third_party.content_translation: type: mapping label: 'Content translation field settings' mapping: @@ -11,7 +11,7 @@ field_config.third_party.content_translation: - type: string label: 'Field column for which to synchronize translations' -language.content_settings.third_party.content_translation: +language.content_settings.*.*.third_party.content_translation: type: mapping label: 'Content translation content settings' mapping: diff --git a/core/modules/filter/src/Entity/FilterFormat.php b/core/modules/filter/src/Entity/FilterFormat.php index dc4643a..6df0f97 100644 --- a/core/modules/filter/src/Entity/FilterFormat.php +++ b/core/modules/filter/src/Entity/FilterFormat.php @@ -400,7 +400,7 @@ public function removeFilter($instance_id) { * {@inheritdoc} */ public function onDependencyRemoval(array $dependencies) { - $changed = FALSE; + $changed = parent::onDependencyRemoval($dependencies); $filters = $this->filters(); foreach ($filters as $filter) { // Remove disabled filters, so that this FilterFormat config entity can @@ -410,9 +410,7 @@ public function onDependencyRemoval(array $dependencies) { $changed = TRUE; } } - if ($changed) { - $this->save(); - } + return $changed; } /** diff --git a/core/modules/image/config/schema/image.schema.yml b/core/modules/image/config/schema/image.schema.yml index 87f38f6..00268ef 100644 --- a/core/modules/image/config/schema/image.schema.yml +++ b/core/modules/image/config/schema/image.schema.yml @@ -22,11 +22,6 @@ image.style.*: type: integer uuid: type: string - third_party_settings: - type: sequence - label: 'Third party settings' - sequence: - - type: image_style.third_party.[%key] image.effect.*: type: mapping diff --git a/core/modules/image/src/Entity/ImageStyle.php b/core/modules/image/src/Entity/ImageStyle.php index 4c37751..a3c7ab5 100644 --- a/core/modules/image/src/Entity/ImageStyle.php +++ b/core/modules/image/src/Entity/ImageStyle.php @@ -9,7 +9,6 @@ use Drupal\Core\Cache\Cache; use Drupal\Core\Config\Entity\ConfigEntityBase; -use Drupal\Core\Config\Entity\ThirdPartySettingsTrait; use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\Entity\EntityWithPluginCollectionInterface; use Drupal\Core\Routing\RequestHelper; @@ -54,8 +53,6 @@ */ class ImageStyle extends ConfigEntityBase implements ImageStyleInterface, EntityWithPluginCollectionInterface { - use ThirdPartySettingsTrait; - /** * The name of the image style to use as replacement upon delete. * diff --git a/core/modules/image/tests/modules/image_module_test/config/schema/image_module_test.schema.yml b/core/modules/image/tests/modules/image_module_test/config/schema/image_module_test.schema.yml index a36719d..b0e8ebf 100644 --- a/core/modules/image/tests/modules/image_module_test/config/schema/image_module_test.schema.yml +++ b/core/modules/image/tests/modules/image_module_test/config/schema/image_module_test.schema.yml @@ -1,4 +1,4 @@ -image_style.third_party.image_module_test: +image.style.*.third_party.image_module_test: type: mapping label: 'Schema for image_module_test module additions to image_style entity' mapping: diff --git a/core/modules/language/config/schema/language.schema.yml b/core/modules/language/config/schema/language.schema.yml index d894eb6..bd03869 100644 --- a/core/modules/language/config/schema/language.schema.yml +++ b/core/modules/language/config/schema/language.schema.yml @@ -120,11 +120,6 @@ language.content_settings.*.*: language_alterable: type: boolean label: 'Allow to alter the language' - third_party_settings: - type: sequence - label: 'Third party settings' - sequence: - - type: language.content_settings.third_party.[%key] condition.plugin.language: type: condition.plugin diff --git a/core/modules/language/src/Entity/ContentLanguageSettings.php b/core/modules/language/src/Entity/ContentLanguageSettings.php index 607fb4c..19ca584 100644 --- a/core/modules/language/src/Entity/ContentLanguageSettings.php +++ b/core/modules/language/src/Entity/ContentLanguageSettings.php @@ -9,7 +9,6 @@ use Drupal\Component\Utility\String; use Drupal\Core\Config\Entity\ConfigEntityBase; -use Drupal\Core\Config\Entity\ThirdPartySettingsTrait; use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\Language\LanguageInterface; use Drupal\language\ContentLanguageSettingsException; @@ -30,8 +29,6 @@ */ class ContentLanguageSettings extends ConfigEntityBase implements ContentLanguageSettingsInterface { - use ThirdPartySettingsTrait; - /** * The id. Combination of $target_entity_type_id.$target_bundle. * 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 ed1fef8..ad096f2 100644 --- a/core/modules/menu_ui/config/schema/menu_ui.schema.yml +++ b/core/modules/menu_ui/config/schema/menu_ui.schema.yml @@ -8,7 +8,7 @@ menu_ui.settings: type: boolean label: 'Override parent selector' -node_type.third_party.menu_ui: +node.type.*.third_party.menu_ui: type: mapping label: 'Per-content type menu settings' mapping: diff --git a/core/modules/node/config/schema/node.schema.yml b/core/modules/node/config/schema/node.schema.yml index f650794..9b8931c 100644 --- a/core/modules/node/config/schema/node.schema.yml +++ b/core/modules/node/config/schema/node.schema.yml @@ -33,11 +33,6 @@ node.type.*: display_submitted: type: boolean label: 'Display setting for author and date Submitted by post information' - third_party_settings: - type: sequence - label: 'Third party settings' - sequence: - - type: node_type.third_party.[%key] # Plugin \Drupal\node\Plugin\Search\NodeSearch search.plugin.node_search: diff --git a/core/modules/node/src/Entity/NodeType.php b/core/modules/node/src/Entity/NodeType.php index 8a08d26..238ae8f 100644 --- a/core/modules/node/src/Entity/NodeType.php +++ b/core/modules/node/src/Entity/NodeType.php @@ -8,7 +8,6 @@ namespace Drupal\node\Entity; use Drupal\Core\Config\Entity\ConfigEntityBundleBase; -use Drupal\Core\Config\Entity\ThirdPartySettingsTrait; use Drupal\Core\Entity\EntityStorageInterface; use Drupal\node\NodeTypeInterface; @@ -42,7 +41,6 @@ * ) */ class NodeType extends ConfigEntityBundleBase implements NodeTypeInterface { - use ThirdPartySettingsTrait; /** * The machine name of this node type. 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/modules/system/tests/modules/entity_test/config/schema/entity_test.schema.yml b/core/modules/system/tests/modules/entity_test/config/schema/entity_test.schema.yml index 5a3ad02..d671bc4 100644 --- a/core/modules/system/tests/modules/entity_test/config/schema/entity_test.schema.yml +++ b/core/modules/system/tests/modules/entity_test/config/schema/entity_test.schema.yml @@ -1,4 +1,4 @@ -entity_view_display.third_party.entity_test: +core.entity_view_display.*.*.*.third_party.entity_test: type: mapping label: 'Schema for entity_test module additions to entity_view_display entity' mapping: diff --git a/core/modules/taxonomy/config/schema/taxonomy.schema.yml b/core/modules/taxonomy/config/schema/taxonomy.schema.yml index cf4a3a9..c79fa5f 100644 --- a/core/modules/taxonomy/config/schema/taxonomy.schema.yml +++ b/core/modules/taxonomy/config/schema/taxonomy.schema.yml @@ -33,11 +33,6 @@ taxonomy.vocabulary.*: weight: type: integer label: 'Weight' - third_party_settings: - type: sequence - label: 'Third party settings' - sequence: - - type: taxonomy.vocabulary.third_party.[%key] field.storage_settings.taxonomy_term_reference: type: base_entity_reference_field_settings diff --git a/core/modules/taxonomy/src/Entity/Vocabulary.php b/core/modules/taxonomy/src/Entity/Vocabulary.php index 4f21f8a..ae7b10f 100644 --- a/core/modules/taxonomy/src/Entity/Vocabulary.php +++ b/core/modules/taxonomy/src/Entity/Vocabulary.php @@ -8,7 +8,6 @@ namespace Drupal\taxonomy\Entity; use Drupal\Core\Config\Entity\ConfigEntityBundleBase; -use Drupal\Core\Config\Entity\ThirdPartySettingsTrait; use Drupal\Core\Entity\EntityStorageInterface; use Drupal\taxonomy\VocabularyInterface; @@ -46,7 +45,6 @@ * ) */ class Vocabulary extends ConfigEntityBundleBase implements VocabularyInterface { - use ThirdPartySettingsTrait; /** * The taxonomy vocabulary ID. diff --git a/core/modules/taxonomy/tests/modules/taxonomy_crud/config/schema/taxonomy_crud.schema.yml b/core/modules/taxonomy/tests/modules/taxonomy_crud/config/schema/taxonomy_crud.schema.yml index fdbed04..fdbffe9 100644 --- a/core/modules/taxonomy/tests/modules/taxonomy_crud/config/schema/taxonomy_crud.schema.yml +++ b/core/modules/taxonomy/tests/modules/taxonomy_crud/config/schema/taxonomy_crud.schema.yml @@ -1,4 +1,4 @@ -taxonomy.vocabulary.third_party.taxonomy_crud: +taxonomy.vocabulary.*.third_party.taxonomy_crud: type: mapping label: 'Schema for taxonomy_crud module additions to vocabulary entity' mapping: diff --git a/core/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityBaseUnitTest.php b/core/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityBaseUnitTest.php index 7af62e5..9456d33 100644 --- a/core/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityBaseUnitTest.php +++ b/core/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityBaseUnitTest.php @@ -291,14 +291,20 @@ public function providerCalculateDependenciesWithPluginCollections() { /** * @covers ::calculateDependencies + * @covers ::onDependencyRemoval */ public function testCalculateDependenciesWithThirdPartySettings() { - $this->entity = $this->getMockForAbstractClass('\Drupal\Tests\Core\Config\Entity\Fixtures\ConfigEntityBaseWithThirdPartySettings', array(array(), $this->entityTypeId)); + $this->entity = $this->getMockForAbstractClass('\Drupal\Core\Config\Entity\ConfigEntityBase', array(array(), $this->entityTypeId)); $this->entity->setThirdPartySetting('test_provider', 'test', 'test'); $this->entity->setThirdPartySetting('test_provider2', 'test', 'test'); $this->entity->setThirdPartySetting($this->provider, 'test', 'test'); $this->assertEquals(array('test_provider', 'test_provider2'), $this->entity->calculateDependencies()['module']); + $changed = $this->entity->onDependencyRemoval(['module' => ['test_provider2']]); + $this->assertTrue($changed, 'Calling onDependencyRemoval with an existing third party dependency provider returns TRUE.'); + $changed = $this->entity->onDependencyRemoval(['module' => ['test_provider3']]); + $this->assertFalse($changed, 'Calling onDependencyRemoval with a non-existing third party dependency provider returns FALSE.'); + $this->assertEquals(array('test_provider'), $this->entity->calculateDependencies()['module']); } /** @@ -467,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/Fixtures/ConfigEntityBaseWithThirdPartySettings.php b/core/tests/Drupal/Tests/Core/Config/Entity/Fixtures/ConfigEntityBaseWithThirdPartySettings.php deleted file mode 100644 index 6834e63..0000000 --- a/core/tests/Drupal/Tests/Core/Config/Entity/Fixtures/ConfigEntityBaseWithThirdPartySettings.php +++ /dev/null @@ -1,23 +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; - -}