diff --git a/core/lib/Drupal/Core/Form/FormCache.php b/core/lib/Drupal/Core/Form/FormCache.php index 7064e10fb9..9c931fdcae 100644 --- a/core/lib/Drupal/Core/Form/FormCache.php +++ b/core/lib/Drupal/Core/Form/FormCache.php @@ -8,6 +8,7 @@ use Drupal\Core\KeyValueStore\KeyValueExpirableFactoryInterface; use Drupal\Core\PageCache\RequestPolicyInterface; use Drupal\Core\Session\AccountInterface; +use Drupal\Core\Site\Settings; use Psr\Log\LoggerInterface; use Symfony\Component\HttpFoundation\RequestStack; @@ -170,8 +171,8 @@ protected function loadCachedFormState($form_build_id, FormStateInterface $form_ * {@inheritdoc} */ public function setCache($form_build_id, $form, FormStateInterface $form_state) { - // 6 hours cache life time for forms should be plenty. - $expire = 21600; + // Cache forms for 6 hours by default. + $expire = Settings::get('form_cache_expiration', 21600); // Ensure that the form build_id embedded in the form structure is the same // as the one passed in as a parameter. This is an additional safety measure diff --git a/core/tests/Drupal/KernelTests/Core/Form/FormCacheTest.php b/core/tests/Drupal/KernelTests/Core/Form/FormCacheTest.php index 6425a3099d..765dd43131 100644 --- a/core/tests/Drupal/KernelTests/Core/Form/FormCacheTest.php +++ b/core/tests/Drupal/KernelTests/Core/Form/FormCacheTest.php @@ -5,6 +5,7 @@ use Drupal\Core\Form\FormState; use Drupal\Core\Session\AnonymousUserSession; use Drupal\Core\Session\UserSession; +use Drupal\Core\Site\Settings; use Drupal\KernelTests\KernelTestBase; /** @@ -101,4 +102,16 @@ public function testNoCacheToken() { $account_switcher->switchBack(); } + /** + * Tests the form cache with an overridden cache expiration. + */ + public function testCacheCustomExpiration() { + // Override form cache expiration so that the cached form expired yesterday. + new Settings(['form_cache_expiration' => -1 * (24*60*60), 'hash_salt' => $this->randomMachineName()]); + \Drupal::formBuilder()->setCache($this->formBuildId, $this->form, $this->formState); + + $cached_form_state = new FormState(); + $this->assertFalse(\Drupal::formBuilder()->getCache($this->formBuildId, $cached_form_state), 'Expired form not returned from cache'); + } + } diff --git a/sites/default/default.settings.php b/sites/default/default.settings.php index 1720d11e43..c7dd194350 100644 --- a/sites/default/default.settings.php +++ b/sites/default/default.settings.php @@ -440,6 +440,15 @@ */ # $settings['cache_ttl_4xx'] = 3600; +/** + * Expiration of cached forms. + * + * Drupal's Form API stores details of forms in a cache and these entries are + * kept for at least 6 hours by default. Expired entries are cleared by cron. + * + * @see \Drupal\Core\Form\FormCache::setCache() + */ +# $settings['form_cache_expiration'] = 21600; /** * Class Loader.