diff --git a/core/config/schema/core.data_types.schema.yml b/core/config/schema/core.data_types.schema.yml index 0c9ad70569adde8e914aa466da7ea41493f0c772..41332e3eea03d4aca6ab07378182fc44ff866809 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 ee3d5d78285dd07f1c4f1c3a8eb4a1a2bc65ce15..de9530d3865512979e3779c8e1b57c9c8a62175b 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 e3fcaf8856a66ecb6db5234ff9a2ad225eddaf18..7f4a534c8edc9adf152f7cb131679d0ed673d64c 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 12a45432175718ef194cafbfb53d2837f5e541a3..9c8a5e2b61800b2fb1bd5302a6d7835927a18a6d 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; @@ -87,6 +87,15 @@ abstract class ConfigEntityBase extends Entity implements ConfigEntityInterface */ 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(). */ @@ -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 15347e3e70f0d55f5c640b28c124677776df4332..1db3b422ee260a4bda8ab11eec367cc7ee52c03e 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 cc12885a3157e88338bd6bc44e345ac55dab31f7..0000000000000000000000000000000000000000 --- a/core/lib/Drupal/Core/Config/Entity/ThirdPartySettingsTrait.php +++ /dev/null @@ -1,114 +0,0 @@ -<?php - -/** - * @file - * Contains \Drupal\Core\Config\Entity\ThirdPartySettingsTrait. - */ - -namespace Drupal\Core\Config\Entity; - -/** - * Provides generic implementation of ThirdPartySettingsInterface. - * - * The name of the property used to store third party settings is - * 'third_party_settings'. You need to provide configuration schema for that - * setting to ensure it is persisted. See 'third_party_settings' defined on - * field_config_base and other 'field_config.third_party.*' types. - * - * @see \Drupal\Core\Config\Entity\ThirdPartySettingsInterface - */ -trait ThirdPartySettingsTrait { - - /** - * Third party entity settings. - * - * An array of key/value pairs keyed by provider. - * - * @var array - */ - protected $third_party_settings = array(); - - /** - * Sets 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 $value - * The setting value. - * - * @return $this - */ - public function setThirdPartySetting($module, $key, $value) { - $this->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 22f43c1db87351a2dab3382bd8ace6d8ad583b5d..2a9dd9d63c1c440854f108a0f8a7b6a629de9027 100644 --- a/core/lib/Drupal/Core/Config/TypedConfigManager.php +++ b/core/lib/Drupal/Core/Config/TypedConfigManager.php @@ -240,6 +240,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 @@ -249,6 +251,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. @@ -273,9 +278,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 05c0144e4e6fd9c4583e965b0f5f9b57f89a0b0b..90d5955807dbf0c2bdd13dd03f02986ae9f545d8 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 af1c3999fbeb0e634d5ad272e929ef4b16fccdbb..7388b4b27ca20acb6e87dba3e565b92162e61ce1 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 a2a3510e771bc391807e6d28ae4312c86598befd..5e5c605f2111c422cacef271f5bfbb587428e682 100644 --- a/core/modules/config/src/Tests/ConfigSchemaTest.php +++ b/core/modules/config/src/Tests/ConfigSchemaTest.php @@ -26,7 +26,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} @@ -172,7 +172,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); @@ -203,6 +203,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 0000000000000000000000000000000000000000..3db9b1d39b199d32ee0e3428a9980bb0a798560e --- /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 719865a47d248d244388e00a1b9b32ac81084dbb..8c8660c4ee52557a23b2500486e0909bfaa7dbbb 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 @@ -209,3 +209,11 @@ test_with_parents.plugin_types.*: config_schema_test.hook: 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 43575975eec189dfbb6d19287867f67279a70e54..d1c9a576f2bb7acb9fb15c2899249b2884c69854 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 011ae37016489c8c7154460dd9b7c8215842457b..7ebb6f41a20c8a9ad66873d0a303d4b5010c229f 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 d4be3de6e615445fa9a441d37afe2d61d0433066..c0cf26ad4aa1e4742c47ce9617868914915b0986 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 e421214f1c61fec98e5e71614a4bcafdc9f50d64..489301e90cf43730314c0d370691400f18780220 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 1e724d8f7a10b5422295e7663f7a330cecae05e4..ddccb5b8ba235326de7fae8e928451b0f8970c7b 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 dc4643aaca57edefb868dbb35ce233f7a72764ce..6df0f97a4c6c11e8e9dceecb6fe93747dfa0ad5e 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 87f38f69ec8731116cfb0a8455b1f4dfb9fb4950..00268ef6083d583207dd929b3d4d31cc3b4e8a2c 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 4c3775169b6234d3cd6b1b7f4b5d1aa9f615c1e7..a3c7ab534029f2b62934ffce8e1b0ba34c70a27c 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 a36719d703156e38257dfe4a89514459cefd7820..b0e8ebf18a6a741ef64906e617e6a1b828bea4f4 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 d894eb695ab3de831f26aee6e6b13780b60b97d4..bd03869a2a72d2ec029b213d7b6b051d98ddf984 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 607fb4cd580fb60aff027af05358f437b5fc3111..19ca5847779cdada9cb96baff32a193baa292ef4 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 ed1fef8d6072f447187bb8fa329a68f77f3bbd66..ad096f2f2a3a732eb3a8216fbbfa4f645baff115 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 f650794ccdf299d482f1cab7de9cdd49e0f87026..9b8931c738d1c132516331d93ef99708108bcff4 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 8a08d2670aae6dac1f889856866495689787e902..238ae8f7b0219c742a42adbcc2198e2b09ba5966 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 60d5c33833f2cee224ab8cb0ab15d7905d498da7..01185b57305c6cb7c7d5b57f268a3541bccf8956 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. @@ -48,6 +49,14 @@ protected function setUp() { $this->drupalLogin($this->translator); } + /** + * Tests the basic translation UI. + */ + function testTranslationUI() { + parent::testTranslationUI(); + $this->doUninstallTest(); + } + /** * Overrides \Drupal\content_translation\Tests\ContentTranslationUITest::getTranslatorPermission(). */ @@ -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 5a3ad024e9a1c42339e5099cbb9015745709712e..d671bc40141bf29e72660616edbc13aec9848e0d 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 cf4a3a97a51e5b76dbe9c343806b18b955e0f202..c79fa5fc6b623d8b75015808ebbdae5dc3c1be9a 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 4f21f8a781fda39ba6ca2c768fe69f106ce47b3c..ae7b10f1e5d487339b3d701ee60a771af4228dd3 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 fdbed04c90c65ba6c5452c90d09e0baa8a6be57a..fdbffe9d0b7a9c58ace4fb3e0f0592db330fcbb3 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 7af62e5db273d354e9e9f176872deaa61a3b5d11..9456d33c81c56d7f5096b15379b808b45e83268a 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 6834e63bba384161788c0e6f57c1f1576b4c4ffa..0000000000000000000000000000000000000000 --- a/core/tests/Drupal/Tests/Core/Config/Entity/Fixtures/ConfigEntityBaseWithThirdPartySettings.php +++ /dev/null @@ -1,23 +0,0 @@ -<?php - -/** - * @file - * Contains \Drupal\Tests\Core\Config\Entity\Fixtures\ConfigEntityBaseWithThirdPartySettings. - */ - -namespace Drupal\Tests\Core\Config\Entity\Fixtures; - -use Drupal\Core\Config\Entity\ConfigEntityBase; -use Drupal\Core\Config\Entity\ThirdPartySettingsInterface; -use Drupal\Core\Config\Entity\ThirdPartySettingsTrait; - -/** - * Enables testing of dependency calculation. - * - * @see \Drupal\Tests\Core\Config\Entity\ConfigEntityBaseUnitTest::testCalculateDependenciesWithThirdPartySettings() - * @see \Drupal\Core\Config\Entity\ConfigEntityBase::calculateDependencies() - */ -abstract class ConfigEntityBaseWithThirdPartySettings extends ConfigEntityBase implements ThirdPartySettingsInterface { - use ThirdPartySettingsTrait; - -} 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 bcbe12bf2b3e9bc4fc93fd17cab99be4bb22c04d..0000000000000000000000000000000000000000 --- a/core/tests/Drupal/Tests/Core/Config/Entity/ThirdPartySettingsTraitTest.php +++ /dev/null @@ -1,60 +0,0 @@ -<?php - -/** - * @file - * Contains \Drupal\Tests\Core\Config\Entity\ThirdPartySettingsTraitTest. - */ - -namespace Drupal\Tests\Core\Config\Entity; - -use Drupal\Core\Config\Entity\ThirdPartySettingsTrait; -use Drupal\Tests\UnitTestCase; - -/** - * @coversDefaultClass \Drupal\Core\Config\Entity\ThirdPartySettingsTrait - * @group Config - */ -class ThirdPartySettingsTraitTest extends UnitTestCase { - - /** - * @covers ::getThirdPartySetting - * @covers ::setThirdPartySetting - * @covers ::getThirdPartySettings - * @covers ::unsetThirdPartySetting - * @covers ::getThirdPartyProviders - */ - public function testThirdPartySettings() { - $key = 'test'; - $third_party = 'test_provider'; - $value = $this->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; - -}