summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNathaniel Catchpole2018-01-12 10:04:36 (GMT)
committerNathaniel Catchpole2018-01-12 10:04:36 (GMT)
commit601593f06efc32cb96aa1a8779d0ecd690586bbc (patch)
tree9e54896fe557527dfe516b09647efdb6edff537c
parente965387d6f8c082cbf4fb2b710c70f6cdc70929d (diff)
Issue #2935617 by alexpott, chr.fritsch: Move User module's temp stores to core
-rw-r--r--core/core.services.yml11
-rw-r--r--core/lib/Drupal/Core/Session/SessionManager.php5
-rw-r--r--core/lib/Drupal/Core/TempStore/PrivateTempStore.php213
-rw-r--r--core/lib/Drupal/Core/TempStore/PrivateTempStoreFactory.php88
-rw-r--r--core/lib/Drupal/Core/TempStore/SharedTempStore.php279
-rw-r--r--core/lib/Drupal/Core/TempStore/SharedTempStoreFactory.php87
-rw-r--r--core/lib/Drupal/Core/TempStore/TempStoreException.php (renamed from core/modules/user/src/TempStoreException.php)6
-rw-r--r--core/modules/comment/src/Form/CommentAdminOverview.php8
-rw-r--r--core/modules/comment/src/Form/ConfirmDeleteMultiple.php8
-rw-r--r--core/modules/comment/src/Plugin/Action/DeleteComment.php8
-rw-r--r--core/modules/image/src/Controller/QuickEditImageController.php8
-rw-r--r--core/modules/layout_builder/layout_builder.services.yml2
-rw-r--r--core/modules/layout_builder/src/LayoutTempstoreRepository.php8
-rw-r--r--core/modules/layout_builder/tests/src/Unit/LayoutTempstoreRepositoryTest.php4
-rw-r--r--core/modules/media/src/Form/MediaDeleteMultipleConfirmForm.php8
-rw-r--r--core/modules/node/node.services.yml2
-rw-r--r--core/modules/node/src/Form/DeleteMultiple.php8
-rw-r--r--core/modules/node/src/NodeForm.php8
-rw-r--r--core/modules/node/src/ParamConverter/NodePreviewConverter.php6
-rw-r--r--core/modules/node/src/Plugin/Action/DeleteNode.php8
-rw-r--r--core/modules/quickedit/src/Form/QuickEditFieldForm.php8
-rw-r--r--core/modules/quickedit/src/QuickEditController.php8
-rw-r--r--core/modules/user/src/Form/UserMultipleCancelConfirm.php8
-rw-r--r--core/modules/user/src/Plugin/Action/CancelUser.php8
-rw-r--r--core/modules/user/src/PrivateTempStore.php217
-rw-r--r--core/modules/user/src/PrivateTempStoreFactory.php72
-rw-r--r--core/modules/user/src/SharedTempStore.php283
-rw-r--r--core/modules/user/src/SharedTempStoreFactory.php61
-rw-r--r--core/modules/user/src/UserServiceProvider.php24
-rw-r--r--core/modules/user/tests/src/Kernel/TempStoreDatabaseTest.php6
-rw-r--r--core/modules/user/tests/src/Kernel/UserServiceProviderTest.php40
-rw-r--r--core/modules/user/tests/src/Unit/PrivateTempStoreTest.php10
-rw-r--r--core/modules/user/tests/src/Unit/SharedTempStoreTest.php15
-rw-r--r--core/modules/user/user.services.yml9
-rw-r--r--core/modules/views/src/Entity/View.php2
-rw-r--r--core/modules/views_ui/src/Form/BreakLockForm.php10
-rw-r--r--core/modules/views_ui/src/ParamConverter/ViewUIConverter.php6
-rw-r--r--core/modules/views_ui/src/ViewEditForm.php8
-rw-r--r--core/modules/views_ui/src/ViewUI.php6
-rw-r--r--core/modules/views_ui/tests/src/Functional/CachedDataUITest.php8
-rw-r--r--core/modules/views_ui/views_ui.services.yml2
-rw-r--r--core/tests/Drupal/KernelTests/Core/TempStore/TempStoreDatabaseTest.php139
-rw-r--r--core/tests/Drupal/Tests/Core/TempStore/PrivateTempStoreTest.php281
-rw-r--r--core/tests/Drupal/Tests/Core/TempStore/SharedTempStoreTest.php353
44 files changed, 1679 insertions, 680 deletions
diff --git a/core/core.services.yml b/core/core.services.yml
index 737009b..fd8fc04 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -41,6 +41,7 @@ parameters:
exposedHeaders: false
maxAge: false
supportsCredentials: false
+ tempstore.expire: 604800
services:
# Simple cache contexts, directly derived from the request context.
cache_context.ip:
@@ -1650,3 +1651,13 @@ services:
messenger:
class: Drupal\Core\Messenger\Messenger
arguments: ['@session.flash_bag', '@page_cache_kill_switch']
+ tempstore.private:
+ class: Drupal\Core\TempStore\PrivateTempStoreFactory
+ arguments: ['@keyvalue.expirable', '@lock', '@current_user', '@request_stack', '%tempstore.expire%']
+ tags:
+ - { name: backend_overridable }
+ tempstore.shared:
+ class: Drupal\Core\TempStore\SharedTempStoreFactory
+ arguments: ['@keyvalue.expirable', '@lock', '@request_stack', '%tempstore.expire%']
+ tags:
+ - { name: backend_overridable }
diff --git a/core/lib/Drupal/Core/Session/SessionManager.php b/core/lib/Drupal/Core/Session/SessionManager.php
index 95495cf..6071031 100644
--- a/core/lib/Drupal/Core/Session/SessionManager.php
+++ b/core/lib/Drupal/Core/Session/SessionManager.php
@@ -120,8 +120,9 @@ class SessionManager extends NativeSessionStorage implements SessionManagerInter
if (empty($result)) {
// Randomly generate a session identifier for this request. This is
- // necessary because \Drupal\user\SharedTempStoreFactory::get() wants to
- // know the future session ID of a lazily started session in advance.
+ // necessary because \Drupal\Core\TempStore\SharedTempStoreFactory::get()
+ // wants to know the future session ID of a lazily started session in
+ // advance.
//
// @todo: With current versions of PHP there is little reason to generate
// the session id from within application code. Consider using the
diff --git a/core/lib/Drupal/Core/TempStore/PrivateTempStore.php b/core/lib/Drupal/Core/TempStore/PrivateTempStore.php
new file mode 100644
index 0000000..f9d1034
--- /dev/null
+++ b/core/lib/Drupal/Core/TempStore/PrivateTempStore.php
@@ -0,0 +1,213 @@
+<?php
+
+namespace Drupal\Core\TempStore;
+
+use Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface;
+use Drupal\Core\Lock\LockBackendInterface;
+use Drupal\Core\Session\AccountProxyInterface;
+use Symfony\Component\HttpFoundation\RequestStack;
+
+/**
+ * Stores and retrieves temporary data for a given owner.
+ *
+ * A PrivateTempStore can be used to make temporary, non-cache data available
+ * across requests. The data for the PrivateTempStore is stored in one
+ * key/value collection. PrivateTempStore data expires automatically after a
+ * given timeframe.
+ *
+ * The PrivateTempStore is different from a cache, because the data in it is not
+ * yet saved permanently and so it cannot be rebuilt. Typically, the
+ * PrivateTempStore might be used to store work in progress that is later saved
+ * permanently elsewhere, e.g. autosave data, multistep forms, or in-progress
+ * changes to complex configuration that are not ready to be saved.
+ *
+ * The PrivateTempStore differs from the SharedTempStore in that all keys are
+ * ensured to be unique for a particular user and users can never share data. If
+ * you want to be able to share data between users or use it for locking, use
+ * \Drupal\Core\TempStore\SharedTempStore.
+ */
+class PrivateTempStore {
+
+ /**
+ * The key/value storage object used for this data.
+ *
+ * @var \Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface
+ */
+ protected $storage;
+
+ /**
+ * The lock object used for this data.
+ *
+ * @var \Drupal\Core\Lock\LockBackendInterface
+ */
+ protected $lockBackend;
+
+ /**
+ * The current user.
+ *
+ * @var \Drupal\Core\Session\AccountProxyInterface
+ */
+ protected $currentUser;
+
+ /**
+ * The request stack.
+ *
+ * @var \Symfony\Component\HttpFoundation\RequestStack
+ */
+ protected $requestStack;
+
+ /**
+ * The time to live for items in seconds.
+ *
+ * By default, data is stored for one week (604800 seconds) before expiring.
+ *
+ * @var int
+ */
+ protected $expire;
+
+ /**
+ * Constructs a new object for accessing data from a key/value store.
+ *
+ * @param \Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface $storage
+ * The key/value storage object used for this data. Each storage object
+ * represents a particular collection of data and will contain any number
+ * of key/value pairs.
+ * @param \Drupal\Core\Lock\LockBackendInterface $lock_backend
+ * The lock object used for this data.
+ * @param \Drupal\Core\Session\AccountProxyInterface $current_user
+ * The current user account.
+ * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
+ * The request stack.
+ * @param int $expire
+ * The time to live for items, in seconds.
+ */
+ public function __construct(KeyValueStoreExpirableInterface $storage, LockBackendInterface $lock_backend, AccountProxyInterface $current_user, RequestStack $request_stack, $expire = 604800) {
+ $this->storage = $storage;
+ $this->lockBackend = $lock_backend;
+ $this->currentUser = $current_user;
+ $this->requestStack = $request_stack;
+ $this->expire = $expire;
+ }
+
+ /**
+ * Retrieves a value from this PrivateTempStore for a given key.
+ *
+ * @param string $key
+ * The key of the data to retrieve.
+ *
+ * @return mixed
+ * The data associated with the key, or NULL if the key does not exist.
+ */
+ public function get($key) {
+ $key = $this->createkey($key);
+ if (($object = $this->storage->get($key)) && ($object->owner == $this->getOwner())) {
+ return $object->data;
+ }
+ }
+
+ /**
+ * Stores a particular key/value pair in this PrivateTempStore.
+ *
+ * @param string $key
+ * The key of the data to store.
+ * @param mixed $value
+ * The data to store.
+ *
+ * @throws \Drupal\Core\TempStore\TempStoreException
+ * Thrown when a lock for the backend storage could not be acquired.
+ */
+ public function set($key, $value) {
+ $key = $this->createkey($key);
+ if (!$this->lockBackend->acquire($key)) {
+ $this->lockBackend->wait($key);
+ if (!$this->lockBackend->acquire($key)) {
+ throw new TempStoreException("Couldn't acquire lock to update item '$key' in '{$this->storage->getCollectionName()}' temporary storage.");
+ }
+ }
+
+ $value = (object) [
+ 'owner' => $this->getOwner(),
+ 'data' => $value,
+ 'updated' => (int) $this->requestStack->getMasterRequest()->server->get('REQUEST_TIME'),
+ ];
+ $this->storage->setWithExpire($key, $value, $this->expire);
+ $this->lockBackend->release($key);
+ }
+
+ /**
+ * Returns the metadata associated with a particular key/value pair.
+ *
+ * @param string $key
+ * The key of the data to store.
+ *
+ * @return mixed
+ * An object with the owner and updated time if the key has a value, or
+ * NULL otherwise.
+ */
+ public function getMetadata($key) {
+ $key = $this->createkey($key);
+ // Fetch the key/value pair and its metadata.
+ $object = $this->storage->get($key);
+ if ($object) {
+ // Don't keep the data itself in memory.
+ unset($object->data);
+ return $object;
+ }
+ }
+
+ /**
+ * Deletes data from the store for a given key and releases the lock on it.
+ *
+ * @param string $key
+ * The key of the data to delete.
+ *
+ * @return bool
+ * TRUE if the object was deleted or does not exist, FALSE if it exists but
+ * is not owned by $this->owner.
+ *
+ * @throws \Drupal\Core\TempStore\TempStoreException
+ * Thrown when a lock for the backend storage could not be acquired.
+ */
+ public function delete($key) {
+ $key = $this->createkey($key);
+ if (!$object = $this->storage->get($key)) {
+ return TRUE;
+ }
+ elseif ($object->owner != $this->getOwner()) {
+ return FALSE;
+ }
+ if (!$this->lockBackend->acquire($key)) {
+ $this->lockBackend->wait($key);
+ if (!$this->lockBackend->acquire($key)) {
+ throw new TempStoreException("Couldn't acquire lock to delete item '$key' from '{$this->storage->getCollectionName()}' temporary storage.");
+ }
+ }
+ $this->storage->delete($key);
+ $this->lockBackend->release($key);
+ return TRUE;
+ }
+
+ /**
+ * Ensures that the key is unique for a user.
+ *
+ * @param string $key
+ * The key.
+ *
+ * @return string
+ * The unique key for the user.
+ */
+ protected function createkey($key) {
+ return $this->getOwner() . ':' . $key;
+ }
+
+ /**
+ * Gets the current owner based on the current user or the session ID.
+ *
+ * @return string
+ * The owner.
+ */
+ protected function getOwner() {
+ return $this->currentUser->id() ?: $this->requestStack->getCurrentRequest()->getSession()->getId();
+ }
+
+}
diff --git a/core/lib/Drupal/Core/TempStore/PrivateTempStoreFactory.php b/core/lib/Drupal/Core/TempStore/PrivateTempStoreFactory.php
new file mode 100644
index 0000000..b80b825
--- /dev/null
+++ b/core/lib/Drupal/Core/TempStore/PrivateTempStoreFactory.php
@@ -0,0 +1,88 @@
+<?php
+
+namespace Drupal\Core\TempStore;
+
+use Drupal\Core\KeyValueStore\KeyValueExpirableFactoryInterface;
+use Drupal\Core\Lock\LockBackendInterface;
+use Drupal\Core\Session\AccountProxyInterface;
+use Symfony\Component\HttpFoundation\RequestStack;
+
+/**
+ * Creates a PrivateTempStore object for a given collection.
+ */
+class PrivateTempStoreFactory {
+
+ /**
+ * The storage factory creating the backend to store the data.
+ *
+ * @var \Drupal\Core\KeyValueStore\KeyValueExpirableFactoryInterface
+ */
+ protected $storageFactory;
+
+ /**
+ * The lock object used for this data.
+ *
+ * @var \Drupal\Core\Lock\LockBackendInterface
+ */
+ protected $lockBackend;
+
+ /**
+ * The current user.
+ *
+ * @var \Drupal\Core\Session\AccountProxyInterface
+ */
+ protected $currentUser;
+
+ /**
+ * The request stack.
+ *
+ * @var \Symfony\Component\HttpFoundation\RequestStack
+ */
+ protected $requestStack;
+
+ /**
+ * The time to live for items in seconds.
+ *
+ * @var int
+ */
+ protected $expire;
+
+ /**
+ * Constructs a Drupal\Core\TempStore\PrivateTempStoreFactory object.
+ *
+ * @param \Drupal\Core\KeyValueStore\KeyValueExpirableFactoryInterface $storage_factory
+ * The key/value store factory.
+ * @param \Drupal\Core\Lock\LockBackendInterface $lock_backend
+ * The lock object used for this data.
+ * @param \Drupal\Core\Session\AccountProxyInterface $current_user
+ * The current account.
+ * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
+ * The request stack.
+ * @param int $expire
+ * The time to live for items, in seconds.
+ */
+ public function __construct(KeyValueExpirableFactoryInterface $storage_factory, LockBackendInterface $lock_backend, AccountProxyInterface $current_user, RequestStack $request_stack, $expire = 604800) {
+ $this->storageFactory = $storage_factory;
+ $this->lockBackend = $lock_backend;
+ $this->currentUser = $current_user;
+ $this->requestStack = $request_stack;
+ $this->expire = $expire;
+ }
+
+ /**
+ * Creates a PrivateTempStore.
+ *
+ * @param string $collection
+ * The collection name to use for this key/value store. This is typically
+ * a shared namespace or module name, e.g. 'views', 'entity', etc.
+ *
+ * @return \Drupal\Core\TempStore\PrivateTempStore
+ * An instance of the key/value store.
+ */
+ public function get($collection) {
+ // Store the data for this collection in the database.
+ $storage = $this->storageFactory->get("tempstore.private.$collection");
+ return new PrivateTempStore($storage, $this->lockBackend, $this->currentUser, $this->requestStack, $this->expire);
+ }
+
+}
diff --git a/core/lib/Drupal/Core/TempStore/SharedTempStore.php b/core/lib/Drupal/Core/TempStore/SharedTempStore.php
new file mode 100644
index 0000000..c131a80
--- /dev/null
+++ b/core/lib/Drupal/Core/TempStore/SharedTempStore.php
@@ -0,0 +1,279 @@
+<?php
+
+namespace Drupal\Core\TempStore;
+
+use Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface;
+use Drupal\Core\Lock\LockBackendInterface;
+use Symfony\Component\HttpFoundation\RequestStack;
+
+/**
+ * Stores and retrieves temporary data for a given owner.
+ *
+ * A SharedTempStore can be used to make temporary, non-cache data available
+ * across requests. The data for the SharedTempStore is stored in one key/value
+ * collection. SharedTempStore data expires automatically after a given
+ * timeframe.
+ *
+ * The SharedTempStore is different from a cache, because the data in it is not
+ * yet saved permanently and so it cannot be rebuilt. Typically, the
+ * SharedTempStore might be used to store work in progress that is later saved
+ * permanently elsewhere, e.g. autosave data, multistep forms, or in-progress
+ * changes to complex configuration that are not ready to be saved.
+ *
+ * Each SharedTempStore belongs to a particular owner (e.g. a user, session, or
+ * process). Multiple owners may use the same key/value collection, and the
+ * owner is stored along with the key/value pair.
+ *
+ * Every key is unique within the collection, so the SharedTempStore can check
+ * whether a particular key is already set by a different owner. This is
+ * useful for informing one owner that the data is already in use by another;
+ * for example, to let one user know that another user is in the process of
+ * editing certain data, or even to restrict other users from editing it at
+ * the same time. It is the responsibility of the implementation to decide
+ * when and whether one owner can use or update another owner's data.
+ *
+ * If you want to be able to ensure that the data belongs to the current user,
+ * use \Drupal\Core\TempStore\PrivateTempStore.
+ */
+class SharedTempStore {
+
+ /**
+ * The key/value storage object used for this data.
+ *
+ * @var \Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface
+ */
+ protected $storage;
+
+ /**
+ * The lock object used for this data.
+ *
+ * @var \Drupal\Core\Lock\LockBackendInterface
+ */
+ protected $lockBackend;
+
+ /**
+ * The request stack.
+ *
+ * @var \Symfony\Component\HttpFoundation\RequestStack
+ */
+ protected $requestStack;
+
+ /**
+ * The owner key to store along with the data (e.g. a user or session ID).
+ *
+ * @var mixed
+ */
+ protected $owner;
+
+ /**
+ * The time to live for items in seconds.
+ *
+ * By default, data is stored for one week (604800 seconds) before expiring.
+ *
+ * @var int
+ */
+ protected $expire;
+
+ /**
+ * Constructs a new object for accessing data from a key/value store.
+ *
+ * @param \Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface $storage
+ * The key/value storage object used for this data. Each storage object
+ * represents a particular collection of data and will contain any number
+ * of key/value pairs.
+ * @param \Drupal\Core\Lock\LockBackendInterface $lock_backend
+ * The lock object used for this data.
+ * @param mixed $owner
+ * The owner key to store along with the data (e.g. a user or session ID).
+ * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
+ * The request stack.
+ * @param int $expire
+ * The time to live for items, in seconds.
+ */
+ public function __construct(KeyValueStoreExpirableInterface $storage, LockBackendInterface $lock_backend, $owner, RequestStack $request_stack, $expire = 604800) {
+ $this->storage = $storage;
+ $this->lockBackend = $lock_backend;
+ $this->owner = $owner;
+ $this->requestStack = $request_stack;
+ $this->expire = $expire;
+ }
+
+ /**
+ * Retrieves a value from this SharedTempStore for a given key.
+ *
+ * @param string $key
+ * The key of the data to retrieve.
+ *
+ * @return mixed
+ * The data associated with the key, or NULL if the key does not exist.
+ */
+ public function get($key) {
+ if ($object = $this->storage->get($key)) {
+ return $object->data;
+ }
+ }
+
+ /**
+ * Retrieves a value from this SharedTempStore for a given key.
+ *
+ * Only returns the value if the value is owned by $this->owner.
+ *
+ * @param string $key
+ * The key of the data to retrieve.
+ *
+ * @return mixed
+ * The data associated with the key, or NULL if the key does not exist.
+ */
+ public function getIfOwner($key) {
+ if (($object = $this->storage->get($key)) && ($object->owner == $this->owner)) {
+ return $object->data;
+ }
+ }
+
+ /**
+ * Stores a particular key/value pair only if the key doesn't already exist.
+ *
+ * @param string $key
+ * The key of the data to check and store.
+ * @param mixed $value
+ * The data to store.
+ *
+ * @return bool
+ * TRUE if the data was set, or FALSE if it already existed.
+ */
+ public function setIfNotExists($key, $value) {
+ $value = (object) [
+ 'owner' => $this->owner,
+ 'data' => $value,
+ 'updated' => (int) $this->requestStack->getMasterRequest()->server->get('REQUEST_TIME'),
+ ];
+ return $this->storage->setWithExpireIfNotExists($key, $value, $this->expire);
+ }
+
+ /**
+ * Stores a particular key/value pair in this SharedTempStore.
+ *
+ * Only stores the given key/value pair if it does not exist yet or is owned
+ * by $this->owner.
+ *
+ * @param string $key
+ * The key of the data to store.
+ * @param mixed $value
+ * The data to store.
+ *
+ * @return bool
+ * TRUE if the data was set, or FALSE if it already exists and is not owned
+ * by $this->user.
+ *
+ * @throws \Drupal\Core\TempStore\TempStoreException
+ * Thrown when a lock for the backend storage could not be acquired.
+ */
+ public function setIfOwner($key, $value) {
+ if ($this->setIfNotExists($key, $value)) {
+ return TRUE;
+ }
+
+ if (($object = $this->storage->get($key)) && ($object->owner == $this->owner)) {
+ $this->set($key, $value);
+ return TRUE;
+ }
+
+ return FALSE;
+ }
+
+ /**
+ * Stores a particular key/value pair in this SharedTempStore.
+ *
+ * @param string $key
+ * The key of the data to store.
+ * @param mixed $value
+ * The data to store.
+ *
+ * @throws \Drupal\Core\TempStore\TempStoreException
+ * Thrown when a lock for the backend storage could not be acquired.
+ */
+ public function set($key, $value) {
+ if (!$this->lockBackend->acquire($key)) {
+ $this->lockBackend->wait($key);
+ if (!$this->lockBackend->acquire($key)) {
+ throw new TempStoreException("Couldn't acquire lock to update item '$key' in '{$this->storage->getCollectionName()}' temporary storage.");
+ }
+ }
+
+ $value = (object) [
+ 'owner' => $this->owner,
+ 'data' => $value,
+ 'updated' => (int) $this->requestStack->getMasterRequest()->server->get('REQUEST_TIME'),
+ ];
+ $this->storage->setWithExpire($key, $value, $this->expire);
+ $this->lockBackend->release($key);
+ }
+
+ /**
+ * Returns the metadata associated with a particular key/value pair.
+ *
+ * @param string $key
+ * The key of the data to store.
+ *
+ * @return mixed
+ * An object with the owner and updated time if the key has a value, or
+ * NULL otherwise.
+ */
+ public function getMetadata($key) {
+ // Fetch the key/value pair and its metadata.
+ $object = $this->storage->get($key);
+ if ($object) {
+ // Don't keep the data itself in memory.
+ unset($object->data);
+ return $object;
+ }
+ }
+
+ /**
+ * Deletes data from the store for a given key and releases the lock on it.
+ *
+ * @param string $key
+ * The key of the data to delete.
+ *
+ * @throws \Drupal\Core\TempStore\TempStoreException
+ * Thrown when a lock for the backend storage could not be acquired.
+ */
+ public function delete($key) {
+ if (!$this->lockBackend->acquire($key)) {
+ $this->lockBackend->wait($key);
+ if (!$this->lockBackend->acquire($key)) {
+ throw new TempStoreException("Couldn't acquire lock to delete item '$key' from {$this->storage->getCollectionName()} temporary storage.");
+ }
+ }
+ $this->storage->delete($key);
+ $this->lockBackend->release($key);
+ }
+
+ /**
+ * Deletes data from the store for a given key and releases the lock on it.
+ *
+ * Only delete the given key if it is owned by $this->owner.
+ *
+ * @param string $key
+ * The key of the data to delete.
+ *
+ * @return bool
+ * TRUE if the object was deleted or does not exist, FALSE if it exists but
+ * is not owned by $this->owner.
+ *
+ * @throws \Drupal\Core\TempStore\TempStoreException
+ * Thrown when a lock for the backend storage could not be acquired.
+ */
+ public function deleteIfOwner($key) {
+ if (!$object = $this->storage->get($key)) {
+ return TRUE;
+ }
+ elseif ($object->owner == $this->owner) {
+ $this->delete($key);
+ return TRUE;
+ }
+
+ return FALSE;
+ }
+
+}
diff --git a/core/lib/Drupal/Core/TempStore/SharedTempStoreFactory.php b/core/lib/Drupal/Core/TempStore/SharedTempStoreFactory.php
new file mode 100644
index 0000000..90e816a
--- /dev/null
+++ b/core/lib/Drupal/Core/TempStore/SharedTempStoreFactory.php
@@ -0,0 +1,87 @@
+<?php
+
+namespace Drupal\Core\TempStore;
+
+use Drupal\Core\KeyValueStore\KeyValueExpirableFactoryInterface;
+use Drupal\Core\Lock\LockBackendInterface;
+use Symfony\Component\HttpFoundation\RequestStack;
+
+/**
+ * Creates a shared temporary storage for a collection.
+ */
+class SharedTempStoreFactory {
+
+ /**
+ * The storage factory creating the backend to store the data.
+ *
+ * @var \Drupal\Core\KeyValueStore\KeyValueExpirableFactoryInterface
+ */
+ protected $storageFactory;
+
+ /**
+ * The lock object used for this data.
+ *
+ * @var \Drupal\Core\Lock\LockBackendInterface
+ */
+ protected $lockBackend;
+
+ /**
+ * The request stack.
+ *
+ * @var \Symfony\Component\HttpFoundation\RequestStack
+ */
+ protected $requestStack;
+
+ /**
+ * The time to live for items in seconds.
+ *
+ * @var int
+ */
+ protected $expire;
+
+ /**
+ * Constructs a Drupal\Core\TempStore\SharedTempStoreFactory object.
+ *
+ * @param \Drupal\Core\KeyValueStore\KeyValueExpirableFactoryInterface $storage_factory
+ * The key/value store factory.
+ * @param \Drupal\Core\Lock\LockBackendInterface $lock_backend
+ * The lock object used for this data.
+ * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
+ * The request stack.
+ * @param int $expire
+ * The time to live for items, in seconds.
+ */
+ public function __construct(KeyValueExpirableFactoryInterface $storage_factory, LockBackendInterface $lock_backend, RequestStack $request_stack, $expire = 604800) {
+ $this->storageFactory = $storage_factory;
+ $this->lockBackend = $lock_backend;
+ $this->requestStack = $request_stack;
+ $this->expire = $expire;
+ }
+
+ /**
+ * Creates a SharedTempStore for the current user or anonymous session.
+ *
+ * @param string $collection
+ * The collection name to use for this key/value store. This is typically
+ * a shared namespace or module name, e.g. 'views', 'entity', etc.
+ * @param mixed $owner
+ * (optional) The owner of this SharedTempStore. By default, the
+ * SharedTempStore is owned by the currently authenticated user, or by the
+ * active anonymous session if no user is logged in.
+ *
+ * @return \Drupal\Core\TempStore\SharedTempStore
+ * An instance of the key/value store.
+ */
+ public function get($collection, $owner = NULL) {
+ // Use the currently authenticated user ID or the active user ID unless
+ // the owner is overridden.
+ if (!isset($owner)) {
+ $owner = \Drupal::currentUser()->id() ?: session_id();
+ }
+
+ // Store the data for this collection in the database.
+ $storage = $this->storageFactory->get("tempstore.shared.$collection");
+ return new SharedTempStore($storage, $this->lockBackend, $owner, $this->requestStack, $this->expire);
+ }
+
+}
diff --git a/core/modules/user/src/TempStoreException.php b/core/lib/Drupal/Core/TempStore/TempStoreException.php
index 1f9c79b..53c3a59 100644
--- a/core/modules/user/src/TempStoreException.php
+++ b/core/lib/Drupal/Core/TempStore/TempStoreException.php
@@ -1,11 +1,11 @@
<?php
-namespace Drupal\user;
+namespace Drupal\Core\TempStore;
/**
* Thrown by SharedTempStore and PrivateTempStore if they cannot acquire a lock.
*
- * @see \Drupal\user\SharedTempStore
- * @see \Drupal\user\PrivateTempStore
+ * @see \Drupal\Core\TempStore\SharedTempStore
+ * @see \Drupal\Core\TempStore\PrivateTempStore
*/
class TempStoreException extends \Exception {}
diff --git a/core/modules/comment/src/Form/CommentAdminOverview.php b/core/modules/comment/src/Form/CommentAdminOverview.php
index 1ffa2c6..4fe7291 100644
--- a/core/modules/comment/src/Form/CommentAdminOverview.php
+++ b/core/modules/comment/src/Form/CommentAdminOverview.php
@@ -9,7 +9,7 @@ use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
-use Drupal\user\PrivateTempStoreFactory;
+use Drupal\Core\TempStore\PrivateTempStoreFactory;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
@@ -50,7 +50,7 @@ class CommentAdminOverview extends FormBase {
/**
* The tempstore factory.
*
- * @var \Drupal\user\PrivateTempStoreFactory
+ * @var \Drupal\Core\TempStore\PrivateTempStoreFactory
*/
protected $tempStoreFactory;
@@ -63,7 +63,7 @@ class CommentAdminOverview extends FormBase {
* The date formatter service.
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
* The module handler.
- * @param \Drupal\user\PrivateTempStoreFactory $temp_store_factory
+ * @param \Drupal\Core\TempStore\PrivateTempStoreFactory $temp_store_factory
* The tempstore factory.
*/
public function __construct(EntityTypeManagerInterface $entity_type_manager, DateFormatterInterface $date_formatter, ModuleHandlerInterface $module_handler, PrivateTempStoreFactory $temp_store_factory) {
@@ -82,7 +82,7 @@ class CommentAdminOverview extends FormBase {
$container->get('entity_type.manager'),
$container->get('date.formatter'),
$container->get('module_handler'),
- $container->get('user.private_tempstore')
+ $container->get('tempstore.private')
);
}
diff --git a/core/modules/comment/src/Form/ConfirmDeleteMultiple.php b/core/modules/comment/src/Form/ConfirmDeleteMultiple.php
index 83f1889..7044393 100644
--- a/core/modules/comment/src/Form/ConfirmDeleteMultiple.php
+++ b/core/modules/comment/src/Form/ConfirmDeleteMultiple.php
@@ -3,7 +3,7 @@
namespace Drupal\comment\Form;
use Drupal\comment\CommentStorageInterface;
-use Drupal\user\PrivateTempStoreFactory;
+use Drupal\Core\TempStore\PrivateTempStoreFactory;
use Drupal\Core\Form\ConfirmFormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;
@@ -19,7 +19,7 @@ class ConfirmDeleteMultiple extends ConfirmFormBase {
/**
* The tempstore factory.
*
- * @var \Drupal\user\PrivateTempStoreFactory
+ * @var \Drupal\Core\TempStore\PrivateTempStoreFactory
*/
protected $tempStoreFactory;
@@ -42,7 +42,7 @@ class ConfirmDeleteMultiple extends ConfirmFormBase {
*
* @param \Drupal\comment\CommentStorageInterface $comment_storage
* The comment storage.
- * @param \Drupal\user\PrivateTempStoreFactory $temp_store_factory
+ * @param \Drupal\Core\TempStore\PrivateTempStoreFactory $temp_store_factory
* The tempstore factory.
*/
public function __construct(CommentStorageInterface $comment_storage, PrivateTempStoreFactory $temp_store_factory) {
@@ -56,7 +56,7 @@ class ConfirmDeleteMultiple extends ConfirmFormBase {
public static function create(ContainerInterface $container) {
return new static(
$container->get('entity.manager')->getStorage('comment'),
- $container->get('user.private_tempstore')
+ $container->get('tempstore.private')
);
}
diff --git a/core/modules/comment/src/Plugin/Action/DeleteComment.php b/core/modules/comment/src/Plugin/Action/DeleteComment.php
index 675b021..5c6941d 100644
--- a/core/modules/comment/src/Plugin/Action/DeleteComment.php
+++ b/core/modules/comment/src/Plugin/Action/DeleteComment.php
@@ -5,7 +5,7 @@ namespace Drupal\comment\Plugin\Action;
use Drupal\Core\Action\ActionBase;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Session\AccountInterface;
-use Drupal\user\PrivateTempStoreFactory;
+use Drupal\Core\TempStore\PrivateTempStoreFactory;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
@@ -23,7 +23,7 @@ class DeleteComment extends ActionBase implements ContainerFactoryPluginInterfac
/**
* The tempstore object.
*
- * @var \Drupal\user\PrivateTempStore
+ * @var \Drupal\Core\TempStore\PrivateTempStore
*/
protected $tempStore;
@@ -43,7 +43,7 @@ class DeleteComment extends ActionBase implements ContainerFactoryPluginInterfac
* The plugin ID for the plugin instance.
* @param array $plugin_definition
* The plugin implementation definition.
- * @param \Drupal\user\PrivateTempStoreFactory $temp_store_factory
+ * @param \Drupal\Core\TempStore\PrivateTempStoreFactory $temp_store_factory
* The tempstore factory.
* @param \Drupal\Core\Session\AccountInterface $current_user
* The current user.
@@ -62,7 +62,7 @@ class DeleteComment extends ActionBase implements ContainerFactoryPluginInterfac
$configuration,
$plugin_id,
$plugin_definition,
- $container->get('user.private_tempstore'),
+ $container->get('tempstore.private'),
$container->get('current_user')
);
}
diff --git a/core/modules/image/src/Controller/QuickEditImageController.php b/core/modules/image/src/Controller/QuickEditImageController.php
index aa49bc7..5fc28ba 100644
--- a/core/modules/image/src/Controller/QuickEditImageController.php
+++ b/core/modules/image/src/Controller/QuickEditImageController.php
@@ -10,7 +10,7 @@ use Drupal\Core\Image\ImageFactory;
use Drupal\Core\Render\Element\StatusMessages;
use Drupal\Core\Render\RendererInterface;
use Drupal\image\Plugin\Field\FieldType\ImageItem;
-use Drupal\user\PrivateTempStoreFactory;
+use Drupal\Core\TempStore\PrivateTempStoreFactory;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
@@ -23,7 +23,7 @@ class QuickEditImageController extends ControllerBase {
/**
* Stores The Quick Edit tempstore.
*
- * @var \Drupal\user\PrivateTempStore
+ * @var \Drupal\Core\TempStore\PrivateTempStore
*/
protected $tempStore;
@@ -48,7 +48,7 @@ class QuickEditImageController extends ControllerBase {
* The renderer.
* @param \Drupal\Core\Image\ImageFactory $image_factory
* The image factory.
- * @param \Drupal\user\PrivateTempStoreFactory $temp_store_factory
+ * @param \Drupal\Core\TempStore\PrivateTempStoreFactory $temp_store_factory
* The tempstore factory.
*/
public function __construct(RendererInterface $renderer, ImageFactory $image_factory, PrivateTempStoreFactory $temp_store_factory) {
@@ -64,7 +64,7 @@ class QuickEditImageController extends ControllerBase {
return new static(
$container->get('renderer'),
$container->get('image.factory'),
- $container->get('user.private_tempstore')
+ $container->get('tempstore.private')
);
}
diff --git a/core/modules/layout_builder/layout_builder.services.yml b/core/modules/layout_builder/layout_builder.services.yml
index 67f1aa1..db6a1c1 100644
--- a/core/modules/layout_builder/layout_builder.services.yml
+++ b/core/modules/layout_builder/layout_builder.services.yml
@@ -1,7 +1,7 @@
services:
layout_builder.tempstore_repository:
class: Drupal\layout_builder\LayoutTempstoreRepository
- arguments: ['@user.shared_tempstore']
+ arguments: ['@tempstore.shared']
access_check.entity.layout:
class: Drupal\layout_builder\Access\LayoutSectionAccessCheck
tags:
diff --git a/core/modules/layout_builder/src/LayoutTempstoreRepository.php b/core/modules/layout_builder/src/LayoutTempstoreRepository.php
index 5e1a18d..0fa9d73 100644
--- a/core/modules/layout_builder/src/LayoutTempstoreRepository.php
+++ b/core/modules/layout_builder/src/LayoutTempstoreRepository.php
@@ -2,7 +2,7 @@
namespace Drupal\layout_builder;
-use Drupal\user\SharedTempStoreFactory;
+use Drupal\Core\TempStore\SharedTempStoreFactory;
/**
* Provides a mechanism for loading layouts from tempstore.
@@ -14,14 +14,14 @@ class LayoutTempstoreRepository implements LayoutTempstoreRepositoryInterface {
/**
* The shared tempstore factory.
*
- * @var \Drupal\user\SharedTempStoreFactory
+ * @var \Drupal\Core\TempStore\SharedTempStoreFactory
*/
protected $tempStoreFactory;
/**
* LayoutTempstoreRepository constructor.
*
- * @param \Drupal\user\SharedTempStoreFactory $temp_store_factory
+ * @param \Drupal\Core\TempStore\SharedTempStoreFactory $temp_store_factory
* The shared tempstore factory.
*/
public function __construct(SharedTempStoreFactory $temp_store_factory) {
@@ -67,7 +67,7 @@ class LayoutTempstoreRepository implements LayoutTempstoreRepositoryInterface {
* @param \Drupal\layout_builder\SectionStorageInterface $section_storage
* The section storage.
*
- * @return \Drupal\user\SharedTempStore
+ * @return \Drupal\Core\TempStore\SharedTempStore
* The tempstore.
*/
protected function getTempstore(SectionStorageInterface $section_storage) {
diff --git a/core/modules/layout_builder/tests/src/Unit/LayoutTempstoreRepositoryTest.php b/core/modules/layout_builder/tests/src/Unit/LayoutTempstoreRepositoryTest.php
index 75502d5..b7702c1 100644
--- a/core/modules/layout_builder/tests/src/Unit/LayoutTempstoreRepositoryTest.php
+++ b/core/modules/layout_builder/tests/src/Unit/LayoutTempstoreRepositoryTest.php
@@ -5,8 +5,8 @@ namespace Drupal\Tests\layout_builder\Unit;
use Drupal\layout_builder\LayoutTempstoreRepository;
use Drupal\layout_builder\SectionStorageInterface;
use Drupal\Tests\UnitTestCase;
-use Drupal\user\SharedTempStore;
-use Drupal\user\SharedTempStoreFactory;
+use Drupal\Core\TempStore\SharedTempStore;
+use Drupal\Core\TempStore\SharedTempStoreFactory;
/**
* @coversDefaultClass \Drupal\layout_builder\LayoutTempstoreRepository
diff --git a/core/modules/media/src/Form/MediaDeleteMultipleConfirmForm.php b/core/modules/media/src/Form/MediaDeleteMultipleConfirmForm.php
index 616a567..6659887 100644
--- a/core/modules/media/src/Form/MediaDeleteMultipleConfirmForm.php
+++ b/core/modules/media/src/Form/MediaDeleteMultipleConfirmForm.php
@@ -6,7 +6,7 @@ use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\ConfirmFormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;
-use Drupal\user\PrivateTempStoreFactory;
+use Drupal\Core\TempStore\PrivateTempStoreFactory;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
@@ -27,7 +27,7 @@ class MediaDeleteMultipleConfirmForm extends ConfirmFormBase {
/**
* The tempstore factory.
*
- * @var \Drupal\user\PrivateTempStoreFactory
+ * @var \Drupal\Core\TempStore\PrivateTempStoreFactory
*/
protected $tempStoreFactory;
@@ -41,7 +41,7 @@ class MediaDeleteMultipleConfirmForm extends ConfirmFormBase {
/**
* Constructs a MediaDeleteMultipleConfirmForm form object.
*
- * @param \Drupal\user\PrivateTempStoreFactory $temp_store_factory
+ * @param \Drupal\Core\TempStore\PrivateTempStoreFactory $temp_store_factory
* The tempstore factory.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $manager
* The entity type manager.
@@ -56,7 +56,7 @@ class MediaDeleteMultipleConfirmForm extends ConfirmFormBase {
*/
public static function create(ContainerInterface $container) {
return new static(
- $container->get('user.private_tempstore'),
+ $container->get('tempstore.private'),
$container->get('entity_type.manager')
);
}
diff --git a/core/modules/node/node.services.yml b/core/modules/node/node.services.yml
index 2ff32c3..f94a4bb 100644
--- a/core/modules/node/node.services.yml
+++ b/core/modules/node/node.services.yml
@@ -30,7 +30,7 @@ services:
- { name: event_subscriber }
node_preview:
class: Drupal\node\ParamConverter\NodePreviewConverter
- arguments: ['@user.private_tempstore']
+ arguments: ['@tempstore.private']
tags:
- { name: paramconverter }
lazy: true
diff --git a/core/modules/node/src/Form/DeleteMultiple.php b/core/modules/node/src/Form/DeleteMultiple.php
index 8bc8f06..ef2c89f 100644
--- a/core/modules/node/src/Form/DeleteMultiple.php
+++ b/core/modules/node/src/Form/DeleteMultiple.php
@@ -6,7 +6,7 @@ use Drupal\Core\Entity\EntityManagerInterface;
use Drupal\Core\Form\ConfirmFormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;
-use Drupal\user\PrivateTempStoreFactory;
+use Drupal\Core\TempStore\PrivateTempStoreFactory;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
@@ -27,7 +27,7 @@ class DeleteMultiple extends ConfirmFormBase {
/**
* The tempstore factory.
*
- * @var \Drupal\user\PrivateTempStoreFactory
+ * @var \Drupal\Core\TempStore\PrivateTempStoreFactory
*/
protected $tempStoreFactory;
@@ -41,7 +41,7 @@ class DeleteMultiple extends ConfirmFormBase {
/**
* Constructs a DeleteMultiple form object.
*
- * @param \Drupal\user\PrivateTempStoreFactory $temp_store_factory
+ * @param \Drupal\Core\TempStore\PrivateTempStoreFactory $temp_store_factory
* The tempstore factory.
* @param \Drupal\Core\Entity\EntityManagerInterface $manager
* The entity manager.
@@ -56,7 +56,7 @@ class DeleteMultiple extends ConfirmFormBase {
*/
public static function create(ContainerInterface $container) {
return new static(
- $container->get('user.private_tempstore'),
+ $container->get('tempstore.private'),
$container->get('entity.manager')
);
}
diff --git a/core/modules/node/src/NodeForm.php b/core/modules/node/src/NodeForm.php
index 0513d1f..0ad34ad 100644
--- a/core/modules/node/src/NodeForm.php
+++ b/core/modules/node/src/NodeForm.php
@@ -8,7 +8,7 @@ use Drupal\Core\Entity\EntityManagerInterface;
use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Session\AccountInterface;
-use Drupal\user\PrivateTempStoreFactory;
+use Drupal\Core\TempStore\PrivateTempStoreFactory;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
@@ -21,7 +21,7 @@ class NodeForm extends ContentEntityForm {
/**
* The tempstore factory.
*
- * @var \Drupal\user\PrivateTempStoreFactory
+ * @var \Drupal\Core\TempStore\PrivateTempStoreFactory
*/
protected $tempStoreFactory;
@@ -37,7 +37,7 @@ class NodeForm extends ContentEntityForm {
*
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
* The entity manager.
- * @param \Drupal\user\PrivateTempStoreFactory $temp_store_factory
+ * @param \Drupal\Core\TempStore\PrivateTempStoreFactory $temp_store_factory
* The factory for the temp store object.
* @param \Drupal\Core\Entity\EntityTypeBundleInfoInterface $entity_type_bundle_info
* The entity type bundle service.
@@ -58,7 +58,7 @@ class NodeForm extends ContentEntityForm {
public static function create(ContainerInterface $container) {
return new static(
$container->get('entity.manager'),
- $container->get('user.private_tempstore'),
+ $container->get('tempstore.private'),
$container->get('entity_type.bundle.info'),
$container->get('datetime.time'),
$container->get('current_user')
diff --git a/core/modules/node/src/ParamConverter/NodePreviewConverter.php b/core/modules/node/src/ParamConverter/NodePreviewConverter.php
index b75d062..a40301a 100644
--- a/core/modules/node/src/ParamConverter/NodePreviewConverter.php
+++ b/core/modules/node/src/ParamConverter/NodePreviewConverter.php
@@ -2,7 +2,7 @@
namespace Drupal\node\ParamConverter;
-use Drupal\user\PrivateTempStoreFactory;
+use Drupal\Core\TempStore\PrivateTempStoreFactory;
use Symfony\Component\Routing\Route;
use Drupal\Core\ParamConverter\ParamConverterInterface;
@@ -14,14 +14,14 @@ class NodePreviewConverter implements ParamConverterInterface {
/**
* Stores the tempstore factory.
*
- * @var \Drupal\user\PrivateTempStoreFactory
+ * @var \Drupal\Core\TempStore\PrivateTempStoreFactory
*/
protected $tempStoreFactory;
/**
* Constructs a new NodePreviewConverter.
*
- * @param \Drupal\user\PrivateTempStoreFactory $temp_store_factory
+ * @param \Drupal\Core\TempStore\PrivateTempStoreFactory $temp_store_factory
* The factory for the temp store object.
*/
public function __construct(PrivateTempStoreFactory $temp_store_factory) {
diff --git a/core/modules/node/src/Plugin/Action/DeleteNode.php b/core/modules/node/src/Plugin/Action/DeleteNode.php
index c4d1aeb..19f8a7a 100644
--- a/core/modules/node/src/Plugin/Action/DeleteNode.php
+++ b/core/modules/node/src/Plugin/Action/DeleteNode.php
@@ -5,7 +5,7 @@ namespace Drupal\node\Plugin\Action;
use Drupal\Core\Action\ActionBase;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Session\AccountInterface;
-use Drupal\user\PrivateTempStoreFactory;
+use Drupal\Core\TempStore\PrivateTempStoreFactory;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
@@ -23,7 +23,7 @@ class DeleteNode extends ActionBase implements ContainerFactoryPluginInterface {
/**
* The tempstore object.
*
- * @var \Drupal\user\SharedTempStore
+ * @var \Drupal\Core\TempStore\SharedTempStore
*/
protected $tempStore;
@@ -43,7 +43,7 @@ class DeleteNode extends ActionBase implements ContainerFactoryPluginInterface {
* The plugin ID for the plugin instance.
* @param mixed $plugin_definition
* The plugin implementation definition.
- * @param \Drupal\user\PrivateTempStoreFactory $temp_store_factory
+ * @param \Drupal\Core\TempStore\PrivateTempStoreFactory $temp_store_factory
* The tempstore factory.
* @param \Drupal\Core\Session\AccountInterface $current_user
* Current user.
@@ -63,7 +63,7 @@ class DeleteNode extends ActionBase implements ContainerFactoryPluginInterface {
$configuration,
$plugin_id,
$plugin_definition,
- $container->get('user.private_tempstore'),
+ $container->get('tempstore.private'),
$container->get('current_user')
);
}
diff --git a/core/modules/quickedit/src/Form/QuickEditFieldForm.php b/core/modules/quickedit/src/Form/QuickEditFieldForm.php
index a9e0671..c092167 100644
--- a/core/modules/quickedit/src/Form/QuickEditFieldForm.php
+++ b/core/modules/quickedit/src/Form/QuickEditFieldForm.php
@@ -10,7 +10,7 @@ use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\Element;
use Drupal\Core\Entity\Entity\EntityFormDisplay;
-use Drupal\user\PrivateTempStoreFactory;
+use Drupal\Core\TempStore\PrivateTempStoreFactory;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Validator\Validator\ValidatorInterface;
@@ -24,7 +24,7 @@ class QuickEditFieldForm extends FormBase {
/**
* Stores the tempstore factory.
*
- * @var \Drupal\user\PrivateTempStoreFactory
+ * @var \Drupal\Core\TempStore\PrivateTempStoreFactory
*/
protected $tempStoreFactory;
@@ -52,7 +52,7 @@ class QuickEditFieldForm extends FormBase {
/**
* Constructs a new EditFieldForm.
*
- * @param \Drupal\user\PrivateTempStoreFactory $temp_store_factory
+ * @param \Drupal\Core\TempStore\PrivateTempStoreFactory $temp_store_factory
* The tempstore factory.
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
* The module handler.
@@ -73,7 +73,7 @@ class QuickEditFieldForm extends FormBase {
*/
public static function create(ContainerInterface $container) {
return new static(
- $container->get('user.private_tempstore'),
+ $container->get('tempstore.private'),
$container->get('module_handler'),
$container->get('entity.manager')->getStorage('node_type'),
$container->get('typed_data_manager')->getValidator()
diff --git a/core/modules/quickedit/src/QuickEditController.php b/core/modules/quickedit/src/QuickEditController.php
index 2b1e4b2..0f470b1 100644
--- a/core/modules/quickedit/src/QuickEditController.php
+++ b/core/modules/quickedit/src/QuickEditController.php
@@ -5,7 +5,7 @@ namespace Drupal\quickedit;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Form\FormState;
use Drupal\Core\Render\RendererInterface;
-use Drupal\user\PrivateTempStoreFactory;
+use Drupal\Core\TempStore\PrivateTempStoreFactory;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
@@ -25,7 +25,7 @@ class QuickEditController extends ControllerBase {
/**
* The PrivateTempStore factory.
*
- * @var \Drupal\user\PrivateTempStoreFactory
+ * @var \Drupal\Core\TempStore\PrivateTempStoreFactory
*/
protected $tempStoreFactory;
@@ -53,7 +53,7 @@ class QuickEditController extends ControllerBase {
/**
* Constructs a new QuickEditController.
*
- * @param \Drupal\user\PrivateTempStoreFactory $temp_store_factory
+ * @param \Drupal\Core\TempStore\PrivateTempStoreFactory $temp_store_factory
* The PrivateTempStore factory.
* @param \Drupal\quickedit\MetadataGeneratorInterface $metadata_generator
* The in-place editing metadata generator.
@@ -74,7 +74,7 @@ class QuickEditController extends ControllerBase {
*/
public static function create(ContainerInterface $container) {
return new static(
- $container->get('user.private_tempstore'),
+ $container->get('tempstore.private'),
$container->get('quickedit.metadata.generator'),
$container->get('quickedit.editor.selector'),
$container->get('renderer')
diff --git a/core/modules/user/src/Form/UserMultipleCancelConfirm.php b/core/modules/user/src/Form/UserMultipleCancelConfirm.php
index 985d199..b4487c2 100644
--- a/core/modules/user/src/Form/UserMultipleCancelConfirm.php
+++ b/core/modules/user/src/Form/UserMultipleCancelConfirm.php
@@ -6,7 +6,7 @@ use Drupal\Core\Entity\EntityManagerInterface;
use Drupal\Core\Form\ConfirmFormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;
-use Drupal\user\PrivateTempStoreFactory;
+use Drupal\Core\TempStore\PrivateTempStoreFactory;
use Drupal\user\UserStorageInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -20,7 +20,7 @@ class UserMultipleCancelConfirm extends ConfirmFormBase {
/**
* The temp store factory.
*
- * @var \Drupal\user\PrivateTempStoreFactory
+ * @var \Drupal\Core\TempStore\PrivateTempStoreFactory
*/
protected $tempStoreFactory;
@@ -41,7 +41,7 @@ class UserMultipleCancelConfirm extends ConfirmFormBase {
/**
* Constructs a new UserMultipleCancelConfirm.
*
- * @param \Drupal\user\PrivateTempStoreFactory $temp_store_factory
+ * @param \Drupal\Core\TempStore\PrivateTempStoreFactory $temp_store_factory
* The temp store factory.
* @param \Drupal\user\UserStorageInterface $user_storage
* The user storage.
@@ -59,7 +59,7 @@ class UserMultipleCancelConfirm extends ConfirmFormBase {
*/
public static function create(ContainerInterface $container) {
return new static(
- $container->get('user.private_tempstore'),
+ $container->get('tempstore.private'),
$container->get('entity.manager')->getStorage('user'),
$container->get('entity.manager')
);
diff --git a/core/modules/user/src/Plugin/Action/CancelUser.php b/core/modules/user/src/Plugin/Action/CancelUser.php
index 60ae156..e9726b4 100644
--- a/core/modules/user/src/Plugin/Action/CancelUser.php
+++ b/core/modules/user/src/Plugin/Action/CancelUser.php
@@ -5,7 +5,7 @@ namespace Drupal\user\Plugin\Action;
use Drupal\Core\Action\ActionBase;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Session\AccountInterface;
-use Drupal\user\PrivateTempStoreFactory;
+use Drupal\Core\TempStore\PrivateTempStoreFactory;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
@@ -23,7 +23,7 @@ class CancelUser extends ActionBase implements ContainerFactoryPluginInterface {
/**
* The tempstore factory.
*
- * @var \Drupal\user\PrivateTempStoreFactory
+ * @var \Drupal\Core\TempStore\PrivateTempStoreFactory
*/
protected $tempStoreFactory;
@@ -43,7 +43,7 @@ class CancelUser extends ActionBase implements ContainerFactoryPluginInterface {
* The plugin ID for the plugin instance.
* @param mixed $plugin_definition
* The plugin implementation definition.
- * @param \Drupal\user\PrivateTempStoreFactory $temp_store_factory
+ * @param \Drupal\Core\TempStore\PrivateTempStoreFactory $temp_store_factory
* The tempstore factory.
* @param \Drupal\Core\Session\AccountInterface $current_user
* Current user.
@@ -63,7 +63,7 @@ class CancelUser extends ActionBase implements ContainerFactoryPluginInterface {
$configuration,
$plugin_id,
$plugin_definition,
- $container->get('user.private_tempstore'),
+ $container->get('tempstore.private'),
$container->get('current_user')
);
}
diff --git a/core/modules/user/src/PrivateTempStore.php b/core/modules/user/src/PrivateTempStore.php
index 786ff1e..8b0bc43 100644
--- a/core/modules/user/src/PrivateTempStore.php
+++ b/core/modules/user/src/PrivateTempStore.php
@@ -2,212 +2,25 @@
namespace Drupal\user;
-use Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface;
-use Drupal\Core\Lock\LockBackendInterface;
-use Drupal\Core\Session\AccountProxyInterface;
-use Symfony\Component\HttpFoundation\RequestStack;
+use Drupal\Core\TempStore\PrivateTempStore as CorePrivateTempStore;
+
+@trigger_error('\Drupal\user\PrivateTempStore is scheduled for removal in Drupal 9.0.0. Use \Drupal\Core\TempStore\PrivateTempStore instead. See https://www.drupal.org/node/2935639.', E_USER_DEPRECATED);
+
+/**
+ * In order to preserve BC alias the core exception.
+ */
+if (!class_exists('\Drupal\user\TempStoreException')) {
+ class_alias('\Drupal\Core\TempStore\TempStoreException', '\Drupal\user\TempStoreException');
+}
/**
* Stores and retrieves temporary data for a given owner.
*
- * A PrivateTempStore can be used to make temporary, non-cache data available
- * across requests. The data for the PrivateTempStore is stored in one
- * key/value collection. PrivateTempStore data expires automatically after a
- * given timeframe.
+ * @deprecated in Drupal 8.5.x, to be removed before Drupal 9.0.0.
+ * Use \Drupal\Core\TempStore\PrivateTempStore instead.
*
- * The PrivateTempStore is different from a cache, because the data in it is not
- * yet saved permanently and so it cannot be rebuilt. Typically, the
- * PrivateTempStore might be used to store work in progress that is later saved
- * permanently elsewhere, e.g. autosave data, multistep forms, or in-progress
- * changes to complex configuration that are not ready to be saved.
- *
- * The PrivateTempStore differs from the SharedTempStore in that all keys are
- * ensured to be unique for a particular user and users can never share data. If
- * you want to be able to share data between users or use it for locking, use
- * \Drupal\user\SharedTempStore.
+ * @see \Drupal\Core\TempStore\PrivateTempStore
+ * @see https://www.drupal.org/node/2935639
*/
-class PrivateTempStore {
-
- /**
- * The key/value storage object used for this data.
- *
- * @var \Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface
- */
- protected $storage;
-
- /**
- * The lock object used for this data.
- *
- * @var \Drupal\Core\Lock\LockBackendInterface
- */
- protected $lockBackend;
-
- /**
- * The current user.
- *
- * @var \Drupal\Core\Session\AccountProxyInterface
- */
- protected $currentUser;
-
- /**
- * The request stack.
- *
- * @var \Symfony\Component\HttpFoundation\RequestStack
- */
- protected $requestStack;
-
- /**
- * The time to live for items in seconds.
- *
- * By default, data is stored for one week (604800 seconds) before expiring.
- *
- * @var int
- */
- protected $expire;
-
- /**
- * Constructs a new object for accessing data from a key/value store.
- *
- * @param \Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface $storage
- * The key/value storage object used for this data. Each storage object
- * represents a particular collection of data and will contain any number
- * of key/value pairs.
- * @param \Drupal\Core\Lock\LockBackendInterface $lock_backend
- * The lock object used for this data.
- * @param \Drupal\Core\Session\AccountProxyInterface $current_user
- * The current user account.
- * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
- * The request stack.
- * @param int $expire
- * The time to live for items, in seconds.
- */
- public function __construct(KeyValueStoreExpirableInterface $storage, LockBackendInterface $lock_backend, AccountProxyInterface $current_user, RequestStack $request_stack, $expire = 604800) {
- $this->storage = $storage;
- $this->lockBackend = $lock_backend;
- $this->currentUser = $current_user;
- $this->requestStack = $request_stack;
- $this->expire = $expire;
- }
-
- /**
- * Retrieves a value from this PrivateTempStore for a given key.
- *
- * @param string $key
- * The key of the data to retrieve.
- *
- * @return mixed
- * The data associated with the key, or NULL if the key does not exist.
- */
- public function get($key) {
- $key = $this->createkey($key);
- if (($object = $this->storage->get($key)) && ($object->owner == $this->getOwner())) {
- return $object->data;
- }
- }
-
- /**
- * Stores a particular key/value pair in this PrivateTempStore.
- *
- * @param string $key
- * The key of the data to store.
- * @param mixed $value
- * The data to store.
- *
- * @throws \Drupal\user\TempStoreException
- * Thrown when a lock for the backend storage could not be acquired.
- */
- public function set($key, $value) {
- $key = $this->createkey($key);
- if (!$this->lockBackend->acquire($key)) {
- $this->lockBackend->wait($key);
- if (!$this->lockBackend->acquire($key)) {
- throw new TempStoreException("Couldn't acquire lock to update item '$key' in '{$this->storage->getCollectionName()}' temporary storage.");
- }
- }
-
- $value = (object) [
- 'owner' => $this->getOwner(),
- 'data' => $value,
- 'updated' => (int) $this->requestStack->getMasterRequest()->server->get('REQUEST_TIME'),
- ];
- $this->storage->setWithExpire($key, $value, $this->expire);
- $this->lockBackend->release($key);
- }
-
- /**
- * Returns the metadata associated with a particular key/value pair.
- *
- * @param string $key
- * The key of the data to store.
- *
- * @return mixed
- * An object with the owner and updated time if the key has a value, or
- * NULL otherwise.
- */
- public function getMetadata($key) {
- $key = $this->createkey($key);
- // Fetch the key/value pair and its metadata.
- $object = $this->storage->get($key);
- if ($object) {
- // Don't keep the data itself in memory.
- unset($object->data);
- return $object;
- }
- }
-
- /**
- * Deletes data from the store for a given key and releases the lock on it.
- *
- * @param string $key
- * The key of the data to delete.
- *
- * @return bool
- * TRUE if the object was deleted or does not exist, FALSE if it exists but
- * is not owned by $this->owner.
- *
- * @throws \Drupal\user\TempStoreException
- * Thrown when a lock for the backend storage could not be acquired.
- */
- public function delete($key) {
- $key = $this->createkey($key);
- if (!$object = $this->storage->get($key)) {
- return TRUE;
- }
- elseif ($object->owner != $this->getOwner()) {
- return FALSE;
- }
- if (!$this->lockBackend->acquire($key)) {
- $this->lockBackend->wait($key);
- if (!$this->lockBackend->acquire($key)) {
- throw new TempStoreException("Couldn't acquire lock to delete item '$key' from '{$this->storage->getCollectionName()}' temporary storage.");
- }
- }
- $this->storage->delete($key);
- $this->lockBackend->release($key);
- return TRUE;
- }
-
- /**
- * Ensures that the key is unique for a user.
- *
- * @param string $key
- * The key.
- *
- * @return string
- * The unique key for the user.
- */
- protected function createkey($key) {
- return $this->getOwner() . ':' . $key;
- }
-
- /**
- * Gets the current owner based on the current user or the session ID.
- *
- * @return string
- * The owner.
- */
- protected function getOwner() {
- return $this->currentUser->id() ?: $this->requestStack->getCurrentRequest()->getSession()->getId();
- }
-
+class PrivateTempStore extends CorePrivateTempStore {
}
diff --git a/core/modules/user/src/PrivateTempStoreFactory.php b/core/modules/user/src/PrivateTempStoreFactory.php
index e51faf3..21d6bd1 100644
--- a/core/modules/user/src/PrivateTempStoreFactory.php
+++ b/core/modules/user/src/PrivateTempStoreFactory.php
@@ -2,72 +2,20 @@
namespace Drupal\user;
-use Drupal\Core\KeyValueStore\KeyValueExpirableFactoryInterface;
-use Drupal\Core\Lock\LockBackendInterface;
-use Drupal\Core\Session\AccountProxyInterface;
-use Symfony\Component\HttpFoundation\RequestStack;
+use Drupal\Core\TempStore\PrivateTempStoreFactory as CorePrivateTempStoreFactory;
+
+@trigger_error('\Drupal\user\PrivateTempStoreFactory is scheduled for removal in Drupal 9.0.0. Use \Drupal\Core\TempStore\PrivateTempStoreFactory instead. See https://www.drupal.org/node/2935639.', E_USER_DEPRECATED);
/**
* Creates a PrivateTempStore object for a given collection.
+ *
+ * @deprecated in Drupal 8.5.x, to be removed before Drupal 9.0.0.
+ * Use \Drupal\Core\TempStore\PrivateTempStoreFactory instead.
+ *
+ * @see \Drupal\Core\TempStore\PrivateTempStoreFactory
+ * @see https://www.drupal.org/node/2935639
*/
-class PrivateTempStoreFactory {
-
- /**
- * The storage factory creating the backend to store the data.
- *
- * @var \Drupal\Core\KeyValueStore\KeyValueExpirableFactoryInterface
- */
- protected $storageFactory;
-
- /**
- * The lock object used for this data.
- *
- * @var \Drupal\Core\Lock\LockBackendInterface
- */
- protected $lockBackend;
-
- /**
- * The current user.
- *
- * @var \Drupal\Core\Session\AccountProxyInterface
- */
- protected $currentUser;
-
- /**
- * The request stack.
- *
- * @var \Symfony\Component\HttpFoundation\RequestStack
- */
- protected $requestStack;
-
- /**
- * The time to live for items in seconds.
- *
- * @var int
- */
- protected $expire;
-
- /**
- * Constructs a Drupal\user\PrivateTempStoreFactory object.
- *
- * @param \Drupal\Core\KeyValueStore\KeyValueExpirableFactoryInterface $storage_factory
- * The key/value store factory.
- * @param \Drupal\Core\Lock\LockBackendInterface $lock_backend
- * The lock object used for this data.
- * @param \Drupal\Core\Session\AccountProxyInterface $current_user
- * The current account.
- * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
- * The request stack.
- * @param int $expire
- * The time to live for items, in seconds.
- */
- public function __construct(KeyValueExpirableFactoryInterface $storage_factory, LockBackendInterface $lock_backend, AccountProxyInterface $current_user, RequestStack $request_stack, $expire = 604800) {
- $this->storageFactory = $storage_factory;
- $this->lockBackend = $lock_backend;
- $this->currentUser = $current_user;
- $this->requestStack = $request_stack;
- $this->expire = $expire;
- }
+class PrivateTempStoreFactory extends CorePrivateTempStoreFactory {
/**
* Creates a PrivateTempStore.
diff --git a/core/modules/user/src/SharedTempStore.php b/core/modules/user/src/SharedTempStore.php
index 91a622b..1802110 100644
--- a/core/modules/user/src/SharedTempStore.php
+++ b/core/modules/user/src/SharedTempStore.php
@@ -2,278 +2,25 @@
namespace Drupal\user;
-use Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface;
-use Drupal\Core\Lock\LockBackendInterface;
-use Symfony\Component\HttpFoundation\RequestStack;
+use Drupal\Core\TempStore\SharedTempStore as CoreSharedTempStore;
+
+@trigger_error('\Drupal\user\SharedTempStore is scheduled for removal in Drupal 9.0.0. Use \Drupal\Core\TempStore\SharedTempStore instead. See https://www.drupal.org/node/2935639.', E_USER_DEPRECATED);
+
+/**
+ * In order to preserve BC alias the core exception.
+ */
+if (!class_exists('\Drupal\user\TempStoreException')) {
+ class_alias('\Drupal\Core\TempStore\TempStoreException', '\Drupal\user\TempStoreException');
+}
/**
* Stores and retrieves temporary data for a given owner.
*
- * A SharedTempStore can be used to make temporary, non-cache data available
- * across requests. The data for the SharedTempStore is stored in one key/value
- * collection. SharedTempStore data expires automatically after a given
- * timeframe.
- *
- * The SharedTempStore is different from a cache, because the data in it is not
- * yet saved permanently and so it cannot be rebuilt. Typically, the
- * SharedTempStore might be used to store work in progress that is later saved
- * permanently elsewhere, e.g. autosave data, multistep forms, or in-progress
- * changes to complex configuration that are not ready to be saved.
- *
- * Each SharedTempStore belongs to a particular owner (e.g. a user, session, or
- * process). Multiple owners may use the same key/value collection, and the
- * owner is stored along with the key/value pair.
+ * @deprecated in Drupal 8.5.x, to be removed before Drupal 9.0.0.
+ * Use \Drupal\Core\TempStore\SharedTempStore instead.
*
- * Every key is unique within the collection, so the SharedTempStore can check
- * whether a particular key is already set by a different owner. This is
- * useful for informing one owner that the data is already in use by another;
- * for example, to let one user know that another user is in the process of
- * editing certain data, or even to restrict other users from editing it at
- * the same time. It is the responsibility of the implementation to decide
- * when and whether one owner can use or update another owner's data.
- *
- * If you want to be able to ensure that the data belongs to the current user,
- * use \Drupal\user\PrivateTempStore.
+ * @see \Drupal\Core\TempStore\SharedTempStore
+ * @see https://www.drupal.org/node/2935639
*/
-class SharedTempStore {
-
- /**
- * The key/value storage object used for this data.
- *
- * @var \Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface
- */
- protected $storage;
-
- /**
- * The lock object used for this data.
- *
- * @var \Drupal\Core\Lock\LockBackendInterface
- */
- protected $lockBackend;
-
- /**
- * The request stack.
- *
- * @var \Symfony\Component\HttpFoundation\RequestStack
- */
- protected $requestStack;
-
- /**
- * The owner key to store along with the data (e.g. a user or session ID).
- *
- * @var mixed
- */
- protected $owner;
-
- /**
- * The time to live for items in seconds.
- *
- * By default, data is stored for one week (604800 seconds) before expiring.
- *
- * @var int
- */
- protected $expire;
-
- /**
- * Constructs a new object for accessing data from a key/value store.
- *
- * @param \Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface $storage
- * The key/value storage object used for this data. Each storage object
- * represents a particular collection of data and will contain any number
- * of key/value pairs.
- * @param \Drupal\Core\Lock\LockBackendInterface $lock_backend
- * The lock object used for this data.
- * @param mixed $owner
- * The owner key to store along with the data (e.g. a user or session ID).
- * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
- * The request stack.
- * @param int $expire
- * The time to live for items, in seconds.
- */
- public function __construct(KeyValueStoreExpirableInterface $storage, LockBackendInterface $lock_backend, $owner, RequestStack $request_stack, $expire = 604800) {
- $this->storage = $storage;
- $this->lockBackend = $lock_backend;
- $this->owner = $owner;
- $this->requestStack = $request_stack;
- $this->expire = $expire;
- }
-
- /**
- * Retrieves a value from this SharedTempStore for a given key.
- *
- * @param string $key
- * The key of the data to retrieve.
- *
- * @return mixed
- * The data associated with the key, or NULL if the key does not exist.
- */
- public function get($key) {
- if ($object = $this->storage->get($key)) {
- return $object->data;
- }
- }
-
- /**
- * Retrieves a value from this SharedTempStore for a given key.
- *
- * Only returns the value if the value is owned by $this->owner.
- *
- * @param string $key
- * The key of the data to retrieve.
- *
- * @return mixed
- * The data associated with the key, or NULL if the key does not exist.
- */
- public function getIfOwner($key) {
- if (($object = $this->storage->get($key)) && ($object->owner == $this->owner)) {
- return $object->data;
- }
- }
-
- /**
- * Stores a particular key/value pair only if the key doesn't already exist.
- *
- * @param string $key
- * The key of the data to check and store.
- * @param mixed $value
- * The data to store.
- *
- * @return bool
- * TRUE if the data was set, or FALSE if it already existed.
- */
- public function setIfNotExists($key, $value) {
- $value = (object) [
- 'owner' => $this->owner,
- 'data' => $value,
- 'updated' => (int) $this->requestStack->getMasterRequest()->server->get('REQUEST_TIME'),
- ];
- return $this->storage->setWithExpireIfNotExists($key, $value, $this->expire);
- }
-
- /**
- * Stores a particular key/value pair in this SharedTempStore.
- *
- * Only stores the given key/value pair if it does not exist yet or is owned
- * by $this->owner.
- *
- * @param string $key
- * The key of the data to store.
- * @param mixed $value
- * The data to store.
- *
- * @return bool
- * TRUE if the data was set, or FALSE if it already exists and is not owned
- * by $this->user.
- *
- * @throws \Drupal\user\TempStoreException
- * Thrown when a lock for the backend storage could not be acquired.
- */
- public function setIfOwner($key, $value) {
- if ($this->setIfNotExists($key, $value)) {
- return TRUE;
- }
-
- if (($object = $this->storage->get($key)) && ($object->owner == $this->owner)) {
- $this->set($key, $value);
- return TRUE;
- }
-
- return FALSE;
- }
-
- /**
- * Stores a particular key/value pair in this SharedTempStore.
- *
- * @param string $key
- * The key of the data to store.
- * @param mixed $value
- * The data to store.
- *
- * @throws \Drupal\user\TempStoreException
- * Thrown when a lock for the backend storage could not be acquired.
- */
- public function set($key, $value) {
- if (!$this->lockBackend->acquire($key)) {
- $this->lockBackend->wait($key);
- if (!$this->lockBackend->acquire($key)) {
- throw new TempStoreException("Couldn't acquire lock to update item '$key' in '{$this->storage->getCollectionName()}' temporary storage.");
- }
- }
-
- $value = (object) [
- 'owner' => $this->owner,
- 'data' => $value,
- 'updated' => (int) $this->requestStack->getMasterRequest()->server->get('REQUEST_TIME'),
- ];
- $this->storage->setWithExpire($key, $value, $this->expire);
- $this->lockBackend->release($key);
- }
-
- /**
- * Returns the metadata associated with a particular key/value pair.
- *
- * @param string $key
- * The key of the data to store.
- *
- * @return mixed
- * An object with the owner and updated time if the key has a value, or
- * NULL otherwise.
- */
- public function getMetadata($key) {
- // Fetch the key/value pair and its metadata.
- $object = $this->storage->get($key);
- if ($object) {
- // Don't keep the data itself in memory.
- unset($object->data);
- return $object;
- }
- }
-
- /**
- * Deletes data from the store for a given key and releases the lock on it.
- *
- * @param string $key
- * The key of the data to delete.
- *
- * @throws \Drupal\user\TempStoreException
- * Thrown when a lock for the backend storage could not be acquired.
- */
- public function delete($key) {
- if (!$this->lockBackend->acquire($key)) {
- $this->lockBackend->wait($key);
- if (!$this->lockBackend->acquire($key)) {
- throw new TempStoreException("Couldn't acquire lock to delete item '$key' from {$this->storage->getCollectionName()} temporary storage.");
- }
- }
- $this->storage->delete($key);
- $this->lockBackend->release($key);
- }
-
- /**
- * Deletes data from the store for a given key and releases the lock on it.
- *
- * Only delete the given key if it is owned by $this->owner.
- *
- * @param string $key
- * The key of the data to delete.
- *
- * @return bool
- * TRUE if the object was deleted or does not exist, FALSE if it exists but
- * is not owned by $this->owner.
- *
- * @throws \Drupal\user\TempStoreException
- * Thrown when a lock for the backend storage could not be acquired.
- */
- public function deleteIfOwner($key) {
- if (!$object = $this->storage->get($key)) {
- return TRUE;
- }
- elseif ($object->owner == $this->owner) {
- $this->delete($key);
- return TRUE;
- }
-
- return FALSE;
- }
-
+class SharedTempStore extends CoreSharedTempStore {
}
diff --git a/core/modules/user/src/SharedTempStoreFactory.php b/core/modules/user/src/SharedTempStoreFactory.php
index 29f8683..c955f07 100644
--- a/core/modules/user/src/SharedTempStoreFactory.php
+++ b/core/modules/user/src/SharedTempStoreFactory.php
@@ -2,61 +2,20 @@
namespace Drupal\user;
-use Drupal\Core\KeyValueStore\KeyValueExpirableFactoryInterface;
-use Drupal\Core\Lock\LockBackendInterface;
-use Symfony\Component\HttpFoundation\RequestStack;
+use Drupal\Core\TempStore\SharedTempStoreFactory as CoreSharedTempStoreFactory;
+
+@trigger_error('\Drupal\user\SharedTempStoreFactory is scheduled for removal in Drupal 9.0.0. Use \Drupal\Core\TempStore\SharedTempStoreFactory instead. See https://www.drupal.org/node/2935639.', E_USER_DEPRECATED);
/**
* Creates a shared temporary storage for a collection.
+ *
+ * @deprecated in Drupal 8.5.x, to be removed before Drupal 9.0.0.
+ * Use \Drupal\Core\TempStore\SharedTempStoreFactory instead.
+ *
+ * @see \Drupal\Core\TempStore\SharedTempStoreFactory
+ * @see https://www.drupal.org/node/2935639
*/
-class SharedTempStoreFactory {
-
- /**
- * The storage factory creating the backend to store the data.
- *
- * @var \Drupal\Core\KeyValueStore\KeyValueExpirableFactoryInterface
- */
- protected $storageFactory;
-
- /**
- * The lock object used for this data.
- *
- * @var \Drupal\Core\Lock\LockBackendInterface
- */
- protected $lockBackend;
-
- /**
- * The request stack.
- *
- * @var \Symfony\Component\HttpFoundation\RequestStack
- */
- protected $requestStack;
-
- /**
- * The time to live for items in seconds.
- *
- * @var int
- */
- protected $expire;
-
- /**
- * Constructs a Drupal\user\SharedTempStoreFactory object.
- *
- * @param \Drupal\Core\KeyValueStore\KeyValueExpirableFactoryInterface $storage_factory
- * The key/value store factory.
- * @param \Drupal\Core\Lock\LockBackendInterface $lock_backend
- * The lock object used for this data.
- * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
- * The request stack.
- * @param int $expire
- * The time to live for items, in seconds.
- */
- public function __construct(KeyValueExpirableFactoryInterface $storage_factory, LockBackendInterface $lock_backend, RequestStack $request_stack, $expire = 604800) {
- $this->storageFactory = $storage_factory;
- $this->lockBackend = $lock_backend;
- $this->requestStack = $request_stack;
- $this->expire = $expire;
- }
+class SharedTempStoreFactory extends CoreSharedTempStoreFactory {
/**
* Creates a SharedTempStore for the current user or anonymous session.
diff --git a/core/modules/user/src/UserServiceProvider.php b/core/modules/user/src/UserServiceProvider.php
index 49537e5..d43604c 100644
--- a/core/modules/user/src/UserServiceProvider.php
+++ b/core/modules/user/src/UserServiceProvider.php
@@ -1,8 +1,20 @@
<?php
-// @codingStandardsIgnoreFile
-// This class is intentionally empty so that it overwrites when sites are
-// updated from a zip/tarball without deleting the /core folder first.
-// @todo: remove in 8.3.x
-//
+
namespace Drupal\user;
-class UserServiceProvider {}
+
+use Drupal\Core\DependencyInjection\ContainerBuilder;
+use Drupal\Core\DependencyInjection\ServiceModifierInterface;
+
+class UserServiceProvider implements ServiceModifierInterface {
+
+ /**
+ * {@inheritdoc}
+ */
+ public function alter(ContainerBuilder $container) {
+ if ($container->hasParameter('user.tempstore.expire')) {
+ @trigger_error('The container parameter "user.tempstore.expire" is deprecated. Use "tempstore.expire" instead. See https://www.drupal.org/node/2935639.', E_USER_DEPRECATED);
+ $container->setParameter('tempstore.expire', $container->getParameter('user.tempstore.expire'));
+ }
+ }
+
+}
diff --git a/core/modules/user/tests/src/Kernel/TempStoreDatabaseTest.php b/core/modules/user/tests/src/Kernel/TempStoreDatabaseTest.php
index b3d7ff1..ae9d4cb 100644
--- a/core/modules/user/tests/src/Kernel/TempStoreDatabaseTest.php
+++ b/core/modules/user/tests/src/Kernel/TempStoreDatabaseTest.php
@@ -12,7 +12,8 @@ use Drupal\Core\Database\Database;
* Tests the temporary object storage system.
*
* @group user
- * @see \Drupal\Core\TempStore\TempStore.
+ * @group legacy
+ * @see \Drupal\user\SharedTempStore
*/
class TempStoreDatabaseTest extends KernelTestBase {
@@ -67,6 +68,9 @@ class TempStoreDatabaseTest extends KernelTestBase {
/**
* Tests the UserTempStore API.
+ *
+ * @expectedDeprecation \Drupal\user\SharedTempStoreFactory is scheduled for removal in Drupal 9.0.0. Use \Drupal\Core\TempStore\SharedTempStoreFactory instead. See https://www.drupal.org/node/2935639.
+ * @expectedDeprecation \Drupal\user\SharedTempStore is scheduled for removal in Drupal 9.0.0. Use \Drupal\Core\TempStore\SharedTempStore instead. See https://www.drupal.org/node/2935639.
*/
public function testUserTempStore() {
// Create a key/value collection.
diff --git a/core/modules/user/tests/src/Kernel/UserServiceProviderTest.php b/core/modules/user/tests/src/Kernel/UserServiceProviderTest.php
new file mode 100644
index 0000000..38f1af1
--- /dev/null
+++ b/core/modules/user/tests/src/Kernel/UserServiceProviderTest.php
@@ -0,0 +1,40 @@
+<?php
+
+namespace Drupal\Tests\user\Kernel;
+
+use Drupal\Core\DependencyInjection\ContainerBuilder;
+use Drupal\KernelTests\KernelTestBase;
+
+/**
+ * Tests \Drupal\user\UserServiceProvider.
+ *
+ * @group user
+ * @group legacy
+ */
+class UserServiceProviderTest extends KernelTestBase {
+
+ /**
+ * Modules to enable.
+ *
+ * @var array
+ */
+ public static $modules = ['user'];
+
+ /**
+ * Tests that tempstore.expire is set to user.tempstore.expire.
+ *
+ * @expectedDeprecation The container parameter "user.tempstore.expire" is deprecated. Use "tempstore.expire" instead. See https://www.drupal.org/node/2935639.
+ */
+ public function testUserServiceProvider() {
+ $this->assertEquals(1000, $this->container->getParameter('tempstore.expire'));
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function register(ContainerBuilder $container) {
+ $container->setParameter('user.tempstore.expire', 1000);
+ parent::register($container);
+ }
+
+}
diff --git a/core/modules/user/tests/src/Unit/PrivateTempStoreTest.php b/core/modules/user/tests/src/Unit/PrivateTempStoreTest.php
index 8d18811..be9376a 100644
--- a/core/modules/user/tests/src/Unit/PrivateTempStoreTest.php
+++ b/core/modules/user/tests/src/Unit/PrivateTempStoreTest.php
@@ -11,6 +11,9 @@ use Symfony\Component\HttpFoundation\RequestStack;
/**
* @coversDefaultClass \Drupal\user\PrivateTempStore
* @group user
+ * @group legacy
+ * @runTestsInSeparateProcesses
+ * @preserveGlobalState disabled
*/
class PrivateTempStoreTest extends UnitTestCase {
@@ -98,6 +101,7 @@ class PrivateTempStoreTest extends UnitTestCase {
* Tests the get() method.
*
* @covers ::get
+ * @expectedDeprecation \Drupal\user\PrivateTempStore is scheduled for removal in Drupal 9.0.0. Use \Drupal\Core\TempStore\PrivateTempStore instead. See https://www.drupal.org/node/2935639.
*/
public function testGet() {
$this->keyValue->expects($this->at(0))
@@ -122,6 +126,7 @@ class PrivateTempStoreTest extends UnitTestCase {
* Tests the set() method with no lock available.
*
* @covers ::set
+ * @expectedDeprecation \Drupal\user\PrivateTempStore is scheduled for removal in Drupal 9.0.0. Use \Drupal\Core\TempStore\PrivateTempStore instead. See https://www.drupal.org/node/2935639.
*/
public function testSetWithNoLockAvailable() {
$this->lock->expects($this->at(0))
@@ -147,6 +152,7 @@ class PrivateTempStoreTest extends UnitTestCase {
* Tests a successful set() call.
*
* @covers ::set
+ * @expectedDeprecation \Drupal\user\PrivateTempStore is scheduled for removal in Drupal 9.0.0. Use \Drupal\Core\TempStore\PrivateTempStore instead. See https://www.drupal.org/node/2935639.
*/
public function testSet() {
$this->lock->expects($this->once())
@@ -170,6 +176,7 @@ class PrivateTempStoreTest extends UnitTestCase {
* Tests the getMetadata() method.
*
* @covers ::getMetadata
+ * @expectedDeprecation \Drupal\user\PrivateTempStore is scheduled for removal in Drupal 9.0.0. Use \Drupal\Core\TempStore\PrivateTempStore instead. See https://www.drupal.org/node/2935639.
*/
public function testGetMetadata() {
$this->keyValue->expects($this->at(0))
@@ -194,6 +201,7 @@ class PrivateTempStoreTest extends UnitTestCase {
* Tests the locking in the delete() method.
*
* @covers ::delete
+ * @expectedDeprecation \Drupal\user\PrivateTempStore is scheduled for removal in Drupal 9.0.0. Use \Drupal\Core\TempStore\PrivateTempStore instead. See https://www.drupal.org/node/2935639.
*/
public function testDeleteLocking() {
$this->keyValue->expects($this->once())
@@ -221,6 +229,7 @@ class PrivateTempStoreTest extends UnitTestCase {
* Tests the delete() method with no lock available.
*
* @covers ::delete
+ * @expectedDeprecation \Drupal\user\PrivateTempStore is scheduled for removal in Drupal 9.0.0. Use \Drupal\Core\TempStore\PrivateTempStore instead. See https://www.drupal.org/node/2935639.
*/
public function testDeleteWithNoLockAvailable() {
$this->keyValue->expects($this->once())
@@ -250,6 +259,7 @@ class PrivateTempStoreTest extends UnitTestCase {
* Tests the delete() method.
*
* @covers ::delete
+ * @expectedDeprecation \Drupal\user\PrivateTempStore is scheduled for removal in Drupal 9.0.0. Use \Drupal\Core\TempStore\PrivateTempStore instead. See https://www.drupal.org/node/2935639.
*/
public function testDelete() {
$this->lock->expects($this->once())
diff --git a/core/modules/user/tests/src/Unit/SharedTempStoreTest.php b/core/modules/user/tests/src/Unit/SharedTempStoreTest.php
index 33bde41..6b5d441 100644
--- a/core/modules/user/tests/src/Unit/SharedTempStoreTest.php
+++ b/core/modules/user/tests/src/Unit/SharedTempStoreTest.php
@@ -11,6 +11,9 @@ use Symfony\Component\HttpFoundation\RequestStack;
/**
* @coversDefaultClass \Drupal\user\SharedTempStore
* @group user
+ * @group legacy
+ * @runTestsInSeparateProcesses
+ * @preserveGlobalState disabled
*/
class SharedTempStoreTest extends UnitTestCase {
@@ -90,6 +93,7 @@ class SharedTempStoreTest extends UnitTestCase {
/**
* @covers ::get
+ * @expectedDeprecation \Drupal\user\SharedTempStore is scheduled for removal in Drupal 9.0.0. Use \Drupal\Core\TempStore\SharedTempStore instead. See https://www.drupal.org/node/2935639.
*/
public function testGet() {
$this->keyValue->expects($this->at(0))
@@ -109,6 +113,7 @@ class SharedTempStoreTest extends UnitTestCase {
* Tests the getIfOwner() method.
*
* @covers ::getIfOwner
+ * @expectedDeprecation \Drupal\user\SharedTempStore is scheduled for removal in Drupal 9.0.0. Use \Drupal\Core\TempStore\SharedTempStore instead. See https://www.drupal.org/node/2935639.
*/
public function testGetIfOwner() {
$this->keyValue->expects($this->at(0))
@@ -133,6 +138,7 @@ class SharedTempStoreTest extends UnitTestCase {
* Tests the set() method with no lock available.
*
* @covers ::set
+ * @expectedDeprecation \Drupal\user\SharedTempStore is scheduled for removal in Drupal 9.0.0. Use \Drupal\Core\TempStore\SharedTempStore instead. See https://www.drupal.org/node/2935639.
*/
public function testSetWithNoLockAvailable() {
$this->lock->expects($this->at(0))
@@ -158,6 +164,7 @@ class SharedTempStoreTest extends UnitTestCase {
* Tests a successful set() call.
*
* @covers ::set
+ * @expectedDeprecation \Drupal\user\SharedTempStore is scheduled for removal in Drupal 9.0.0. Use \Drupal\Core\TempStore\SharedTempStore instead. See https://www.drupal.org/node/2935639.
*/
public function testSet() {
$this->lock->expects($this->once())
@@ -181,6 +188,7 @@ class SharedTempStoreTest extends UnitTestCase {
* Tests the setIfNotExists() methods.
*
* @covers ::setIfNotExists
+ * @expectedDeprecation \Drupal\user\SharedTempStore is scheduled for removal in Drupal 9.0.0. Use \Drupal\Core\TempStore\SharedTempStore instead. See https://www.drupal.org/node/2935639.
*/
public function testSetIfNotExists() {
$this->keyValue->expects($this->once())
@@ -195,6 +203,7 @@ class SharedTempStoreTest extends UnitTestCase {
* Tests the setIfOwner() method when no key exists.
*
* @covers ::setIfOwner
+ * @expectedDeprecation \Drupal\user\SharedTempStore is scheduled for removal in Drupal 9.0.0. Use \Drupal\Core\TempStore\SharedTempStore instead. See https://www.drupal.org/node/2935639.
*/
public function testSetIfOwnerWhenNotExists() {
$this->keyValue->expects($this->once())
@@ -208,6 +217,7 @@ class SharedTempStoreTest extends UnitTestCase {
* Tests the setIfOwner() method when a key already exists but no object.
*
* @covers ::setIfOwner
+ * @expectedDeprecation \Drupal\user\SharedTempStore is scheduled for removal in Drupal 9.0.0. Use \Drupal\Core\TempStore\SharedTempStore instead. See https://www.drupal.org/node/2935639.
*/
public function testSetIfOwnerNoObject() {
$this->keyValue->expects($this->once())
@@ -226,6 +236,7 @@ class SharedTempStoreTest extends UnitTestCase {
* Tests the setIfOwner() method with matching and non matching owners.
*
* @covers ::setIfOwner
+ * @expectedDeprecation \Drupal\user\SharedTempStore is scheduled for removal in Drupal 9.0.0. Use \Drupal\Core\TempStore\SharedTempStore instead. See https://www.drupal.org/node/2935639.
*/
public function testSetIfOwner() {
$this->lock->expects($this->once())
@@ -250,6 +261,7 @@ class SharedTempStoreTest extends UnitTestCase {
* Tests the getMetadata() method.
*
* @covers ::getMetadata
+ * @expectedDeprecation \Drupal\user\SharedTempStore is scheduled for removal in Drupal 9.0.0. Use \Drupal\Core\TempStore\SharedTempStore instead. See https://www.drupal.org/node/2935639.
*/
public function testGetMetadata() {
$this->keyValue->expects($this->at(0))
@@ -274,6 +286,7 @@ class SharedTempStoreTest extends UnitTestCase {
* Tests the delete() method.
*
* @covers ::delete
+ * @expectedDeprecation \Drupal\user\SharedTempStore is scheduled for removal in Drupal 9.0.0. Use \Drupal\Core\TempStore\SharedTempStore instead. See https://www.drupal.org/node/2935639.
*/
public function testDelete() {
$this->lock->expects($this->once())
@@ -297,6 +310,7 @@ class SharedTempStoreTest extends UnitTestCase {
* Tests the delete() method with no lock available.
*
* @covers ::delete
+ * @expectedDeprecation \Drupal\user\SharedTempStore is scheduled for removal in Drupal 9.0.0. Use \Drupal\Core\TempStore\SharedTempStore instead. See https://www.drupal.org/node/2935639.
*/
public function testDeleteWithNoLockAvailable() {
$this->lock->expects($this->at(0))
@@ -322,6 +336,7 @@ class SharedTempStoreTest extends UnitTestCase {
* Tests the deleteIfOwner() method.
*
* @covers ::deleteIfOwner
+ * @expectedDeprecation \Drupal\user\SharedTempStore is scheduled for removal in Drupal 9.0.0. Use \Drupal\Core\TempStore\SharedTempStore instead. See https://www.drupal.org/node/2935639.
*/
public function testDeleteIfOwner() {
$this->lock->expects($this->once())
diff --git a/core/modules/user/user.services.yml b/core/modules/user/user.services.yml
index c273cb3..aede2f4 100644
--- a/core/modules/user/user.services.yml
+++ b/core/modules/user/user.services.yml
@@ -50,12 +50,14 @@ services:
arguments: ['@entity.manager', '@password']
user.private_tempstore:
class: Drupal\user\PrivateTempStoreFactory
- arguments: ['@keyvalue.expirable', '@lock', '@current_user', '@request_stack', '%user.tempstore.expire%']
+ arguments: ['@keyvalue.expirable', '@lock', '@current_user', '@request_stack', '%tempstore.expire%']
+ deprecated: The "%service_id%" service is deprecated. You should use the 'tempstore.private' service instead. See https://www.drupal.org/node/2935639.
tags:
- { name: backend_overridable }
user.shared_tempstore:
class: Drupal\user\SharedTempStoreFactory
- arguments: ['@keyvalue.expirable', '@lock', '@request_stack', '%user.tempstore.expire%']
+ arguments: ['@keyvalue.expirable', '@lock', '@request_stack', '%tempstore.expire%']
+ deprecated: The "%service_id%" service is deprecated. You should use the 'tempstore.shared' service instead. See https://www.drupal.org/node/2935639.
tags:
- { name: backend_overridable }
user.permissions:
@@ -66,6 +68,3 @@ services:
arguments: ['@current_user', '@entity.manager']
tags:
- { name: 'context_provider' }
-
-parameters:
- user.tempstore.expire: 604800
diff --git a/core/modules/views/src/Entity/View.php b/core/modules/views/src/Entity/View.php
index b69234c..c82d64c 100644
--- a/core/modules/views/src/Entity/View.php
+++ b/core/modules/views/src/Entity/View.php
@@ -456,7 +456,7 @@ class View extends ConfigEntityBase implements ViewEntityInterface {
public static function postDelete(EntityStorageInterface $storage, array $entities) {
parent::postDelete($storage, $entities);
- $tempstore = \Drupal::service('user.shared_tempstore')->get('views');
+ $tempstore = \Drupal::service('tempstore.shared')->get('views');
foreach ($entities as $entity) {
$tempstore->delete($entity->id());
}
diff --git a/core/modules/views_ui/src/Form/BreakLockForm.php b/core/modules/views_ui/src/Form/BreakLockForm.php
index 464920b..6e93848 100644
--- a/core/modules/views_ui/src/Form/BreakLockForm.php
+++ b/core/modules/views_ui/src/Form/BreakLockForm.php
@@ -5,7 +5,7 @@ namespace Drupal\views_ui\Form;
use Drupal\Core\Entity\EntityConfirmFormBase;
use Drupal\Core\Entity\EntityManagerInterface;
use Drupal\Core\Form\FormStateInterface;
-use Drupal\user\SharedTempStoreFactory;
+use Drupal\Core\TempStore\SharedTempStoreFactory;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
@@ -23,9 +23,9 @@ class BreakLockForm extends EntityConfirmFormBase {
protected $entityManager;
/**
- * Stores the user tempstore.
+ * Stores the shared tempstore.
*
- * @var \Drupal\user\SharedTempStore
+ * @var \Drupal\Core\TempStore\SharedTempStore
*/
protected $tempStore;
@@ -34,7 +34,7 @@ class BreakLockForm extends EntityConfirmFormBase {
*
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
* The Entity manager.
- * @param \Drupal\user\SharedTempStoreFactory $temp_store_factory
+ * @param \Drupal\Core\TempStore\SharedTempStoreFactory $temp_store_factory
* The factory for the temp store object.
*/
public function __construct(EntityManagerInterface $entity_manager, SharedTempStoreFactory $temp_store_factory) {
@@ -48,7 +48,7 @@ class BreakLockForm extends EntityConfirmFormBase {
public static function create(ContainerInterface $container) {
return new static(
$container->get('entity.manager'),
- $container->get('user.shared_tempstore')
+ $container->get('tempstore.shared')
);
}
diff --git a/core/modules/views_ui/src/ParamConverter/ViewUIConverter.php b/core/modules/views_ui/src/ParamConverter/ViewUIConverter.php
index ad718ba..fb19d18 100644
--- a/core/modules/views_ui/src/ParamConverter/ViewUIConverter.php
+++ b/core/modules/views_ui/src/ParamConverter/ViewUIConverter.php
@@ -8,7 +8,7 @@ use Drupal\Core\ParamConverter\AdminPathConfigEntityConverter;
use Drupal\Core\Routing\AdminContext;
use Symfony\Component\Routing\Route;
use Drupal\Core\ParamConverter\ParamConverterInterface;
-use Drupal\user\SharedTempStoreFactory;
+use Drupal\Core\TempStore\SharedTempStoreFactory;
use Drupal\views_ui\ViewUI;
/**
@@ -32,7 +32,7 @@ class ViewUIConverter extends AdminPathConfigEntityConverter implements ParamCon
/**
* Stores the tempstore factory.
*
- * @var \Drupal\user\SharedTempStoreFactory
+ * @var \Drupal\Core\TempStore\SharedTempStoreFactory
*/
protected $tempStoreFactory;
@@ -41,7 +41,7 @@ class ViewUIConverter extends AdminPathConfigEntityConverter implements ParamCon
*
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
* The entity manager.
- * @param \Drupal\user\SharedTempStoreFactory $temp_store_factory
+ * @param \Drupal\Core\TempStore\SharedTempStoreFactory $temp_store_factory
* The factory for the temp store object.
*/
public function __construct(EntityManagerInterface $entity_manager, SharedTempStoreFactory $temp_store_factory, ConfigFactoryInterface $config_factory = NULL, AdminContext $admin_context = NULL) {
diff --git a/core/modules/views_ui/src/ViewEditForm.php b/core/modules/views_ui/src/ViewEditForm.php
index 9c1d58a..cea587e 100644
--- a/core/modules/views_ui/src/ViewEditForm.php
+++ b/core/modules/views_ui/src/ViewEditForm.php
@@ -11,7 +11,7 @@ use Drupal\Core\Datetime\DateFormatterInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\ElementInfoManagerInterface;
use Drupal\Core\Url;
-use Drupal\user\SharedTempStoreFactory;
+use Drupal\Core\TempStore\SharedTempStoreFactory;
use Drupal\views\Views;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\RequestStack;
@@ -27,7 +27,7 @@ class ViewEditForm extends ViewFormBase {
/**
* The views temp store.
*
- * @var \Drupal\user\SharedTempStore
+ * @var \Drupal\Core\TempStore\SharedTempStore
*/
protected $tempStore;
@@ -55,7 +55,7 @@ class ViewEditForm extends ViewFormBase {
/**
* Constructs a new ViewEditForm object.
*
- * @param \Drupal\user\SharedTempStoreFactory $temp_store_factory
+ * @param \Drupal\Core\TempStore\SharedTempStoreFactory $temp_store_factory
* The factory for the temp store object.
* @param \Symfony\Component\HttpFoundation\RequestStack $requestStack
* The request stack object.
@@ -76,7 +76,7 @@ class ViewEditForm extends ViewFormBase {
*/
public static function create(ContainerInterface $container) {
return new static(
- $container->get('user.shared_tempstore'),
+ $container->get('tempstore.shared'),
$container->get('request_stack'),
$container->get('date.formatter'),
$container->get('element_info')
diff --git a/core/modules/views_ui/src/ViewUI.php b/core/modules/views_ui/src/ViewUI.php
index 2e7fabd..b2be658 100644
--- a/core/modules/views_ui/src/ViewUI.php
+++ b/core/modules/views_ui/src/ViewUI.php
@@ -48,7 +48,7 @@ class ViewUI implements ViewEntityInterface {
* If this view is locked for editing.
*
* If this view is locked it will contain the result of
- * \Drupal\user\SharedTempStore::getMetadata(). Which can be a stdClass or
+ * \Drupal\Core\TempStore\SharedTempStore::getMetadata(). Which can be a stdClass or
* NULL.
*
* @var stdClass
@@ -855,7 +855,7 @@ class ViewUI implements ViewEntityInterface {
}
/**
- * Sets a cached view object in the user tempstore.
+ * Sets a cached view object in the shared tempstore.
*/
public function cacheSet() {
if ($this->isLocked()) {
@@ -878,7 +878,7 @@ class ViewUI implements ViewEntityInterface {
$executable->default_display = NULL;
$executable->query = NULL;
$executable->displayHandlers = NULL;
- \Drupal::service('user.shared_tempstore')->get('views')->set($this->id(), $this);
+ \Drupal::service('tempstore.shared')->get('views')->set($this->id(), $this);
}
/**
diff --git a/core/modules/views_ui/tests/src/Functional/CachedDataUITest.php b/core/modules/views_ui/tests/src/Functional/CachedDataUITest.php
index 51e489d..c8da87c 100644
--- a/core/modules/views_ui/tests/src/Functional/CachedDataUITest.php
+++ b/core/modules/views_ui/tests/src/Functional/CachedDataUITest.php
@@ -3,7 +3,7 @@
namespace Drupal\Tests\views_ui\Functional;
/**
- * Tests the user tempstore cache in the UI.
+ * Tests the shared tempstore cache in the UI.
*
* @group views_ui
*/
@@ -17,12 +17,12 @@ class CachedDataUITest extends UITestBase {
public static $testViews = ['test_view'];
/**
- * Tests the user tempstore views data in the UI.
+ * Tests the shared tempstore views data in the UI.
*/
public function testCacheData() {
$views_admin_user_uid = $this->fullAdminUser->id();
- $temp_store = $this->container->get('user.shared_tempstore')->get('views');
+ $temp_store = $this->container->get('tempstore.shared')->get('views');
// The view should not be locked.
$this->assertEqual($temp_store->getMetadata('test_view'), NULL, 'The view is not locked.');
@@ -40,7 +40,7 @@ class CachedDataUITest extends UITestBase {
// Cancel the view edit and make sure the cache is deleted.
$this->drupalPostForm(NULL, [], t('Cancel'));
- $this->assertEqual($temp_store->getMetadata('test_view'), NULL, 'User tempstore data has been removed.');
+ $this->assertEqual($temp_store->getMetadata('test_view'), NULL, 'Shared tempstore data has been removed.');
// Test we are redirected to the view listing page.
$this->assertUrl('admin/structure/views', [], 'Redirected back to the view listing page.');
diff --git a/core/modules/views_ui/views_ui.services.yml b/core/modules/views_ui/views_ui.services.yml
index 27fa334..adf87e6 100644
--- a/core/modules/views_ui/views_ui.services.yml
+++ b/core/modules/views_ui/views_ui.services.yml
@@ -1,7 +1,7 @@
services:
paramconverter.views_ui:
class: Drupal\views_ui\ParamConverter\ViewUIConverter
- arguments: ['@entity.manager', '@user.shared_tempstore', '@config.factory', '@router.admin_context']
+ arguments: ['@entity.manager', '@tempstore.shared', '@config.factory', '@router.admin_context']
tags:
- { name: paramconverter, priority: 10 }
lazy: true
diff --git a/core/tests/Drupal/KernelTests/Core/TempStore/TempStoreDatabaseTest.php b/core/tests/Drupal/KernelTests/Core/TempStore/TempStoreDatabaseTest.php
new file mode 100644
index 0000000..2abe707
--- /dev/null
+++ b/core/tests/Drupal/KernelTests/Core/TempStore/TempStoreDatabaseTest.php
@@ -0,0 +1,139 @@
+<?php
+
+namespace Drupal\KernelTests\Core\TempStore;
+
+use Drupal\Core\KeyValueStore\KeyValueExpirableFactory;
+use Drupal\KernelTests\KernelTestBase;
+use Drupal\Core\TempStore\SharedTempStoreFactory;
+use Drupal\Core\Lock\DatabaseLockBackend;
+use Drupal\Core\Database\Database;
+
+/**
+ * Tests the temporary object storage system.
+ *
+ * @group TempStore
+ * @see \Drupal\Core\TempStore\SharedTempStore
+ */
+class TempStoreDatabaseTest extends KernelTestBase {
+
+ /**
+ * Modules to enable.
+ *
+ * @var array
+ */
+ public static $modules = ['system'];
+
+ /**
+ * A key/value store factory.
+ *
+ * @var \Drupal\Core\TempStore\SharedTempStoreFactory
+ */
+ protected $storeFactory;
+
+ /**
+ * The name of the key/value collection to set and retrieve.
+ *
+ * @var string
+ */
+ protected $collection;
+
+ /**
+ * An array of random stdClass objects.
+ *
+ * @var array
+ */
+ protected $objects = [];
+
+ protected function setUp() {
+ parent::setUp();
+
+ // Install system tables to test the key/value storage without installing a
+ // full Drupal environment.
+ $this->installSchema('system', ['key_value_expire']);
+
+ // Create several objects for testing.
+ for ($i = 0; $i <= 3; $i++) {
+ $this->objects[$i] = $this->randomObject();
+ }
+
+ }
+
+ /**
+ * Tests the SharedTempStore API.
+ */
+ public function testSharedTempStore() {
+ // Create a key/value collection.
+ $factory = new SharedTempStoreFactory(new KeyValueExpirableFactory(\Drupal::getContainer()), new DatabaseLockBackend(Database::getConnection()), $this->container->get('request_stack'));
+ $collection = $this->randomMachineName();
+
+ // Create two mock users.
+ for ($i = 0; $i <= 1; $i++) {
+ $users[$i] = mt_rand(500, 5000000);
+
+ // Storing the SharedTempStore objects in a class member variable causes a
+ // fatal exception, because in that situation garbage collection is not
+ // triggered until the test class itself is destructed, after tearDown()
+ // has deleted the database tables. Store the objects locally instead.
+ $stores[$i] = $factory->get($collection, $users[$i]);
+ }
+
+ $key = $this->randomMachineName();
+ // Test that setIfNotExists() succeeds only the first time.
+ for ($i = 0; $i <= 1; $i++) {
+ // setIfNotExists() should be TRUE the first time (when $i is 0) and
+ // FALSE the second time (when $i is 1).
+ $this->assertEqual(!$i, $stores[0]->setIfNotExists($key, $this->objects[$i]));
+ $metadata = $stores[0]->getMetadata($key);
+ $this->assertEqual($users[0], $metadata->owner);
+ $this->assertIdenticalObject($this->objects[0], $stores[0]->get($key));
+ // Another user should get the same result.
+ $metadata = $stores[1]->getMetadata($key);
+ $this->assertEqual($users[0], $metadata->owner);
+ $this->assertIdenticalObject($this->objects[0], $stores[1]->get($key));
+ }
+
+ // Remove the item and try to set it again.
+ $stores[0]->delete($key);
+ $stores[0]->setIfNotExists($key, $this->objects[1]);
+ // This time it should succeed.
+ $this->assertIdenticalObject($this->objects[1], $stores[0]->get($key));
+
+ // This user can update the object.
+ $stores[0]->set($key, $this->objects[2]);
+ $this->assertIdenticalObject($this->objects[2], $stores[0]->get($key));
+ // The object is the same when another user loads it.
+ $this->assertIdenticalObject($this->objects[2], $stores[1]->get($key));
+
+ // This user should be allowed to get, update, delete.
+ $this->assertTrue($stores[0]->getIfOwner($key) instanceof \stdClass);
+ $this->assertTrue($stores[0]->setIfOwner($key, $this->objects[1]));
+ $this->assertTrue($stores[0]->deleteIfOwner($key));
+
+ // Another user can update the object and become the owner.
+ $stores[1]->set($key, $this->objects[3]);
+ $this->assertIdenticalObject($this->objects[3], $stores[0]->get($key));
+ $this->assertIdenticalObject($this->objects[3], $stores[1]->get($key));
+ $metadata = $stores[1]->getMetadata($key);
+ $this->assertEqual($users[1], $metadata->owner);
+
+ // The first user should be informed that the second now owns the data.
+ $metadata = $stores[0]->getMetadata($key);
+ $this->assertEqual($users[1], $metadata->owner);
+
+ // The first user should no longer be allowed to get, update, delete.
+ $this->assertNull($stores[0]->getIfOwner($key));
+ $this->assertFalse($stores[0]->setIfOwner($key, $this->objects[1]));
+ $this->assertFalse($stores[0]->deleteIfOwner($key));
+
+ // Now manually expire the item (this is not exposed by the API) and then
+ // assert it is no longer accessible.
+ db_update('key_value_expire')
+ ->fields(['expire' => REQUEST_TIME - 1])
+ ->condition('collection', "tempstore.shared.$collection")
+ ->condition('name', $key)
+ ->execute();
+ $this->assertFalse($stores[0]->get($key));
+ $this->assertFalse($stores[1]->get($key));
+ }
+
+}
diff --git a/core/tests/Drupal/Tests/Core/TempStore/PrivateTempStoreTest.php b/core/tests/Drupal/Tests/Core/TempStore/PrivateTempStoreTest.php
new file mode 100644
index 0000000..0144919
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/TempStore/PrivateTempStoreTest.php
@@ -0,0 +1,281 @@
+<?php
+
+namespace Drupal\Tests\Core\TempStore;
+
+use Drupal\Tests\UnitTestCase;
+use Drupal\Core\TempStore\PrivateTempStore;
+use Drupal\Core\TempStore\TempStoreException;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\RequestStack;
+
+/**
+ * @coversDefaultClass \Drupal\Core\TempStore\PrivateTempStore
+ * @group TempStore
+ */
+class PrivateTempStoreTest extends UnitTestCase {
+
+ /**
+ * The mock key value expirable backend.
+ *
+ * @var \Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface|\PHPUnit_Framework_MockObject_MockObject
+ */
+ protected $keyValue;
+
+ /**
+ * The mock lock backend.
+ *
+ * @var \Drupal\Core\Lock\LockBackendInterface|\PHPUnit_Framework_MockObject_MockObject
+ */
+ protected $lock;
+
+ /**
+ * The temp store.
+ *
+ * @var \Drupal\Core\TempStore\PrivateTempStore
+ */
+ protected $tempStore;
+
+ /**
+ * The current user.
+ *
+ * @var \Drupal\Core\Session\AccountProxyInterface|\PHPUnit_Framework_MockObject_MockObject
+ */
+ protected $currentUser;
+
+ /**
+ * The request stack.
+ *
+ * @var \Symfony\Component\HttpFoundation\RequestStack
+ */
+ protected $requestStack;
+
+ /**
+ * A tempstore object belonging to the owner.
+ *
+ * @var \stdClass
+ */
+ protected $ownObject;
+
+ /**
+ * A tempstore object not belonging to the owner.
+ *
+ * @var \stdClass
+ */
+ protected $otherObject;
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function setUp() {
+ parent::setUp();
+
+ $this->keyValue = $this->getMock('Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface');
+ $this->lock = $this->getMock('Drupal\Core\Lock\LockBackendInterface');
+ $this->currentUser = $this->getMock('Drupal\Core\Session\AccountProxyInterface');
+ $this->currentUser->expects($this->any())
+ ->method('id')
+ ->willReturn(1);
+
+ $this->requestStack = new RequestStack();
+ $request = Request::createFromGlobals();
+ $this->requestStack->push($request);
+
+ $this->tempStore = new PrivateTempStore($this->keyValue, $this->lock, $this->currentUser, $this->requestStack, 604800);
+
+ $this->ownObject = (object) [
+ 'data' => 'test_data',
+ 'owner' => $this->currentUser->id(),
+ 'updated' => (int) $request->server->get('REQUEST_TIME'),
+ ];
+
+ // Clone the object but change the owner.
+ $this->otherObject = clone $this->ownObject;
+ $this->otherObject->owner = 2;
+ }
+
+
+ /**
+ * Tests the get() method.
+ *
+ * @covers ::get
+ */
+ public function testGet() {
+ $this->keyValue->expects($this->at(0))
+ ->method('get')
+ ->with('1:test_2')
+ ->will($this->returnValue(FALSE));
+ $this->keyValue->expects($this->at(1))
+ ->method('get')
+ ->with('1:test')
+ ->will($this->returnValue($this->ownObject));
+ $this->keyValue->expects($this->at(2))
+ ->method('get')
+ ->with('1:test')
+ ->will($this->returnValue($this->otherObject));
+
+ $this->assertNull($this->tempStore->get('test_2'));
+ $this->assertSame($this->ownObject->data, $this->tempStore->get('test'));
+ $this->assertNull($this->tempStore->get('test'));
+ }
+
+ /**
+ * Tests the set() method with no lock available.
+ *
+ * @covers ::set
+ */
+ public function testSetWithNoLockAvailable() {
+ $this->lock->expects($this->at(0))
+ ->method('acquire')
+ ->with('1:test')
+ ->will($this->returnValue(FALSE));
+ $this->lock->expects($this->at(1))
+ ->method('wait')
+ ->with('1:test');
+ $this->lock->expects($this->at(2))
+ ->method('acquire')
+ ->with('1:test')
+ ->will($this->returnValue(FALSE));
+
+ $this->keyValue->expects($this->once())
+ ->method('getCollectionName');
+
+ $this->setExpectedException(TempStoreException::class);
+ $this->tempStore->set('test', 'value');
+ }
+
+ /**
+ * Tests a successful set() call.
+ *
+ * @covers ::set
+ */
+ public function testSet() {
+ $this->lock->expects($this->once())
+ ->method('acquire')
+ ->with('1:test')
+ ->will($this->returnValue(TRUE));
+ $this->lock->expects($this->never())
+ ->method('wait');
+ $this->lock->expects($this->once())
+ ->method('release')
+ ->with('1:test');
+
+ $this->keyValue->expects($this->once())
+ ->method('setWithExpire')
+ ->with('1:test', $this->ownObject, 604800);
+
+ $this->tempStore->set('test', 'test_data');
+ }
+
+ /**
+ * Tests the getMetadata() method.
+ *
+ * @covers ::getMetadata
+ */
+ public function testGetMetadata() {
+ $this->keyValue->expects($this->at(0))
+ ->method('get')
+ ->with('1:test')
+ ->will($this->returnValue($this->ownObject));
+
+ $this->keyValue->expects($this->at(1))
+ ->method('get')
+ ->with('1:test')
+ ->will($this->returnValue(FALSE));
+
+ $metadata = $this->tempStore->getMetadata('test');
+ $this->assertObjectHasAttribute('owner', $metadata);
+ // Data should get removed.
+ $this->assertObjectNotHasAttribute('data', $metadata);
+
+ $this->assertNull($this->tempStore->getMetadata('test'));
+ }
+
+ /**
+ * Tests the locking in the delete() method.
+ *
+ * @covers ::delete
+ */
+ public function testDeleteLocking() {
+ $this->keyValue->expects($this->once())
+ ->method('get')
+ ->with('1:test')
+ ->will($this->returnValue($this->ownObject));
+ $this->lock->expects($this->once())
+ ->method('acquire')
+ ->with('1:test')
+ ->will($this->returnValue(TRUE));
+ $this->lock->expects($this->never())
+ ->method('wait');
+ $this->lock->expects($this->once())
+ ->method('release')
+ ->with('1:test');
+
+ $this->keyValue->expects($this->once())
+ ->method('delete')
+ ->with('1:test');
+
+ $this->assertTrue($this->tempStore->delete('test'));
+ }
+
+ /**
+ * Tests the delete() method with no lock available.
+ *
+ * @covers ::delete
+ */
+ public function testDeleteWithNoLockAvailable() {
+ $this->keyValue->expects($this->once())
+ ->method('get')
+ ->with('1:test')
+ ->will($this->returnValue($this->ownObject));
+ $this->lock->expects($this->at(0))
+ ->method('acquire')
+ ->with('1:test')
+ ->will($this->returnValue(FALSE));
+ $this->lock->expects($this->at(1))
+ ->method('wait')
+ ->with('1:test');
+ $this->lock->expects($this->at(2))
+ ->method('acquire')
+ ->with('1:test')
+ ->will($this->returnValue(FALSE));
+
+ $this->keyValue->expects($this->once())
+ ->method('getCollectionName');
+
+ $this->setExpectedException(TempStoreException::class);
+ $this->tempStore->delete('test');
+ }
+
+ /**
+ * Tests the delete() method.
+ *
+ * @covers ::delete
+ */
+ public function testDelete() {
+ $this->lock->expects($this->once())
+ ->method('acquire')
+ ->with('1:test_2')
+ ->will($this->returnValue(TRUE));
+
+ $this->keyValue->expects($this->at(0))
+ ->method('get')
+ ->with('1:test_1')
+ ->will($this->returnValue(FALSE));
+ $this->keyValue->expects($this->at(1))
+ ->method('get')
+ ->with('1:test_2')
+ ->will($this->returnValue($this->ownObject));
+ $this->keyValue->expects($this->at(2))
+ ->method('delete')
+ ->with('1:test_2');
+ $this->keyValue->expects($this->at(3))
+ ->method('get')
+ ->with('1:test_3')
+ ->will($this->returnValue($this->otherObject));
+
+ $this->assertTrue($this->tempStore->delete('test_1'));
+ $this->assertTrue($this->tempStore->delete('test_2'));
+ $this->assertFalse($this->tempStore->delete('test_3'));
+ }
+
+}
diff --git a/core/tests/Drupal/Tests/Core/TempStore/SharedTempStoreTest.php b/core/tests/Drupal/Tests/Core/TempStore/SharedTempStoreTest.php
new file mode 100644
index 0000000..55a78b9
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/TempStore/SharedTempStoreTest.php
@@ -0,0 +1,353 @@
+<?php
+
+namespace Drupal\Tests\Core\TempStore;
+
+use Drupal\Tests\UnitTestCase;
+use Drupal\Core\TempStore\SharedTempStore;
+use Drupal\Core\TempStore\TempStoreException;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\RequestStack;
+
+/**
+ * @coversDefaultClass \Drupal\Core\TempStore\SharedTempStore
+ * @group TempStore
+ */
+class SharedTempStoreTest extends UnitTestCase {
+
+ /**
+ * The mock key value expirable backend.
+ *
+ * @var \Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface|\PHPUnit_Framework_MockObject_MockObject
+ */
+ protected $keyValue;
+
+ /**
+ * The mock lock backend.
+ *
+ * @var \Drupal\Core\Lock\LockBackendInterface|\PHPUnit_Framework_MockObject_MockObject
+ */
+ protected $lock;
+
+ /**
+ * The temp store.
+ *
+ * @var \Drupal\Core\TempStore\SharedTempStore
+ */
+ protected $tempStore;
+
+ /**
+ * The owner used in this test.
+ *
+ * @var int
+ */
+ protected $owner = 1;
+
+ /**
+ * The request stack.
+ *
+ * @var \Symfony\Component\HttpFoundation\RequestStack
+ */
+ protected $requestStack;
+
+ /**
+ * A tempstore object belonging to the owner.
+ *
+ * @var \stdClass
+ */
+ protected $ownObject;
+
+ /**
+ * A tempstore object not belonging to the owner.
+ *
+ * @var \stdClass
+ */
+ protected $otherObject;
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function setUp() {
+ parent::setUp();
+
+ $this->keyValue = $this->getMock('Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface');
+ $this->lock = $this->getMock('Drupal\Core\Lock\LockBackendInterface');
+ $this->requestStack = new RequestStack();
+ $request = Request::createFromGlobals();
+ $this->requestStack->push($request);
+
+ $this->tempStore = new SharedTempStore($this->keyValue, $this->lock, $this->owner, $this->requestStack, 604800);
+
+ $this->ownObject = (object) [
+ 'data' => 'test_data',
+ 'owner' => $this->owner,
+ 'updated' => (int) $request->server->get('REQUEST_TIME'),
+ ];
+
+ // Clone the object but change the owner.
+ $this->otherObject = clone $this->ownObject;
+ $this->otherObject->owner = 2;
+ }
+
+ /**
+ * @covers ::get
+ */
+ public function testGet() {
+ $this->keyValue->expects($this->at(0))
+ ->method('get')
+ ->with('test_2')
+ ->will($this->returnValue(FALSE));
+ $this->keyValue->expects($this->at(1))
+ ->method('get')
+ ->with('test')
+ ->will($this->returnValue($this->ownObject));
+
+ $this->assertNull($this->tempStore->get('test_2'));
+ $this->assertSame($this->ownObject->data, $this->tempStore->get('test'));
+ }
+
+ /**
+ * Tests the getIfOwner() method.
+ *
+ * @covers ::getIfOwner
+ */
+ public function testGetIfOwner() {
+ $this->keyValue->expects($this->at(0))
+ ->method('get')
+ ->with('test_2')
+ ->will($this->returnValue(FALSE));
+ $this->keyValue->expects($this->at(1))
+ ->method('get')
+ ->with('test')
+ ->will($this->returnValue($this->ownObject));
+ $this->keyValue->expects($this->at(2))
+ ->method('get')
+ ->with('test')
+ ->will($this->returnValue($this->otherObject));
+
+ $this->assertNull($this->tempStore->getIfOwner('test_2'));
+ $this->assertSame($this->ownObject->data, $this->tempStore->getIfOwner('test'));
+ $this->assertNull($this->tempStore->getIfOwner('test'));
+ }
+
+ /**
+ * Tests the set() method with no lock available.
+ *
+ * @covers ::set
+ */
+ public function testSetWithNoLockAvailable() {
+ $this->lock->expects($this->at(0))
+ ->method('acquire')
+ ->with('test')
+ ->will($this->returnValue(FALSE));
+ $this->lock->expects($this->at(1))
+ ->method('wait')
+ ->with('test');
+ $this->lock->expects($this->at(2))
+ ->method('acquire')
+ ->with('test')
+ ->will($this->returnValue(FALSE));
+
+ $this->keyValue->expects($this->once())
+ ->method('getCollectionName');
+
+ $this->setExpectedException(TempStoreException::class);
+ $this->tempStore->set('test', 'value');
+ }
+
+ /**
+ * Tests a successful set() call.
+ *
+ * @covers ::set
+ */
+ public function testSet() {
+ $this->lock->expects($this->once())
+ ->method('acquire')
+ ->with('test')
+ ->will($this->returnValue(TRUE));
+ $this->lock->expects($this->never())
+ ->method('wait');
+ $this->lock->expects($this->once())
+ ->method('release')
+ ->with('test');
+
+ $this->keyValue->expects($this->once())
+ ->method('setWithExpire')
+ ->with('test', $this->ownObject, 604800);
+
+ $this->tempStore->set('test', 'test_data');
+ }
+
+ /**
+ * Tests the setIfNotExists() methods.
+ *
+ * @covers ::setIfNotExists
+ */
+ public function testSetIfNotExists() {
+ $this->keyValue->expects($this->once())
+ ->method('setWithExpireIfNotExists')
+ ->with('test', $this->ownObject, 604800)
+ ->will($this->returnValue(TRUE));
+
+ $this->assertTrue($this->tempStore->setIfNotExists('test', 'test_data'));
+ }
+
+ /**
+ * Tests the setIfOwner() method when no key exists.
+ *
+ * @covers ::setIfOwner
+ */
+ public function testSetIfOwnerWhenNotExists() {
+ $this->keyValue->expects($this->once())
+ ->method('setWithExpireIfNotExists')
+ ->will($this->returnValue(TRUE));
+
+ $this->assertTrue($this->tempStore->setIfOwner('test', 'test_data'));
+ }
+
+ /**
+ * Tests the setIfOwner() method when a key already exists but no object.
+ *
+ * @covers ::setIfOwner
+ */
+ public function testSetIfOwnerNoObject() {
+ $this->keyValue->expects($this->once())
+ ->method('setWithExpireIfNotExists')
+ ->will($this->returnValue(FALSE));
+
+ $this->keyValue->expects($this->once())
+ ->method('get')
+ ->with('test')
+ ->will($this->returnValue(FALSE));
+
+ $this->assertFalse($this->tempStore->setIfOwner('test', 'test_data'));
+ }
+
+ /**
+ * Tests the setIfOwner() method with matching and non matching owners.
+ *
+ * @covers ::setIfOwner
+ */
+ public function testSetIfOwner() {
+ $this->lock->expects($this->once())
+ ->method('acquire')
+ ->with('test')
+ ->will($this->returnValue(TRUE));
+
+ $this->keyValue->expects($this->exactly(2))
+ ->method('setWithExpireIfNotExists')
+ ->will($this->returnValue(FALSE));
+
+ $this->keyValue->expects($this->exactly(2))
+ ->method('get')
+ ->with('test')
+ ->will($this->onConsecutiveCalls($this->ownObject, $this->otherObject));
+
+ $this->assertTrue($this->tempStore->setIfOwner('test', 'test_data'));
+ $this->assertFalse($this->tempStore->setIfOwner('test', 'test_data'));
+ }
+
+ /**
+ * Tests the getMetadata() method.
+ *
+ * @covers ::getMetadata
+ */
+ public function testGetMetadata() {
+ $this->keyValue->expects($this->at(0))
+ ->method('get')
+ ->with('test')
+ ->will($this->returnValue($this->ownObject));
+
+ $this->keyValue->expects($this->at(1))
+ ->method('get')
+ ->with('test')
+ ->will($this->returnValue(FALSE));
+
+ $metadata = $this->tempStore->getMetadata('test');
+ $this->assertObjectHasAttribute('owner', $metadata);
+ // Data should get removed.
+ $this->assertObjectNotHasAttribute('data', $metadata);
+
+ $this->assertNull($this->tempStore->getMetadata('test'));
+ }
+
+ /**
+ * Tests the delete() method.
+ *
+ * @covers ::delete
+ */
+ public function testDelete() {
+ $this->lock->expects($this->once())
+ ->method('acquire')
+ ->with('test')
+ ->will($this->returnValue(TRUE));
+ $this->lock->expects($this->never())
+ ->method('wait');
+ $this->lock->expects($this->once())
+ ->method('release')
+ ->with('test');
+
+ $this->keyValue->expects($this->once())
+ ->method('delete')
+ ->with('test');
+
+ $this->tempStore->delete('test');
+ }
+
+ /**
+ * Tests the delete() method with no lock available.
+ *
+ * @covers ::delete
+ */
+ public function testDeleteWithNoLockAvailable() {
+ $this->lock->expects($this->at(0))
+ ->method('acquire')
+ ->with('test')
+ ->will($this->returnValue(FALSE));
+ $this->lock->expects($this->at(1))
+ ->method('wait')
+ ->with('test');
+ $this->lock->expects($this->at(2))
+ ->method('acquire')
+ ->with('test')
+ ->will($this->returnValue(FALSE));
+
+ $this->keyValue->expects($this->once())
+ ->method('getCollectionName');
+
+ $this->setExpectedException(TempStoreException::class);
+ $this->tempStore->delete('test');
+ }
+
+ /**
+ * Tests the deleteIfOwner() method.
+ *
+ * @covers ::deleteIfOwner
+ */
+ public function testDeleteIfOwner() {
+ $this->lock->expects($this->once())
+ ->method('acquire')
+ ->with('test_2')
+ ->will($this->returnValue(TRUE));
+
+ $this->keyValue->expects($this->at(0))
+ ->method('get')
+ ->with('test_1')
+ ->will($this->returnValue(FALSE));
+ $this->keyValue->expects($this->at(1))
+ ->method('get')
+ ->with('test_2')
+ ->will($this->returnValue($this->ownObject));
+ $this->keyValue->expects($this->at(2))
+ ->method('delete')
+ ->with('test_2');
+ $this->keyValue->expects($this->at(3))
+ ->method('get')
+ ->with('test_3')
+ ->will($this->returnValue($this->otherObject));
+
+ $this->assertTrue($this->tempStore->deleteIfOwner('test_1'));
+ $this->assertTrue($this->tempStore->deleteIfOwner('test_2'));
+ $this->assertFalse($this->tempStore->deleteIfOwner('test_3'));
+ }
+
+}