diff --git a/core/includes/file.inc b/core/includes/file.inc index 858c4a6..60cec1c 100644 --- a/core/includes/file.inc +++ b/core/includes/file.inc @@ -1215,8 +1215,9 @@ function file_directory_temp() { // everything to use slash which is supported on all platforms. $temporary_directory = str_replace('\\', '/', $temporary_directory); } - // Save the path of the discovered directory. - $config->set('path.temporary', $temporary_directory)->save(); + // Save the path of the discovered directory. Do not check config schema on + // save. + $config->set('path.temporary', (string) $temporary_directory)->save(TRUE); } return $temporary_directory; diff --git a/core/includes/install.inc b/core/includes/install.inc index 7e0e32e..d56c44f 100644 --- a/core/includes/install.inc +++ b/core/includes/install.inc @@ -619,9 +619,9 @@ function drupal_install_system($install_state) { // Ensure default language is saved. if (isset($install_state['parameters']['langcode'])) { \Drupal::configFactory()->getEditable('system.site') - ->set('langcode', $install_state['parameters']['langcode']) - ->set('default_langcode', $install_state['parameters']['langcode']) - ->save(); + ->set('langcode', (string) $install_state['parameters']['langcode']) + ->set('default_langcode', (string) $install_state['parameters']['langcode']) + ->save(TRUE); } } diff --git a/core/includes/module.inc b/core/includes/module.inc index 0f1b0d8..8f8bf9c 100644 --- a/core/includes/module.inc +++ b/core/includes/module.inc @@ -179,10 +179,12 @@ function drupal_required_modules() { function module_set_weight($module, $weight) { $extension_config = \Drupal::configFactory()->getEditable('core.extension'); if ($extension_config->get("module.$module") !== NULL) { + // Pre-cast the $weight to an integer so that we can save this without using + // schema. This is a performance improvement for module installation. $extension_config - ->set("module.$module", $weight) + ->set("module.$module", (int) $weight) ->set('module', module_config_sort($extension_config->get('module'))) - ->save(); + ->save(TRUE); // Prepare the new module list, sorted by weight, including filenames. // @see \Drupal\Core\Extension\ModuleHandler::install() diff --git a/core/lib/Drupal/Core/Config/Config.php b/core/lib/Drupal/Core/Config/Config.php index 51ade6c..8861481 100644 --- a/core/lib/Drupal/Core/Config/Config.php +++ b/core/lib/Drupal/Core/Config/Config.php @@ -203,22 +203,24 @@ public function clear($key) { /** * {@inheritdoc} */ - public function save() { + public function save($has_trusted_data = FALSE) { // Validate the configuration object name before saving. static::validateName($this->name); // If there is a schema for this configuration object, cast all values to // conform to the schema. - if ($this->typedConfigManager->hasConfigSchema($this->name)) { - // Ensure that the schema wrapper has the latest data. - $this->schemaWrapper = NULL; - foreach ($this->data as $key => $value) { - $this->data[$key] = $this->castValue($key, $value); + if (!$has_trusted_data) { + if ($this->typedConfigManager->hasConfigSchema($this->name)) { + // Ensure that the schema wrapper has the latest data. + $this->schemaWrapper = NULL; + foreach ($this->data as $key => $value) { + $this->data[$key] = $this->castValue($key, $value); + } } - } - else { - foreach ($this->data as $key => $value) { - $this->validateValue($key, $value); + else { + foreach ($this->data as $key => $value) { + $this->validateValue($key, $value); + } } } @@ -302,4 +304,5 @@ public function getOriginal($key = '', $apply_overrides = TRUE) { } } } + } diff --git a/core/lib/Drupal/Core/Config/ConfigInstaller.php b/core/lib/Drupal/Core/Config/ConfigInstaller.php index c109ea7..082fa63 100644 --- a/core/lib/Drupal/Core/Config/ConfigInstaller.php +++ b/core/lib/Drupal/Core/Config/ConfigInstaller.php @@ -304,11 +304,11 @@ protected function createConfiguration($collection, array $config_to_create) { $entity = $entity_storage->createFromStorageRecord($new_config->get()); } if ($entity->isInstallable()) { - $entity->save(); + $entity->trustData()->save(); } } else { - $new_config->save(); + $new_config->save(TRUE); } } } diff --git a/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php b/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php index 0ca35a5..56603c7 100644 --- a/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php +++ b/core/lib/Drupal/Core/Config/Entity/ConfigEntityBase.php @@ -106,6 +106,13 @@ protected $third_party_settings = array(); /** + * Trust supplied data and not use configuration schema on save. + * + * @var bool + */ + protected $trustedData = FALSE; + + /** * Overrides Entity::__construct(). */ public function __construct(array $values, $entity_type) { @@ -265,22 +272,31 @@ public static function sort(ConfigEntityInterface $a, ConfigEntityInterface $b) */ public function toArray() { $properties = array(); - $config_name = $this->getEntityType()->getConfigPrefix() . '.' . $this->id(); - $definition = $this->getTypedConfig()->getDefinition($config_name); - if (!isset($definition['mapping'])) { - throw new SchemaIncompleteException(SafeMarkup::format('Incomplete or missing schema for @config_name', array('@config_name' => $config_name))); + /** @var \Drupal\Core\Config\Entity\ConfigEntityTypeInterface $entity_type */ + $entity_type = $this->getEntityType(); + + $properties_to_export = $entity_type->getPropertiesToExport(); + if (empty($properties_to_export)) { + $config_name = $entity_type->getConfigPrefix() . '.' . $this->id(); + $definition = $this->getTypedConfig()->getDefinition($config_name); + if (!isset($definition['mapping'])) { + throw new SchemaIncompleteException(SafeMarkup::format('Incomplete or missing schema for @config_name', array('@config_name' => $config_name))); + } + $properties_to_export = array_combine(array_keys($definition['mapping']), array_keys($definition['mapping'])); } - $id_key = $this->getEntityType()->getKey('id'); - foreach (array_keys($definition['mapping']) as $name) { + + $id_key = $entity_type->getKey('id'); + foreach ($properties_to_export as $property_name => $export_name) { // Special handling for IDs so that computed compound IDs work. // @see \Drupal\Core\Entity\EntityDisplayBase::id() - if ($name == $id_key) { - $properties[$name] = $this->id(); + if ($property_name == $id_key) { + $properties[$export_name] = $this->id(); } else { - $properties[$name] = $this->get($name); + $properties[$export_name] = $this->get($property_name); } } + if (empty($this->third_party_settings)) { unset($properties['third_party_settings']); } @@ -328,7 +344,7 @@ public function preSave(EntityStorageInterface $storage) { throw new ConfigDuplicateUUIDException(SafeMarkup::format('Attempt to save a configuration entity %id with UUID %uuid when this entity already exists with UUID %original_uuid', array('%id' => $this->id(), '%uuid' => $this->uuid(), '%original_uuid' => $original->uuid()))); } } - if (!$this->isSyncing()) { + if (!$this->isSyncing() && !$this->trustedData) { // Ensure the correct dependencies are present. If the configuration is // being written during a configuration synchronization then there is no // need to recalculate the dependencies. @@ -572,4 +588,28 @@ public function isInstallable() { return TRUE; } + /** + * {@inheritdoc} + */ + public function trustData() { + $this->trustedData = TRUE; + return $this; + } + + /** + * {@inheritdoc} + */ + public function hasTrustedData() { + return $this->trustedData; + } + + /** + * {@inheritdoc} + */ + public function save() { + $return = parent::save(); + $this->trustedData = FALSE; + return $return; + } + } diff --git a/core/lib/Drupal/Core/Config/Entity/ConfigEntityInterface.php b/core/lib/Drupal/Core/Config/Entity/ConfigEntityInterface.php index 3d688a5..76809ed 100644 --- a/core/lib/Drupal/Core/Config/Entity/ConfigEntityInterface.php +++ b/core/lib/Drupal/Core/Config/Entity/ConfigEntityInterface.php @@ -203,4 +203,27 @@ public function getDependencies(); */ public function isInstallable(); + /** + * Sets that the data should be trusted. + * + * If the data is trusted then dependencies will not be calculated on save and + * schema will not be used to cast the values. Generally this is only used + * during module and theme installation. Once the config entity has been saved + * the data will no longer be marked as trusted. This is an optimization for + * creation of configuration during installation. + * + * @return $this + * + * @see \Drupal\Core\Config\ConfigInstaller::createConfiguration() + */ + public function trustData(); + + /** + * Gets whether on not the data is trusted. + * + * @return bool + * TRUE if the configuration data is trusted, FALSE if not. + */ + public function hasTrustedData(); + } diff --git a/core/lib/Drupal/Core/Config/Entity/ConfigEntityStorage.php b/core/lib/Drupal/Core/Config/Entity/ConfigEntityStorage.php index 2c3e798..540fa15 100644 --- a/core/lib/Drupal/Core/Config/Entity/ConfigEntityStorage.php +++ b/core/lib/Drupal/Core/Config/Entity/ConfigEntityStorage.php @@ -256,7 +256,7 @@ protected function doSave($id, EntityInterface $entity) { // Retrieve the desired properties and set them in config. $config->setData($this->mapToStorageRecord($entity)); - $config->save(); + $config->save($entity->hasTrustedData()); return $is_new ? SAVED_NEW : SAVED_UPDATED; } diff --git a/core/lib/Drupal/Core/Config/Entity/ConfigEntityType.php b/core/lib/Drupal/Core/Config/Entity/ConfigEntityType.php index 0cb9772..f15eef5 100644 --- a/core/lib/Drupal/Core/Config/Entity/ConfigEntityType.php +++ b/core/lib/Drupal/Core/Config/Entity/ConfigEntityType.php @@ -35,6 +35,22 @@ class ConfigEntityType extends EntityType implements ConfigEntityTypeInterface { protected $static_cache = FALSE; /** + * The list of configuration entity properties to export from the annotation. + * + * @var array + */ + protected $config_export = []; + + /** + * The result of merging config_export annotation with the defaults. + * + * This is stored on the class so that it does not have to be recalculated. + * + * @var array + */ + protected $mergedConfigExport = []; + + /** * {@inheritdoc} * * @throws \Drupal\Core\Config\Entity\Exception\ConfigEntityStorageClassException @@ -146,4 +162,32 @@ protected function checkStorageClass($class) { } } + /** + * {@inheritdoc} + */ + public function getPropertiesToExport() { + if (!empty($this->config_export)) { + if (empty($this->mergedConfigExport)) { + // Always add default properties to be exported. + $this->mergedConfigExport = [ + 'uuid' => 'uuid', + 'langcode' => 'langcode', + 'status' => 'status', + 'dependencies' => 'dependencies', + 'third_party_settings' => 'third_party_settings', + ]; + foreach ($this->config_export as $property => $name) { + if (is_numeric($property)) { + $this->mergedConfigExport[$name] = $name; + } + else { + $this->mergedConfigExport[$property] = $name; + } + } + } + return $this->mergedConfigExport; + } + return NULL; + } + } diff --git a/core/lib/Drupal/Core/Config/Entity/ConfigEntityTypeInterface.php b/core/lib/Drupal/Core/Config/Entity/ConfigEntityTypeInterface.php index a24c96f..0f26ae0 100644 --- a/core/lib/Drupal/Core/Config/Entity/ConfigEntityTypeInterface.php +++ b/core/lib/Drupal/Core/Config/Entity/ConfigEntityTypeInterface.php @@ -61,4 +61,13 @@ */ public function getConfigPrefix(); + /** + * Gets the config entity properties to export if declared on the annotation. + * + * @return array|NULL + * The properties to export or NULL if they can not be determine from the + * config entity type annotation. + */ + public function getPropertiesToExport(); + } diff --git a/core/lib/Drupal/Core/Config/ImmutableConfig.php b/core/lib/Drupal/Core/Config/ImmutableConfig.php index e6938fb..8435f71 100644 --- a/core/lib/Drupal/Core/Config/ImmutableConfig.php +++ b/core/lib/Drupal/Core/Config/ImmutableConfig.php @@ -44,7 +44,7 @@ public function clear($key) { /** * {@inheritdoc} */ - public function save() { + public function save($has_trusted_data = FALSE) { throw new ImmutableConfigException(SafeMarkup::format('Can not save immutable configuration !name. Use \Drupal\Core\Config\ConfigFactoryInterface::getEditable() to retrieve a mutable configuration object', ['!name' => $this->getName()])); } diff --git a/core/lib/Drupal/Core/Config/StorableConfigBase.php b/core/lib/Drupal/Core/Config/StorableConfigBase.php index 625900c..d5ea532 100644 --- a/core/lib/Drupal/Core/Config/StorableConfigBase.php +++ b/core/lib/Drupal/Core/Config/StorableConfigBase.php @@ -66,11 +66,18 @@ /** * Saves the configuration object. * + * @param bool $has_trusted_data + * Set to TRUE is the configuration data has already been checked to ensure + * it conforms to schema. Generally this is only used during module and + * theme installation. + * * Must invalidate the cache tags associated with the configuration object. * * @return $this + * + * @see \Drupal\Core\Config\ConfigInstaller::createConfiguration() */ - abstract public function save(); + abstract public function save($has_trusted_data = FALSE); /** * Deletes the configuration object. diff --git a/core/lib/Drupal/Core/Datetime/Entity/DateFormat.php b/core/lib/Drupal/Core/Datetime/Entity/DateFormat.php index f8bb442..fa1de86 100644 --- a/core/lib/Drupal/Core/Datetime/Entity/DateFormat.php +++ b/core/lib/Drupal/Core/Datetime/Entity/DateFormat.php @@ -25,7 +25,13 @@ * "label" = "label" * }, * admin_permission = "administer site configuration", - * list_cache_tags = { "rendered" } + * list_cache_tags = { "rendered" }, + * config_export = { + * "id", + * "label", + * "locked", + * "pattern", + * } * ) */ class DateFormat extends ConfigEntityBase implements DateFormatInterface { diff --git a/core/lib/Drupal/Core/Entity/Entity/EntityFormDisplay.php b/core/lib/Drupal/Core/Entity/Entity/EntityFormDisplay.php index ae4b46d..d0280a0 100644 --- a/core/lib/Drupal/Core/Entity/Entity/EntityFormDisplay.php +++ b/core/lib/Drupal/Core/Entity/Entity/EntityFormDisplay.php @@ -23,6 +23,14 @@ * entity_keys = { * "id" = "id", * "status" = "status" + * }, + * config_export = { + * "id", + * "targetEntityType", + * "bundle", + * "mode", + * "content", + * "hidden", * } * ) */ diff --git a/core/lib/Drupal/Core/Entity/Entity/EntityFormMode.php b/core/lib/Drupal/Core/Entity/Entity/EntityFormMode.php index 7f8371a..1fed80c 100644 --- a/core/lib/Drupal/Core/Entity/Entity/EntityFormMode.php +++ b/core/lib/Drupal/Core/Entity/Entity/EntityFormMode.php @@ -33,6 +33,12 @@ * entity_keys = { * "id" = "id", * "label" = "label" + * }, + * config_export = { + * "id", + * "label", + * "targetEntityType", + * "cache", * } * ) */ diff --git a/core/lib/Drupal/Core/Entity/Entity/EntityViewDisplay.php b/core/lib/Drupal/Core/Entity/Entity/EntityViewDisplay.php index 5b28f76..db56e8b 100644 --- a/core/lib/Drupal/Core/Entity/Entity/EntityViewDisplay.php +++ b/core/lib/Drupal/Core/Entity/Entity/EntityViewDisplay.php @@ -24,6 +24,14 @@ * entity_keys = { * "id" = "id", * "status" = "status" + * }, + * config_export = { + * "id", + * "targetEntityType", + * "bundle", + * "mode", + * "content", + * "hidden", * } * ) */ diff --git a/core/lib/Drupal/Core/Entity/Entity/EntityViewMode.php b/core/lib/Drupal/Core/Entity/Entity/EntityViewMode.php index 80a3875..08eb661 100644 --- a/core/lib/Drupal/Core/Entity/Entity/EntityViewMode.php +++ b/core/lib/Drupal/Core/Entity/Entity/EntityViewMode.php @@ -35,6 +35,12 @@ * entity_keys = { * "id" = "id", * "label" = "label" + * }, + * config_export = { + * "id", + * "label", + * "targetEntityType", + * "cache", * } * ) */ diff --git a/core/lib/Drupal/Core/Extension/ModuleInstaller.php b/core/lib/Drupal/Core/Extension/ModuleInstaller.php index caddbad..6f65a73 100644 --- a/core/lib/Drupal/Core/Extension/ModuleInstaller.php +++ b/core/lib/Drupal/Core/Extension/ModuleInstaller.php @@ -155,10 +155,12 @@ public function install(array $module_list, $enable_dependencies = TRUE) { // exceptions if the configuration is not valid. $config_installer->checkConfigurationToInstall('module', $module); + // Save this data without checking schema. This is a performance + // improvement for module installation. $extension_config ->set("module.$module", 0) ->set('module', module_config_sort($extension_config->get('module'))) - ->save(); + ->save(TRUE); // Prepare the new module list, sorted by weight, including filenames. // This list is used for both the ModuleHandler and DrupalKernel. It @@ -385,8 +387,9 @@ public function uninstall(array $module_list, $uninstall_dependents = TRUE) { // Remove the schema. drupal_uninstall_schema($module); - // Remove the module's entry from the config. - \Drupal::configFactory()->getEditable('core.extension')->clear("module.$module")->save(); + // Remove the module's entry from the config. Don't check schema when + // uninstalling a module since we are only clearing a key. + \Drupal::configFactory()->getEditable('core.extension')->clear("module.$module")->save(TRUE); // Update the module handler to remove the module. // The current ModuleHandler instance is obsolete with the kernel rebuild diff --git a/core/lib/Drupal/Core/Extension/ThemeHandler.php b/core/lib/Drupal/Core/Extension/ThemeHandler.php index 57a317e..9d790ae 100644 --- a/core/lib/Drupal/Core/Extension/ThemeHandler.php +++ b/core/lib/Drupal/Core/Extension/ThemeHandler.php @@ -260,10 +260,11 @@ public function install(array $theme_list, $install_dependencies = TRUE) { // configuration then stop installing. $this->configInstaller->checkConfigurationToInstall('theme', $key); - // The value is not used; the weight is ignored for themes currently. + // The value is not used; the weight is ignored for themes currently. Do + // not check schema when saving the configuration. $extension_config ->set("theme.$key", 0) - ->save(); + ->save(TRUE); // Add the theme to the current list. // @todo Remove all code that relies on $status property. @@ -358,7 +359,9 @@ public function uninstall(array $theme_list) { $this->configManager->uninstall('theme', $key); } - $extension_config->save(); + // Don't check schema when uninstalling a theme since we are only clearing + // keys. + $extension_config->save(TRUE); $this->state->set('system.theme.data', $current_theme_data); $this->resetSystem(); diff --git a/core/lib/Drupal/Core/Field/Entity/BaseFieldOverride.php b/core/lib/Drupal/Core/Field/Entity/BaseFieldOverride.php index 7755187..32862d1 100644 --- a/core/lib/Drupal/Core/Field/Entity/BaseFieldOverride.php +++ b/core/lib/Drupal/Core/Field/Entity/BaseFieldOverride.php @@ -28,6 +28,20 @@ * entity_keys = { * "id" = "id", * "label" = "label" + * }, + * config_export = { + * "id", + * "field_name", + * "entity_type", + * "bundle", + * "label", + * "description", + * "required", + * "translatable", + * "default_value", + * "default_value_callback", + * "settings", + * "field_type", * } * ) */ diff --git a/core/lib/Drupal/Core/Installer/Form/SiteConfigureForm.php b/core/lib/Drupal/Core/Installer/Form/SiteConfigureForm.php index 0354e25..2ad8dc5 100644 --- a/core/lib/Drupal/Core/Installer/Form/SiteConfigureForm.php +++ b/core/lib/Drupal/Core/Installer/Form/SiteConfigureForm.php @@ -260,14 +260,14 @@ public function validateForm(array &$form, FormStateInterface $form_state) { */ public function submitForm(array &$form, FormStateInterface $form_state) { $this->config('system.site') - ->set('name', $form_state->getValue('site_name')) - ->set('mail', $form_state->getValue('site_mail')) - ->save(); + ->set('name', (string) $form_state->getValue('site_name')) + ->set('mail', (string) $form_state->getValue('site_mail')) + ->save(TRUE); $this->config('system.date') - ->set('timezone.default', $form_state->getValue('date_default_timezone')) - ->set('country.default', $form_state->getValue('site_default_country')) - ->save(); + ->set('timezone.default', (string) $form_state->getValue('date_default_timezone')) + ->set('country.default', (string) $form_state->getValue('site_default_country')) + ->save(TRUE); $account_values = $form_state->getValue('account'); @@ -281,7 +281,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) { if ($update_status_module[2]) { // Reset the configuration factory so it is updated with the new module. $this->resetConfigFactory(); - $this->config('update.settings')->set('notification.emails', array($account_values['mail']))->save(); + $this->config('update.settings')->set('notification.emails', array($account_values['mail']))->save(TRUE); } } diff --git a/core/lib/Drupal/Core/Menu/StaticMenuLinkOverrides.php b/core/lib/Drupal/Core/Menu/StaticMenuLinkOverrides.php index a52601c..d09f714 100644 --- a/core/lib/Drupal/Core/Menu/StaticMenuLinkOverrides.php +++ b/core/lib/Drupal/Core/Menu/StaticMenuLinkOverrides.php @@ -130,20 +130,29 @@ public function loadMultipleOverrides(array $ids) { public function saveOverride($id, array $definition) { // Only allow to override a specific subset of the keys. $expected = array( - 'menu_name' => 1, - 'parent' => 1, - 'weight' => 1, - 'expanded' => 1, - 'enabled' => 1, + 'menu_name' => '', + 'parent' => '', + 'weight' => 0, + 'expanded' => FALSE, + 'enabled' => FALSE, ); // Filter the overrides to only those that are expected. $definition = array_intersect_key($definition, $expected); + // Ensure all values are set. + $definition = $definition + $expected; if ($definition) { + // Cast keys to avoid config schema during save. + $definition['menu_name'] = (string) $definition['menu_name']; + $definition['parent'] = (string) $definition['parent']; + $definition['weight'] = (int) $definition['weight']; + $definition['expanded'] = (bool) $definition['expanded']; + $definition['enabled'] = (bool) $definition['enabled']; + $id = static::encodeId($id); $all_overrides = $this->getConfig()->get('definitions'); // Combine with any existing data. $all_overrides[$id] = $definition + $this->loadOverride($id); - $this->getConfig()->set('definitions', $all_overrides)->save(); + $this->getConfig()->set('definitions', $all_overrides)->save(TRUE); } return array_keys($definition); } diff --git a/core/modules/block/src/Entity/Block.php b/core/modules/block/src/Entity/Block.php index 4af2f80..019f997 100644 --- a/core/modules/block/src/Entity/Block.php +++ b/core/modules/block/src/Entity/Block.php @@ -38,6 +38,16 @@ * links = { * "delete-form" = "/admin/structure/block/manage/{block}/delete", * "edit-form" = "/admin/structure/block/manage/{block}" + * }, + * config_export = { + * "id", + * "theme", + * "region", + * "weight", + * "provider", + * "plugin", + * "settings", + * "visibility", * } * ) */ diff --git a/core/modules/block_content/src/Entity/BlockContentType.php b/core/modules/block_content/src/Entity/BlockContentType.php index 81b64e9..8494814 100644 --- a/core/modules/block_content/src/Entity/BlockContentType.php +++ b/core/modules/block_content/src/Entity/BlockContentType.php @@ -38,6 +38,12 @@ * "delete-form" = "/admin/structure/block/block-content/manage/{block_content_type}/delete", * "edit-form" = "/admin/structure/block/block-content/manage/{block_content_type}", * "collection" = "/admin/structure/block/block-content/types", + * }, + * config_export = { + * "id", + * "label", + * "revision", + * "description", * } * ) */ diff --git a/core/modules/book/config/install/node.type.book.yml b/core/modules/book/config/install/node.type.book.yml index 1a5cc16..a5076b2 100644 --- a/core/modules/book/config/install/node.type.book.yml +++ b/core/modules/book/config/install/node.type.book.yml @@ -1,6 +1,8 @@ langcode: en status: true dependencies: + module: + - book enforced: module: - book diff --git a/core/modules/comment/src/Entity/CommentType.php b/core/modules/comment/src/Entity/CommentType.php index fb41442..94fd193 100644 --- a/core/modules/comment/src/Entity/CommentType.php +++ b/core/modules/comment/src/Entity/CommentType.php @@ -38,6 +38,12 @@ * "edit-form" = "/admin/structure/comment/manage/{comment_type}", * "add-form" = "/admin/structure/comment/types/add", * "collection" = "/admin/structure/comment/types", + * }, + * config_export = { + * "id", + * "label", + * "target_entity_type_id", + * "description", * } * ) */ diff --git a/core/modules/config/src/Tests/ConfigInstallTest.php b/core/modules/config/src/Tests/ConfigInstallTest.php index 00ec4fa..2d09548 100644 --- a/core/modules/config/src/Tests/ConfigInstallTest.php +++ b/core/modules/config/src/Tests/ConfigInstallTest.php @@ -53,7 +53,7 @@ function testModuleInstallation() { // Ensure that schema provided by modules that are not installed is not // available. - $this->assertFalse(\Drupal::service('config.typed')->hasConfigSchema('config_schema_test.schema_in_install'), 'Configuration schema for config_schema_test.schema_in_install does not exist.'); + $this->assertFalse(\Drupal::service('config.typed')->hasConfigSchema('config_schema_test.someschema'), 'Configuration schema for config_schema_test.someschema does not exist.'); // Install the test module. $this->installModules(array('config_test')); @@ -80,16 +80,12 @@ function testModuleInstallation() { $this->installConfig(array('config_schema_test')); // After module installation the new schema should exist. - $this->assertTrue(\Drupal::service('config.typed')->hasConfigSchema('config_schema_test.schema_in_install'), 'Configuration schema for config_schema_test.schema_in_install exists.'); - - // Ensure that data type casting is applied during config installation. - $config = $this->config('config_schema_test.schema_in_install'); - $this->assertIdentical($config->get('integer'), 1); + $this->assertTrue(\Drupal::service('config.typed')->hasConfigSchema('config_schema_test.someschema'), 'Configuration schema for config_schema_test.someschema exists.'); // Test that uninstalling configuration removes configuration schema. $this->config('core.extension')->set('module', array())->save(); \Drupal::service('config.manager')->uninstall('module', 'config_test'); - $this->assertFalse(\Drupal::service('config.typed')->hasConfigSchema('config_schema_test.schema_in_install'), 'Configuration schema for config_schema_test.schema_in_install does not exist.'); + $this->assertFalse(\Drupal::service('config.typed')->hasConfigSchema('config_schema_test.someschema'), 'Configuration schema for config_schema_test.someschema does not exist.'); } /** diff --git a/core/modules/config/src/Tests/ConfigSchemaTest.php b/core/modules/config/src/Tests/ConfigSchemaTest.php index 8a8f649..11865ef 100644 --- a/core/modules/config/src/Tests/ConfigSchemaTest.php +++ b/core/modules/config/src/Tests/ConfigSchemaTest.php @@ -209,6 +209,7 @@ function testSchemaMapping() { $this->assertEqual($definition, $expected, 'Retrieved the right metadata for the first effect of image.style.medium'); + $a = \Drupal::config('config_test.dynamic.third_party'); $test = \Drupal::service('config.typed')->get('config_test.dynamic.third_party')->get('third_party_settings.config_schema_test'); $definition = $test->getDataDefinition()->toArray(); $expected = array(); diff --git a/core/modules/config/tests/config_schema_test/config/install/config_schema_test.schema_in_install.yml b/core/modules/config/tests/config_schema_test/config/install/config_schema_test.schema_in_install.yml deleted file mode 100644 index 2ae0ace..0000000 --- a/core/modules/config/tests/config_schema_test/config/install/config_schema_test.schema_in_install.yml +++ /dev/null @@ -1 +0,0 @@ -integer: '1' 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 7c18496..a41dd39 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 @@ -125,14 +125,6 @@ config_schema_test.schema_data_types: sequence: - type: boolean -config_schema_test.schema_in_install: - label: 'Schema test data with parenting' - type: config_object - mapping: - integer: - type: integer - label: 'Integer' - config_schema_test_integer: type: integer label: 'Config test integer' diff --git a/core/modules/config/tests/config_test/config/install/config_test.types.yml b/core/modules/config/tests/config_test/config/install/config_test.types.yml index 060a2b0..6c27522 100644 --- a/core/modules/config/tests/config_test/config/install/config_test.types.yml +++ b/core/modules/config/tests/config_test/config/install/config_test.types.yml @@ -2,7 +2,7 @@ array: [] boolean: true exp: 1.2e+34 float: 3.14159 -float_as_integer: 1 +float_as_integer: !!float 1 hex: 0xC int: 99 octal: 0775 diff --git a/core/modules/config/tests/config_test/config/optional/config_test.dynamic.override.yml b/core/modules/config/tests/config_test/config/optional/config_test.dynamic.override.yml index 9721190..af26b07 100644 --- a/core/modules/config/tests/config_test/config/optional/config_test.dynamic.override.yml +++ b/core/modules/config/tests/config_test/config/optional/config_test.dynamic.override.yml @@ -3,4 +3,4 @@ id: override label: Default weight: 0 protected_property: Default -status: 1 +status: true diff --git a/core/modules/config/tests/config_test/config/optional/config_test.dynamic.override_unmet.yml b/core/modules/config/tests/config_test/config/optional/config_test.dynamic.override_unmet.yml index 7fa7ae4..82a9c3c 100644 --- a/core/modules/config/tests/config_test/config/optional/config_test.dynamic.override_unmet.yml +++ b/core/modules/config/tests/config_test/config/optional/config_test.dynamic.override_unmet.yml @@ -4,7 +4,7 @@ id: override_unmet label: Default weight: 0 protected_property: Default -status: 1 +status: true dependencies: module: - tour diff --git a/core/modules/contact/src/Entity/ContactForm.php b/core/modules/contact/src/Entity/ContactForm.php index c0cf26a..0967c90 100644 --- a/core/modules/contact/src/Entity/ContactForm.php +++ b/core/modules/contact/src/Entity/ContactForm.php @@ -36,6 +36,13 @@ * "delete-form" = "/admin/structure/contact/manage/{contact_form}/delete", * "edit-form" = "/admin/structure/contact/manage/{contact_form}", * "collection" = "/admin/structure/contact", + * }, + * config_export = { + * "id", + * "label", + * "recipients", + * "reply", + * "weight", * } * ) */ diff --git a/core/modules/editor/src/Entity/Editor.php b/core/modules/editor/src/Entity/Editor.php index 60cdf5a..159c9b1 100644 --- a/core/modules/editor/src/Entity/Editor.php +++ b/core/modules/editor/src/Entity/Editor.php @@ -18,6 +18,12 @@ * label = @Translation("Text Editor"), * entity_keys = { * "id" = "format" + * }, + * config_export = { + * "format", + * "editor", + * "settings", + * "image_upload", * } * ) */ diff --git a/core/modules/field/src/Entity/FieldConfig.php b/core/modules/field/src/Entity/FieldConfig.php index d7f2dd0..296d618 100644 --- a/core/modules/field/src/Entity/FieldConfig.php +++ b/core/modules/field/src/Entity/FieldConfig.php @@ -28,6 +28,20 @@ * entity_keys = { * "id" = "id", * "label" = "label" + * }, + * config_export = { + * "id", + * "field_name", + * "entity_type", + * "bundle", + * "label", + * "description", + * "required", + * "translatable", + * "default_value", + * "default_value_callback", + * "settings", + * "field_type", * } * ) */ diff --git a/core/modules/field/src/Entity/FieldStorageConfig.php b/core/modules/field/src/Entity/FieldStorageConfig.php index ca77119..97db63f 100644 --- a/core/modules/field/src/Entity/FieldStorageConfig.php +++ b/core/modules/field/src/Entity/FieldStorageConfig.php @@ -30,6 +30,19 @@ * entity_keys = { * "id" = "id", * "label" = "id" + * }, + * config_export = { + * "id", + * "field_name", + * "entity_type", + * "type", + * "settings", + * "module", + * "locked", + * "cardinality", + * "translatable", + * "indexes", + * "persist_with_no_fields", * } * ) */ diff --git a/core/modules/field/tests/src/Unit/FieldConfigEntityUnitTest.php b/core/modules/field/tests/src/Unit/FieldConfigEntityUnitTest.php index 49d34e2..2bce97d 100644 --- a/core/modules/field/tests/src/Unit/FieldConfigEntityUnitTest.php +++ b/core/modules/field/tests/src/Unit/FieldConfigEntityUnitTest.php @@ -22,7 +22,7 @@ class FieldConfigEntityUnitTest extends UnitTestCase { /** * The entity type used for testing. * - * @var \Drupal\Core\Entity\EntityTypeInterface|\PHPUnit_Framework_MockObject_MockObject + * @var \Drupal\Core\Config\Entity\ConfigEntityTypeInterface|\PHPUnit_Framework_MockObject_MockObject */ protected $entityType; diff --git a/core/modules/field/tests/src/Unit/FieldStorageConfigEntityUnitTest.php b/core/modules/field/tests/src/Unit/FieldStorageConfigEntityUnitTest.php index cd05b9b..424424a 100644 --- a/core/modules/field/tests/src/Unit/FieldStorageConfigEntityUnitTest.php +++ b/core/modules/field/tests/src/Unit/FieldStorageConfigEntityUnitTest.php @@ -19,13 +19,6 @@ class FieldStorageConfigEntityUnitTest extends UnitTestCase { /** - * The entity type used for testing. - * - * @var \Drupal\Core\Entity\EntityTypeInterface|\PHPUnit_Framework_MockObject_MockObject - */ - protected $entityType; - - /** * The entity manager used for testing. * * @var \Drupal\Core\Entity\EntityManagerInterface|\PHPUnit_Framework_MockObject_MockObject @@ -64,7 +57,7 @@ protected function setUp() { */ public function testCalculateDependencies() { // Create a mock entity type for FieldStorageConfig. - $fieldStorageConfigentityType = $this->getMock('\Drupal\Core\Entity\EntityTypeInterface'); + $fieldStorageConfigentityType = $this->getMock('\Drupal\Core\Config\Entity\ConfigEntityTypeInterface'); $fieldStorageConfigentityType->expects($this->any()) ->method('getProvider') ->will($this->returnValue('field')); diff --git a/core/modules/file/config/optional/views.view.files.yml b/core/modules/file/config/optional/views.view.files.yml index 23bfd82..fc1b540 100644 --- a/core/modules/file/config/optional/views.view.files.yml +++ b/core/modules/file/config/optional/views.view.files.yml @@ -236,7 +236,7 @@ display: delta_first_last: false multi_type: separator separator: ', ' - field_api_classes: 0 + field_api_classes: false plugin_id: field entity_type: file entity_field: filename diff --git a/core/modules/filter/src/Entity/FilterFormat.php b/core/modules/filter/src/Entity/FilterFormat.php index 6df0f97..cf61f7f 100644 --- a/core/modules/filter/src/Entity/FilterFormat.php +++ b/core/modules/filter/src/Entity/FilterFormat.php @@ -41,6 +41,13 @@ * links = { * "edit-form" = "/admin/config/content/formats/manage/{filter_format}", * "disable" = "/admin/config/content/formats/manage/{filter_format}/disable" + * }, + * config_export = { + * "name", + * "format", + * "weight", + * "roles", + * "filters", * } * ) */ diff --git a/core/modules/forum/config/install/node.type.forum.yml b/core/modules/forum/config/install/node.type.forum.yml index 8ed965d..b03afe0 100644 --- a/core/modules/forum/config/install/node.type.forum.yml +++ b/core/modules/forum/config/install/node.type.forum.yml @@ -1,6 +1,8 @@ langcode: en status: true dependencies: + module: + - forum enforced: module: - forum diff --git a/core/modules/forum/config/install/taxonomy.vocabulary.forums.yml b/core/modules/forum/config/install/taxonomy.vocabulary.forums.yml index 951e4a3..cfbcca5 100644 --- a/core/modules/forum/config/install/taxonomy.vocabulary.forums.yml +++ b/core/modules/forum/config/install/taxonomy.vocabulary.forums.yml @@ -1,6 +1,8 @@ langcode: en status: true dependencies: + module: + - forum enforced: module: - forum diff --git a/core/modules/image/src/Entity/ImageStyle.php b/core/modules/image/src/Entity/ImageStyle.php index a3c7ab5..a05d3a8 100644 --- a/core/modules/image/src/Entity/ImageStyle.php +++ b/core/modules/image/src/Entity/ImageStyle.php @@ -48,6 +48,11 @@ * "edit-form" = "/admin/config/media/image-styles/manage/{image_style}", * "delete-form" = "/admin/config/media/image-styles/manage/{image_style}/delete", * "collection" = "/admin/config/media/image-styles", + * }, + * config_export = { + * "name", + * "label", + * "effects", * } * ) */ diff --git a/core/modules/language/src/Config/LanguageConfigOverride.php b/core/modules/language/src/Config/LanguageConfigOverride.php index 5be48ad..b673f34 100644 --- a/core/modules/language/src/Config/LanguageConfigOverride.php +++ b/core/modules/language/src/Config/LanguageConfigOverride.php @@ -50,13 +50,16 @@ public function __construct($name, StorageInterface $storage, TypedConfigManager /** * {@inheritdoc} */ - public function save() { - // @todo Use configuration schema to validate. - // https://drupal.org/node/2270399 - // Perform basic data validation. - foreach ($this->data as $key => $value) { - $this->validateValue($key, $value); + public function save($has_trusted_data = FALSE) { + if (!$has_trusted_data) { + // @todo Use configuration schema to validate. + // https://drupal.org/node/2270399 + // Perform basic data validation. + foreach ($this->data as $key => $value) { + $this->validateValue($key, $value); + } } + $this->storage->write($this->name, $this->data); // Invalidate the cache tags not only when updating, but also when creating, // because a language config override object uses the same cache tag as the diff --git a/core/modules/node/config/install/system.action.node_promote_action.yml b/core/modules/node/config/install/system.action.node_promote_action.yml index b1b4f05..4b3a9ae 100644 --- a/core/modules/node/config/install/system.action.node_promote_action.yml +++ b/core/modules/node/config/install/system.action.node_promote_action.yml @@ -4,3 +4,6 @@ status: true langcode: en type: node plugin: node_promote_action +dependencies: + module: + - node diff --git a/core/modules/node/config/install/system.action.node_publish_action.yml b/core/modules/node/config/install/system.action.node_publish_action.yml index e882bf3..af0b82c 100644 --- a/core/modules/node/config/install/system.action.node_publish_action.yml +++ b/core/modules/node/config/install/system.action.node_publish_action.yml @@ -4,3 +4,6 @@ status: true langcode: en type: node plugin: node_publish_action +dependencies: + module: + - node diff --git a/core/modules/node/src/Entity/NodeType.php b/core/modules/node/src/Entity/NodeType.php index 238ae8f..2d8ac15 100644 --- a/core/modules/node/src/Entity/NodeType.php +++ b/core/modules/node/src/Entity/NodeType.php @@ -37,6 +37,15 @@ * "edit-form" = "/admin/structure/types/manage/{node_type}", * "delete-form" = "/admin/structure/types/manage/{node_type}/delete", * "collection" = "/admin/structure/types", + * }, + * config_export = { + * "name", + * "type", + * "description", + * "help", + * "new_revision", + * "preview_mode", + * "display_submitted", * } * ) */ diff --git a/core/modules/options/src/Plugin/Field/FieldType/ListFloatItem.php b/core/modules/options/src/Plugin/Field/FieldType/ListFloatItem.php index 8fd6e29..9ce7cb0 100644 --- a/core/modules/options/src/Plugin/Field/FieldType/ListFloatItem.php +++ b/core/modules/options/src/Plugin/Field/FieldType/ListFloatItem.php @@ -110,4 +110,11 @@ public static function simplifyAllowedValues(array $structured_values) { return $values; } + /** + * {@inheritdoc} + */ + protected static function castAllowedValue($value) { + return (float) $value; + } + } diff --git a/core/modules/options/src/Plugin/Field/FieldType/ListIntegerItem.php b/core/modules/options/src/Plugin/Field/FieldType/ListIntegerItem.php index 5992386..2ded4ca 100644 --- a/core/modules/options/src/Plugin/Field/FieldType/ListIntegerItem.php +++ b/core/modules/options/src/Plugin/Field/FieldType/ListIntegerItem.php @@ -73,4 +73,11 @@ protected static function validateAllowedValue($option) { } } + /** + * {@inheritdoc} + */ + protected static function castAllowedValue($value) { + return (int) $value; + } + } diff --git a/core/modules/options/src/Plugin/Field/FieldType/ListItemBase.php b/core/modules/options/src/Plugin/Field/FieldType/ListItemBase.php index bdf063a..9b785d8 100644 --- a/core/modules/options/src/Plugin/Field/FieldType/ListItemBase.php +++ b/core/modules/options/src/Plugin/Field/FieldType/ListItemBase.php @@ -314,11 +314,24 @@ protected static function structureAllowedValues(array $values) { $label = static::structureAllowedValues($label); } $structured_values[] = array( - 'value' => $value, + 'value' => static::castAllowedValue($value), 'label' => $label, ); } return $structured_values; } + /** + * Converts a value to the correct type. + * + * @param mixed $value + * The value to cast. + * + * @return mixed + * The casted value. + */ + protected static function castAllowedValue($value) { + return $value; + } + } diff --git a/core/modules/options/src/Plugin/Field/FieldType/ListStringItem.php b/core/modules/options/src/Plugin/Field/FieldType/ListStringItem.php index f3bf401..da30810 100644 --- a/core/modules/options/src/Plugin/Field/FieldType/ListStringItem.php +++ b/core/modules/options/src/Plugin/Field/FieldType/ListStringItem.php @@ -75,4 +75,11 @@ protected static function validateAllowedValue($option) { } } + /** + * {@inheritdoc} + */ + protected static function castAllowedValue($value) { + return (string) $value; + } + } diff --git a/core/modules/options/tests/options_config_install_test/config/install/field.storage.node.field_options_float.yml b/core/modules/options/tests/options_config_install_test/config/install/field.storage.node.field_options_float.yml index f355b2e..1d02c61 100644 --- a/core/modules/options/tests/options_config_install_test/config/install/field.storage.node.field_options_float.yml +++ b/core/modules/options/tests/options_config_install_test/config/install/field.storage.node.field_options_float.yml @@ -11,7 +11,7 @@ type: list_float settings: allowed_values: - - value: 0 + value: !!float 0 label: Zero - value: 0.5 diff --git a/core/modules/rdf/src/Entity/RdfMapping.php b/core/modules/rdf/src/Entity/RdfMapping.php index 577cbe7..0a32009 100644 --- a/core/modules/rdf/src/Entity/RdfMapping.php +++ b/core/modules/rdf/src/Entity/RdfMapping.php @@ -20,6 +20,13 @@ * config_prefix = "mapping", * entity_keys = { * "id" = "id" + * }, + * config_export = { + * "id", + * "targetEntityType", + * "bundle", + * "types", + * "fieldMappings", * } * ) */ diff --git a/core/modules/search/src/Entity/SearchPage.php b/core/modules/search/src/Entity/SearchPage.php index 0f583c7..fcce23d 100644 --- a/core/modules/search/src/Entity/SearchPage.php +++ b/core/modules/search/src/Entity/SearchPage.php @@ -47,6 +47,14 @@ * "label" = "label", * "weight" = "weight", * "status" = "status" + * }, + * config_export = { + * "id", + * "label", + * "path", + * "weight", + * "plugin", + * "configuration", * } * ) */ diff --git a/core/modules/shortcut/shortcut.install b/core/modules/shortcut/shortcut.install index c1a6883..b046142 100644 --- a/core/modules/shortcut/shortcut.install +++ b/core/modules/shortcut/shortcut.install @@ -53,7 +53,7 @@ function shortcut_install() { // Theme settings are not configuration entities and cannot depend on modules // so to set a module-specific setting, we need to set it with logic. if (\Drupal::service('theme_handler')->themeExists('seven')) { - \Drupal::configFactory()->getEditable('seven.settings')->set('third_party_settings.shortcut.module_link', TRUE)->save(); + \Drupal::configFactory()->getEditable('seven.settings')->set('third_party_settings.shortcut.module_link', TRUE)->save(TRUE); } } @@ -64,6 +64,6 @@ function shortcut_uninstall() { // Theme settings are not configuration entities and cannot depend on modules // so to unset a module-specific setting, we need to unset it with logic. if (\Drupal::service('theme_handler')->themeExists('seven')) { - \Drupal::configFactory()->getEditable('seven.settings')->clear('third_party_settings.shortcut.module_link')->save(); + \Drupal::configFactory()->getEditable('seven.settings')->clear('third_party_settings.shortcut.module_link')->save(TRUE); } } diff --git a/core/modules/shortcut/shortcut.module b/core/modules/shortcut/shortcut.module index af62bac..abab6ce 100644 --- a/core/modules/shortcut/shortcut.module +++ b/core/modules/shortcut/shortcut.module @@ -415,7 +415,7 @@ function shortcut_themes_installed($theme_list) { // Theme settings are not configuration entities and cannot depend on modules // so to set a module-specific setting, we need to set it with logic. if (\Drupal::moduleHandler()->moduleExists('shortcut')) { - \Drupal::configFactory()->getEditable('seven.settings')->set('third_party_settings.shortcut.module_link', TRUE)->save(); + \Drupal::configFactory()->getEditable('seven.settings')->set('third_party_settings.shortcut.module_link', TRUE)->save(TRUE); } } } diff --git a/core/modules/shortcut/src/Entity/ShortcutSet.php b/core/modules/shortcut/src/Entity/ShortcutSet.php index 692e3ab..52e3ecc 100644 --- a/core/modules/shortcut/src/Entity/ShortcutSet.php +++ b/core/modules/shortcut/src/Entity/ShortcutSet.php @@ -40,6 +40,10 @@ * "delete-form" = "/admin/config/user-interface/shortcut/manage/{shortcut_set}/delete", * "edit-form" = "/admin/config/user-interface/shortcut/manage/{shortcut_set}", * "collection" = "/admin/config/user-interface/shortcut", + * }, + * config_export = { + * "id", + * "label", * } * ) */ diff --git a/core/modules/system/src/Entity/Action.php b/core/modules/system/src/Entity/Action.php index ca3d8cf..b5a0f19 100644 --- a/core/modules/system/src/Entity/Action.php +++ b/core/modules/system/src/Entity/Action.php @@ -24,6 +24,13 @@ * entity_keys = { * "id" = "id", * "label" = "label" + * }, + * config_export = { + * "id", + * "label", + * "type", + * "plugin", + * "configuration", * } * ) */ diff --git a/core/modules/system/src/Entity/Menu.php b/core/modules/system/src/Entity/Menu.php index bf5d77d..fa738f3 100644 --- a/core/modules/system/src/Entity/Menu.php +++ b/core/modules/system/src/Entity/Menu.php @@ -24,6 +24,12 @@ * entity_keys = { * "id" = "id", * "label" = "label" + * }, + * config_export = { + * "id", + * "label", + * "description", + * "locked", * } * ) */ diff --git a/core/modules/system/system.install b/core/modules/system/system.install index f1e6612..082bbc6 100644 --- a/core/modules/system/system.install +++ b/core/modules/system/system.install @@ -665,7 +665,7 @@ function system_install() { if (!$site->get('name')) { $site->set('name', 'Drupal'); } - $site->save(); + $site->save(TRUE); } /** diff --git a/core/modules/system/tests/themes/test_basetheme/config/install/core.date_format.fancy.yml b/core/modules/system/tests/themes/test_basetheme/config/install/core.date_format.fancy.yml index 05d5e27..fc76e73 100644 --- a/core/modules/system/tests/themes/test_basetheme/config/install/core.date_format.fancy.yml +++ b/core/modules/system/tests/themes/test_basetheme/config/install/core.date_format.fancy.yml @@ -8,6 +8,8 @@ langcode: en locked: false pattern: 'U' dependencies: + theme: + - test_basetheme enforced: theme: - test_basetheme diff --git a/core/modules/taxonomy/src/Entity/Vocabulary.php b/core/modules/taxonomy/src/Entity/Vocabulary.php index 7b2def3..2855c65 100644 --- a/core/modules/taxonomy/src/Entity/Vocabulary.php +++ b/core/modules/taxonomy/src/Entity/Vocabulary.php @@ -41,6 +41,13 @@ * "overview-form" = "/admin/structure/taxonomy/manage/{taxonomy_vocabulary}/overview", * "edit-form" = "/admin/structure/taxonomy/manage/{taxonomy_vocabulary}", * "collection" = "/admin/structure/taxonomy", + * }, + * config_export = { + * "name", + * "vid", + * "description", + * "hierarchy", + * "weight", * } * ) */ diff --git a/core/modules/tour/src/Entity/Tour.php b/core/modules/tour/src/Entity/Tour.php index d50caa9..15357e0 100644 --- a/core/modules/tour/src/Entity/Tour.php +++ b/core/modules/tour/src/Entity/Tour.php @@ -24,6 +24,13 @@ * entity_keys = { * "id" = "id", * "label" = "label" + * }, + * config_export = { + * "id", + * "label", + * "module", + * "routes", + * "tips", * } * ) */ diff --git a/core/modules/user/config/optional/views.view.user_admin_people.yml b/core/modules/user/config/optional/views.view.user_admin_people.yml index 8be9b7e..004471c 100644 --- a/core/modules/user/config/optional/views.view.user_admin_people.yml +++ b/core/modules/user/config/optional/views.view.user_admin_people.yml @@ -567,7 +567,7 @@ display: delta_first_last: false multi_type: separator separator: ', ' - field_api_classes: 0 + field_api_classes: false plugin_id: field entity_type: user entity_field: mail diff --git a/core/modules/user/src/Entity/Role.php b/core/modules/user/src/Entity/Role.php index 9216ad8..b997e69 100644 --- a/core/modules/user/src/Entity/Role.php +++ b/core/modules/user/src/Entity/Role.php @@ -40,6 +40,13 @@ * "edit-form" = "/admin/people/roles/manage/{user_role}", * "edit-permissions-form" = "/admin/people/permissions/{user_role}", * "collection" = "/admin/people/roles", + * }, + * config_export = { + * "id", + * "label", + * "weight", + * "is_admin", + * "permissions", * } * ) */ diff --git a/core/modules/user/user.module b/core/modules/user/user.module index 07c84d0..5ad2876 100644 --- a/core/modules/user/user.module +++ b/core/modules/user/user.module @@ -982,7 +982,7 @@ function user_user_role_insert(RoleInterface $role) { ), 'plugin' => 'user_add_role_action', )); - $action->save(); + $action->trustData()->save(); } $remove_id = 'user_remove_role_action.' . $role->id(); if (!entity_load('action', $remove_id)) { @@ -995,7 +995,7 @@ function user_user_role_insert(RoleInterface $role) { ), 'plugin' => 'user_remove_role_action', )); - $action->save(); + $action->trustData()->save(); } } @@ -1140,7 +1140,7 @@ function user_role_grant_permissions($rid, array $permissions = array()) { foreach ($permissions as $permission) { $role->grantPermission($permission); } - $role->save(); + $role->trustData()->save(); } } @@ -1161,7 +1161,7 @@ function user_role_revoke_permissions($rid, array $permissions = array()) { foreach ($permissions as $permission) { $role->revokePermission($permission); } - $role->save(); + $role->trustData()->save(); } /** diff --git a/core/modules/views/src/Entity/View.php b/core/modules/views/src/Entity/View.php index 34b4ab0..b7188c5 100644 --- a/core/modules/views/src/Entity/View.php +++ b/core/modules/views/src/Entity/View.php @@ -29,6 +29,17 @@ * "id" = "id", * "label" = "label", * "status" = "status" + * }, + * config_export = { + * "id", + * "label", + * "module", + * "description", + * "tag", + * "base_table", + * "base_field", + * "core", + * "display", * } * ) */ diff --git a/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php b/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php index a45d39a..d683426 100644 --- a/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php +++ b/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php @@ -2293,7 +2293,7 @@ public function calculateCacheMetadata () { $cache_plugin->alterCacheMetadata($is_cacheable, $cache_contexts); } - return [$is_cacheable, $cache_contexts]; + return [(bool) $is_cacheable, $cache_contexts]; } /** diff --git a/core/modules/views_ui/src/ViewUI.php b/core/modules/views_ui/src/ViewUI.php index 8b5569e..75bbbdf 100644 --- a/core/modules/views_ui/src/ViewUI.php +++ b/core/modules/views_ui/src/ViewUI.php @@ -1285,4 +1285,18 @@ public function getThirdPartyProviders() { return $this->storage->getThirdPartyProviders(); } + /** + * {@inheritdoc} + */ + public function trustData() { + return $this->storage->trustData(); + } + + /** + * {@inheritdoc} + */ + public function hasTrustedData() { + return $this->storage->hasTrustedData(); + } + } diff --git a/core/profiles/minimal/minimal.install b/core/profiles/minimal/minimal.install index a8baf07..d30cb3b 100644 --- a/core/profiles/minimal/minimal.install +++ b/core/profiles/minimal/minimal.install @@ -13,8 +13,8 @@ */ function minimal_install() { // Disable the user pictures on nodes. - \Drupal::configFactory()->getEditable('system.theme.global')->set('features.node_user_picture', FALSE)->save(); + \Drupal::configFactory()->getEditable('system.theme.global')->set('features.node_user_picture', FALSE)->save(TRUE); // Allow visitor account creation, but with administrative approval. - \Drupal::configFactory()->getEditable('user.settings')->set('register', USER_REGISTER_VISITORS_ADMINISTRATIVE_APPROVAL)->save(); + \Drupal::configFactory()->getEditable('user.settings')->set('register', USER_REGISTER_VISITORS_ADMINISTRATIVE_APPROVAL)->save(TRUE); } diff --git a/core/profiles/standard/standard.install b/core/profiles/standard/standard.install index b5e2b63..000ffa4 100644 --- a/core/profiles/standard/standard.install +++ b/core/profiles/standard/standard.install @@ -23,11 +23,11 @@ function standard_install() { \Drupal::service('entity.definition_update_manager')->applyUpdates(); // Set front page to "node". - \Drupal::configFactory()->getEditable('system.site')->set('page.front', 'node')->save(); + \Drupal::configFactory()->getEditable('system.site')->set('page.front', 'node')->save(TRUE); // Allow visitor account creation with administrative approval. $user_settings = \Drupal::configFactory()->getEditable('user.settings'); - $user_settings->set('register', USER_REGISTER_VISITORS_ADMINISTRATIVE_APPROVAL)->save(); + $user_settings->set('register', USER_REGISTER_VISITORS_ADMINISTRATIVE_APPROVAL)->save(TRUE); // Enable default permissions for system roles. user_role_grant_permissions(RoleInterface::ANONYMOUS_ID, array('access comments')); @@ -41,7 +41,7 @@ function standard_install() { // Enable the Contact link in the footer menu. /** @var \Drupal\Core\Menu\MenuLinkManagerInterface $menu_link_manager */ $menu_link_manager = \Drupal::service('plugin.manager.menu.link'); - $menu_link_manager->updateDefinition('contact.site_page', array('enabled' => 1)); + $menu_link_manager->updateDefinition('contact.site_page', array('enabled' => TRUE)); user_role_grant_permissions(RoleInterface::ANONYMOUS_ID, array('access site-wide contact form')); user_role_grant_permissions(RoleInterface::AUTHENTICATED_ID, array('access site-wide contact form')); @@ -67,5 +67,5 @@ function standard_install() { $shortcut->save(); // Enable the admin theme. - \Drupal::configFactory()->getEditable('node.settings')->set('use_admin_theme', '1')->save(); + \Drupal::configFactory()->getEditable('node.settings')->set('use_admin_theme', TRUE)->save(TRUE); } diff --git a/core/profiles/standard/standard.profile b/core/profiles/standard/standard.profile index ad69906..030b92a 100644 --- a/core/profiles/standard/standard.profile +++ b/core/profiles/standard/standard.profile @@ -23,5 +23,5 @@ function standard_form_install_configure_form_alter(&$form, FormStateInterface $ */ function standard_form_install_configure_submit($form, FormStateInterface $form_state) { $site_mail = $form_state->getValue('site_mail'); - ContactForm::load('feedback')->setRecipients([$site_mail])->save(); + ContactForm::load('feedback')->setRecipients([$site_mail])->trustData()->save(); } diff --git a/core/profiles/testing_config_overrides/config/optional/config_test.dynamic.override.yml b/core/profiles/testing_config_overrides/config/optional/config_test.dynamic.override.yml index 4a54a33..e0d67e0 100644 --- a/core/profiles/testing_config_overrides/config/optional/config_test.dynamic.override.yml +++ b/core/profiles/testing_config_overrides/config/optional/config_test.dynamic.override.yml @@ -2,7 +2,7 @@ id: override label: Override weight: 0 protected_property: Default -status: 1 +status: true dependencies: module: - tour diff --git a/core/profiles/testing_config_overrides/config/optional/config_test.dynamic.override_unmet.yml b/core/profiles/testing_config_overrides/config/optional/config_test.dynamic.override_unmet.yml index f20365f..d4e755d 100644 --- a/core/profiles/testing_config_overrides/config/optional/config_test.dynamic.override_unmet.yml +++ b/core/profiles/testing_config_overrides/config/optional/config_test.dynamic.override_unmet.yml @@ -2,7 +2,7 @@ id: override_unmet label: Override weight: 0 protected_property: Default -status: 1 +status: true dependencies: module: - dblog diff --git a/core/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityBaseUnitTest.php b/core/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityBaseUnitTest.php index a0e043b..5e11828 100644 --- a/core/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityBaseUnitTest.php +++ b/core/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityBaseUnitTest.php @@ -28,7 +28,7 @@ class ConfigEntityBaseUnitTest extends UnitTestCase { /** * The entity type used for testing. * - * @var \Drupal\Core\Entity\EntityTypeInterface|\PHPUnit_Framework_MockObject_MockObject + * @var \Drupal\Core\Config\Entity\ConfigEntityTypeInterface|\PHPUnit_Framework_MockObject_MockObject */ protected $entityType; @@ -463,9 +463,51 @@ public function testSort() { * @covers ::toArray */ public function testToArray() { + $this->typedConfigManager->expects($this->never()) + ->method('getDefinition'); + $this->entityType->expects($this->any()) + ->method('getPropertiesToExport') + ->willReturn(['id' => 'configId', 'dependencies' => 'dependencies']); + $properties = $this->entity->toArray(); + $this->assertInternalType('array', $properties); + $this->assertEquals(array('configId' => $this->entity->id(), 'dependencies' => array()), $properties); + } + + /** + * @covers ::toArray + */ + public function testToArrayIdKey() { + $entity = $this->getMockForAbstractClass('\Drupal\Core\Config\Entity\ConfigEntityBase', [[], $this->entityTypeId], '', TRUE, TRUE, TRUE, ['id', 'get']); + $entity->expects($this->exactly(3)) + ->method('id') + ->willReturn($this->id); + $entity->expects($this->once()) + ->method('get') + ->willReturn([]); + $this->typedConfigManager->expects($this->never()) + ->method('getDefinition'); + $this->entityType->expects($this->any()) + ->method('getPropertiesToExport') + ->willReturn(['id' => 'configId', 'dependencies' => 'dependencies']); + $this->entityType->expects($this->once()) + ->method('getKey') + ->with('id') + ->willReturn('id'); + $properties = $entity->toArray(); + $this->assertInternalType('array', $properties); + $this->assertEquals(['configId' => $entity->id(), 'dependencies' => []], $properties); + } + + /** + * @covers ::toArray + */ + public function testToArraySchemaFallback() { $this->typedConfigManager->expects($this->once()) ->method('getDefinition') ->will($this->returnValue(array('mapping' => array('id' => '', 'dependencies' => '')))); + $this->entityType->expects($this->any()) + ->method('getPropertiesToExport') + ->willReturn([]); $properties = $this->entity->toArray(); $this->assertInternalType('array', $properties); $this->assertEquals(array('id' => $this->entity->id(), 'dependencies' => array()), $properties); @@ -477,6 +519,9 @@ public function testToArray() { * @expectedException \Drupal\Core\Config\Schema\SchemaIncompleteException */ public function testToArrayFallback() { + $this->entityType->expects($this->any()) + ->method('getPropertiesToExport') + ->willReturn([]); $this->entity->toArray(); } diff --git a/core/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityStorageTest.php b/core/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityStorageTest.php index 12096ba..e0083e4 100644 --- a/core/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityStorageTest.php +++ b/core/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityStorageTest.php @@ -22,7 +22,7 @@ class ConfigEntityStorageTest extends UnitTestCase { /** * The entity type. * - * @var \Drupal\Core\Entity\EntityTypeInterface|\PHPUnit_Framework_MockObject_MockObject + * @var \Drupal\Core\Config\Entity\ConfigEntityTypeInterface|\PHPUnit_Framework_MockObject_MockObject */ protected $entityType; diff --git a/core/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityTypeTest.php b/core/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityTypeTest.php index b427dfc..524fea0 100644 --- a/core/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityTypeTest.php +++ b/core/tests/Drupal/Tests/Core/Config/Entity/ConfigEntityTypeTest.php @@ -131,4 +131,60 @@ public function providerTestGetConfigPrefix() { ); } + /** + * @covers ::getPropertiesToExport + * + * @dataProvider providerGetPropertiesToExport + */ + public function testGetPropertiesToExport($definition, $expected) { + $entity_type = $this->setUpConfigEntityType($definition); + $properties_to_export = $entity_type->getPropertiesToExport(); + $this->assertSame($expected, $properties_to_export); + + // Ensure the method is idempotent. + $properties_to_export = $entity_type->getPropertiesToExport(); + $this->assertSame($expected, $properties_to_export); + } + + public function providerGetPropertiesToExport() { + $data = []; + $data[] = [ + [], + NULL, + ]; + + $data[] = [ + [ + 'config_export' => [ + 'id', + 'custom_property' => 'customProperty', + ], + ], + [ + 'uuid' => 'uuid', + 'langcode' => 'langcode', + 'status' => 'status', + 'dependencies' => 'dependencies', + 'third_party_settings' => 'third_party_settings', + 'id' => 'id', + 'custom_property' => 'customProperty', + ], + ]; + + $data[] = [ + [ + 'config_export' => [ + 'id', + ], + 'mergedConfigExport' => [ + 'random_key' => 'random_key', + ], + ], + [ + 'random_key' => 'random_key', + ], + ]; + return $data; + } + } diff --git a/core/tests/Drupal/Tests/Core/Menu/StaticMenuLinkOverridesTest.php b/core/tests/Drupal/Tests/Core/Menu/StaticMenuLinkOverridesTest.php index 3f60933..32d0b3a 100644 --- a/core/tests/Drupal/Tests/Core/Menu/StaticMenuLinkOverridesTest.php +++ b/core/tests/Drupal/Tests/Core/Menu/StaticMenuLinkOverridesTest.php @@ -114,11 +114,15 @@ public function testSaveOverride() { ->with('definitions') ->will($this->returnValue(array())); - $definition_save_1 = array('definitions' => array('test1' => array('parent' => 'test0'))); + $definition_save_1 = array( + 'definitions' => array( + 'test1' => array('parent' => 'test0', 'menu_name' => '', 'weight' => 0, 'expanded' => FALSE, 'enabled' => FALSE) + ) + ); $definitions_save_2 = array( 'definitions' => array( - 'test1' => array('parent' => 'test0'), - 'test1__la___ma' => array('parent' => 'test1') + 'test1' => array('parent' => 'test0', 'menu_name' => '', 'weight' => 0, 'expanded' => FALSE, 'enabled' => FALSE), + 'test1__la___ma' => array('parent' => 'test1', 'menu_name' => '', 'weight' => 0, 'expanded' => FALSE, 'enabled' => FALSE) ) ); $config->expects($this->at(2))