diff --git a/core/lib/Drupal/Core/Config/Schema/SchemaCheckTrait.php b/core/lib/Drupal/Core/Config/Schema/SchemaCheckTrait.php index f2974e3a6361e5815d7b47ef555c77eb972a5bd0..3adb9075ad68013e30dcc373d93737fb26b04b59 100644 --- a/core/lib/Drupal/Core/Config/Schema/SchemaCheckTrait.php +++ b/core/lib/Drupal/Core/Config/Schema/SchemaCheckTrait.php @@ -52,6 +52,13 @@ trait SchemaCheckTrait { 'This value should not be blank.', ], ], + 'contact.settings' => [ + // @todo Simple config cannot have dependencies on any other config. + // Remove this in https://www.drupal.org/project/drupal/issues/3425992. + 'default_form' => [ + "The 'contact.form.feedback' config does not exist.", + ], + ], 'editor.editor.*' => [ // @todo Fix stream wrappers not being available early enough in // https://www.drupal.org/project/drupal/issues/3416735 diff --git a/core/modules/contact/config/schema/contact.schema.yml b/core/modules/contact/config/schema/contact.schema.yml index 4357a426219f5c3e14d82e638eda49f4941814d2..4617e47e7603c71be579d9edb903266d39735ac6 100644 --- a/core/modules/contact/config/schema/contact.schema.yml +++ b/core/modules/contact/config/schema/contact.schema.yml @@ -37,20 +37,35 @@ contact.form.*: contact.settings: type: config_object label: 'Contact settings' + constraints: + FullyValidatable: ~ mapping: default_form: type: string label: 'Default form identifier' + # It is possible to not configure a default form. + # @see \Drupal\contact\ContactFormEditForm::save() + nullable: true + constraints: + ConfigExists: + prefix: contact.form. flood: + # @see \Drupal\Core\Flood\FloodInterface::isAllowed() type: mapping label: 'Flood control' mapping: limit: type: integer - label: 'Limit' + label: 'Limit (messages per interval)' + constraints: + Range: + min: 1 interval: type: integer - label: 'Interval' + label: 'Interval (seconds)' + constraints: + Range: + min: 1 user_default_enabled: type: boolean label: 'Personal contact form enabled by default' diff --git a/core/modules/contact/contact.post_update.php b/core/modules/contact/contact.post_update.php index fcb12edb46a8fef76d30cf43104849ff4d5b03b5..ebdc0d7d0f02d051eb40f556ee8e6ec1ae6105d8 100644 --- a/core/modules/contact/contact.post_update.php +++ b/core/modules/contact/contact.post_update.php @@ -13,3 +13,15 @@ function contact_removed_post_updates() { 'contact_post_update_add_message_redirect_field_to_contact_form' => '9.0.0', ]; } + +/** + * Converts empty `default_form` in settings to NULL. + */ +function contact_post_update_set_empty_default_form_to_null(): void { + $config = \Drupal::configFactory()->getEditable('contact.settings'); + // 'default_form' in 'contact.settings' config must be stored as NULL if it + // is empty. + if ($config->get('default_form') === '') { + $config->set('default_form', NULL)->save(); + } +} diff --git a/core/modules/contact/migrations/d6_contact_settings.yml b/core/modules/contact/migrations/d6_contact_settings.yml index a91a9fb1bbdf7297fb7f6563dea31307f624ae87..35e64f5591f0174daca50755ff639f3fbf3e9bc4 100644 --- a/core/modules/contact/migrations/d6_contact_settings.yml +++ b/core/modules/contact/migrations/d6_contact_settings.yml @@ -11,6 +11,11 @@ source: process: user_default_enabled: contact_default_status 'flood/limit': contact_hourly_threshold + 'flood/interval': + plugin: default_value + # It was defaulted to 3600 in D6. + # @see https://api.drupal.org/api/drupal/includes%21common.inc/function/flood_is_allowed/6.x + default_value: 3600 default_form: plugin: migration_lookup migration: contact_category diff --git a/core/modules/contact/migrations/d7_contact_settings.yml b/core/modules/contact/migrations/d7_contact_settings.yml index 282064630c3e9a66d7e165975f777321ee34137e..166e9c307a27b46e5f0291964b8d47f04cd40f5a 100644 --- a/core/modules/contact/migrations/d7_contact_settings.yml +++ b/core/modules/contact/migrations/d7_contact_settings.yml @@ -11,6 +11,11 @@ source: process: user_default_enabled: contact_default_status 'flood/limit': contact_threshold_limit + 'flood/interval': + plugin: default_value + # It was defaulted to 3600 in D7. + # @see https://api.drupal.org/api/drupal/includes%21common.inc/function/flood_is_allowed/7.x + default_value: 3600 default_form: plugin: migration_lookup migration: contact_category diff --git a/core/modules/contact/src/Controller/ContactController.php b/core/modules/contact/src/Controller/ContactController.php index 79ac3f053a09f1fa76833cc98c2541d23dab079a..67b1b98c89b899c7d7344443a8a05f8b9e298657 100644 --- a/core/modules/contact/src/Controller/ContactController.php +++ b/core/modules/contact/src/Controller/ContactController.php @@ -50,9 +50,13 @@ public function contactSitePage(ContactFormInterface $contact_form = NULL) { // Use the default form if no form has been passed. if (empty($contact_form)) { - $contact_form = $this->entityTypeManager() - ->getStorage('contact_form') - ->load($config->get('default_form')); + $default_form = $config->get('default_form'); + // Load the default form, if configured. + if (!is_null($default_form)) { + $contact_form = $this->entityTypeManager() + ->getStorage('contact_form') + ->load($default_form); + } // If there are no forms, do not display the form. if (empty($contact_form)) { if ($this->currentUser()->hasPermission('administer contact forms')) { diff --git a/core/modules/contact/tests/src/Functional/ContactSitewideTest.php b/core/modules/contact/tests/src/Functional/ContactSitewideTest.php index fa1c94abf216644bc2e5b7d44ffc2cff67500c49..4b70da6490bc8d728de06a33d10ef64c0b17e07f 100644 --- a/core/modules/contact/tests/src/Functional/ContactSitewideTest.php +++ b/core/modules/contact/tests/src/Functional/ContactSitewideTest.php @@ -256,7 +256,7 @@ public function testSiteWideContact() { // Test contact form with no default form selected. $this->config('contact.settings') - ->set('default_form', '') + ->set('default_form', NULL) ->save(); $this->drupalGet('contact'); $this->assertSession()->statusCodeEquals(404); diff --git a/core/modules/contact/tests/src/Functional/Update/NullDefaultFormTest.php b/core/modules/contact/tests/src/Functional/Update/NullDefaultFormTest.php new file mode 100644 index 0000000000000000000000000000000000000000..4f825d831c2a857bbefd49f6a76d083358483c3e --- /dev/null +++ b/core/modules/contact/tests/src/Functional/Update/NullDefaultFormTest.php @@ -0,0 +1,36 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\Tests\contact\Functional\Update; + +use Drupal\FunctionalTests\Update\UpdatePathTestBase; + +/** + * Tests the upgrade path for making 'default_form' in 'contact.settings' config to NULL. + * + * @group contact + * @see contact_post_update_set_empty_default_form_to_null() + */ +class NullDefaultFormTest extends UpdatePathTestBase { + + /** + * {@inheritdoc} + */ + protected function setDatabaseDumpFiles() { + $this->databaseDumpFiles = [ + __DIR__ . '/../../../../../system/tests/fixtures/update/drupal-9.4.0.filled.standard.php.gz', + ]; + } + + /** + * Tests the upgrade path for updating empty 'default_form' to NULL. + */ + public function testRunUpdates(): void { + $this->config('contact.settings')->set('default_form', '')->save(); + $this->assertSame('', $this->config('contact.settings')->get('default_form')); + $this->runUpdates(); + $this->assertNull($this->config('contact.settings')->get('default_form')); + } + +}