diff --git a/core/lib/Drupal/Core/Entity/Element/EntityAutocomplete.php b/core/lib/Drupal/Core/Entity/Element/EntityAutocomplete.php index 0691239dfa..bd24cd39b8 100644 --- a/core/lib/Drupal/Core/Entity/Element/EntityAutocomplete.php +++ b/core/lib/Drupal/Core/Entity/Element/EntityAutocomplete.php @@ -4,6 +4,7 @@ use Drupal\Component\Utility\Crypt; use Drupal\Component\Utility\Tags; +use Drupal\Core\Cache\CacheableMetadata; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityReferenceSelection\SelectionInterface; use Drupal\Core\Entity\EntityReferenceSelection\SelectionWithAutocreateInterface; @@ -130,10 +131,16 @@ public static function processEntityAutocomplete(array &$element, FormStateInter $data = serialize($selection_settings) . $element['#target_type'] . $element['#selection_handler']; $selection_settings_key = Crypt::hmacBase64($data, Settings::getHashSalt()); - $key_value_storage = \Drupal::keyValue('entity_autocomplete'); - if (!$key_value_storage->has($selection_settings_key)) { - $key_value_storage->set($selection_settings_key, $selection_settings); - } + // Even if the key already exists, we still need to refresh the expiry. + $expire = 86400; + $key_value_storage = \Drupal::keyValueExpirable('entity_autocomplete'); + $key_value_storage->setWithExpire($selection_settings_key, $selection_settings, $expire); + + // Since the key value entry expires, this element cannot live longer than + // the expiry or it won't work past that time. + $cache = CacheableMetadata::createFromRenderArray($element); + $cache->setCacheMaxAge($expire); + $cache->applyTo($element); $element['#autocomplete_route_name'] = 'system.entity_autocomplete'; $element['#autocomplete_route_parameters'] = [ diff --git a/core/modules/comment/tests/src/Kernel/CommentDefaultFormatterCacheTagsTest.php b/core/modules/comment/tests/src/Kernel/CommentDefaultFormatterCacheTagsTest.php index e681a4d9ad..2b4d364fcd 100644 --- a/core/modules/comment/tests/src/Kernel/CommentDefaultFormatterCacheTagsTest.php +++ b/core/modules/comment/tests/src/Kernel/CommentDefaultFormatterCacheTagsTest.php @@ -52,6 +52,7 @@ protected function setUp() { // Install tables and config needed to render comments. $this->installSchema('comment', ['comment_entity_statistics']); + $this->installSchema('system', ['key_value_expire']); $this->installConfig(['system', 'filter', 'comment']); // Comment rendering generates links, so build the router. diff --git a/core/modules/field/tests/src/Kernel/FieldKernelTestBase.php b/core/modules/field/tests/src/Kernel/FieldKernelTestBase.php index fdc8940fd6..33472dd53f 100644 --- a/core/modules/field/tests/src/Kernel/FieldKernelTestBase.php +++ b/core/modules/field/tests/src/Kernel/FieldKernelTestBase.php @@ -47,7 +47,7 @@ protected function setUp() { $this->installEntitySchema('entity_test'); $this->installEntitySchema('user'); - $this->installSchema('system', ['sequences', 'key_value']); + $this->installSchema('system', ['sequences', 'key_value', 'key_value_expire']); // Set default storage backend and configure the theme system. $this->installConfig(['field', 'system']); diff --git a/core/modules/language/tests/src/Kernel/LanguageSelectWidgetTest.php b/core/modules/language/tests/src/Kernel/LanguageSelectWidgetTest.php index 966275caa3..71857c6659 100644 --- a/core/modules/language/tests/src/Kernel/LanguageSelectWidgetTest.php +++ b/core/modules/language/tests/src/Kernel/LanguageSelectWidgetTest.php @@ -37,6 +37,7 @@ protected function setUp() { $this->installEntitySchema('entity_test'); $this->installEntitySchema('user'); + $this->installSchema('system', ['key_value_expire']); $storage = $this->container->get('entity_type.manager')->getStorage('entity_form_display'); $this->entityFormDisplay = $storage->create([ diff --git a/core/modules/system/src/Controller/EntityAutocompleteController.php b/core/modules/system/src/Controller/EntityAutocompleteController.php index b326385d59..b1947a61cc 100644 --- a/core/modules/system/src/Controller/EntityAutocompleteController.php +++ b/core/modules/system/src/Controller/EntityAutocompleteController.php @@ -28,7 +28,7 @@ class EntityAutocompleteController extends ControllerBase { /** * The key value store. * - * @var \Drupal\Core\KeyValueStore\KeyValueStoreInterface + * @var \Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface */ protected $keyValue; @@ -51,7 +51,7 @@ public function __construct(EntityAutocompleteMatcher $matcher, KeyValueStoreInt public static function create(ContainerInterface $container) { return new static( $container->get('entity.autocomplete_matcher'), - $container->get('keyvalue')->get('entity_autocomplete') + $container->get('keyvalue.expirable')->get('entity_autocomplete') ); } diff --git a/core/modules/system/system.install b/core/modules/system/system.install index 001ddcae88..4b7e9558e6 100644 --- a/core/modules/system/system.install +++ b/core/modules/system/system.install @@ -2472,3 +2472,10 @@ function system_update_8804(&$sandbox = NULL) { return t('Path aliases have been converted to entities.'); } } + +/** + * Delete entity autocomplete data from key/value. + */ +function system_update_8805() { + \Drupal::keyValue('entity_autocomplete')->deleteAll(); +} diff --git a/core/modules/text/tests/src/Kernel/TextSummaryTest.php b/core/modules/text/tests/src/Kernel/TextSummaryTest.php index bcd0cf3380..23c671a211 100644 --- a/core/modules/text/tests/src/Kernel/TextSummaryTest.php +++ b/core/modules/text/tests/src/Kernel/TextSummaryTest.php @@ -32,6 +32,7 @@ class TextSummaryTest extends KernelTestBase { protected function setUp() { parent::setUp(); + $this->installSchema('system', ['key_value_expire']); $this->installConfig(['text']); } diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntityAutocompleteTest.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityAutocompleteTest.php index ca65eb8324..012865bd76 100644 --- a/core/tests/Drupal/KernelTests/Core/Entity/EntityAutocompleteTest.php +++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityAutocompleteTest.php @@ -37,7 +37,7 @@ class EntityAutocompleteTest extends EntityKernelTestBase { */ protected function setUp() { parent::setUp(); - $this->installSchema('system', ['key_value']); + $this->installSchema('system', ['key_value_expire']); } /** @@ -124,7 +124,7 @@ public function testSelectionSettingsHandling() { $selection_settings_key = Crypt::hmacBase64(serialize($selection_settings) . $this->entityType . 'default', Settings::getHashSalt()); $selection_settings[$this->randomMachineName()] = $this->randomString(); - \Drupal::keyValue('entity_autocomplete')->set($selection_settings_key, $selection_settings); + \Drupal::keyValueExpirable('entity_autocomplete')->setWithExpire($selection_settings_key, $selection_settings, 120); $entity_reference_controller->handleAutocomplete($request, $this->entityType, 'default', $selection_settings_key); } @@ -154,7 +154,7 @@ protected function getAutocompleteResult($input) { $selection_settings = []; $selection_settings_key = Crypt::hmacBase64(serialize($selection_settings) . $this->entityType . 'default', Settings::getHashSalt()); - \Drupal::keyValue('entity_autocomplete')->set($selection_settings_key, $selection_settings); + \Drupal::keyValueExpirable('entity_autocomplete')->setWithExpire($selection_settings_key, $selection_settings, 120); $entity_reference_controller = EntityAutocompleteController::create($this->container); $result = $entity_reference_controller->handleAutocomplete($request, $this->entityType, 'default', $selection_settings_key)->getContent(); diff --git a/core/tests/Drupal/KernelTests/Core/Entity/FieldWidgetConstraintValidatorTest.php b/core/tests/Drupal/KernelTests/Core/Entity/FieldWidgetConstraintValidatorTest.php index 2f5f85218c..75bc5f386e 100644 --- a/core/tests/Drupal/KernelTests/Core/Entity/FieldWidgetConstraintValidatorTest.php +++ b/core/tests/Drupal/KernelTests/Core/Entity/FieldWidgetConstraintValidatorTest.php @@ -23,7 +23,7 @@ class FieldWidgetConstraintValidatorTest extends KernelTestBase { protected function setUp() { parent::setUp(); - $this->installSchema('system', ['key_value']); + $this->installSchema('system', ['key_value', 'key_value_expire']); $this->container->get('router.builder')->rebuild(); $this->installEntitySchema('user'); diff --git a/core/tests/Drupal/KernelTests/Core/Entity/RouteProviderTest.php b/core/tests/Drupal/KernelTests/Core/Entity/RouteProviderTest.php index c4e74a80a1..7364eb8bb3 100644 --- a/core/tests/Drupal/KernelTests/Core/Entity/RouteProviderTest.php +++ b/core/tests/Drupal/KernelTests/Core/Entity/RouteProviderTest.php @@ -35,6 +35,7 @@ protected function setUp() { $this->installEntitySchema('entity_test_mul'); $this->installEntitySchema('entity_test_admin_routes'); + $this->installSchema('system', ['key_value_expire']); /** @var \Drupal\user\RoleInterface $role */ $role = Role::create([