summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwebchick2015-02-21 20:12:54 -0800
committerwebchick2015-02-21 20:12:54 -0800
commit95a0059a74fe18a832380f6abea459c835e3836f (patch)
tree31d20fa4870ad3ad134b14541251ebd26cc25ce7
parentd8a6c0a11dfddce648f96c8026dfe3d20eac9971 (diff)
Issue #2421263 by alexpott, formatC'vt, kim.pepper, andypost, larowlan, chx: Potential data loss: concurrent (i.e. by different users) node edits leak through preview
-rw-r--r--core/lib/Drupal/Core/Session/SessionManager.php4
-rw-r--r--core/modules/node/node.services.yml2
-rw-r--r--core/modules/node/src/Form/DeleteMultiple.php10
-rw-r--r--core/modules/node/src/NodeForm.php14
-rw-r--r--core/modules/node/src/ParamConverter/NodePreviewConverter.php8
-rw-r--r--core/modules/node/src/Plugin/Action/DeleteNode.php10
-rw-r--r--core/modules/node/src/Tests/PagePreviewTest.php22
-rw-r--r--core/modules/quickedit/js/editors/formEditor.js13
-rw-r--r--core/modules/quickedit/js/models/EntityModel.js68
-rw-r--r--core/modules/quickedit/js/models/FieldModel.js11
-rw-r--r--core/modules/quickedit/js/util.js2
-rw-r--r--core/modules/quickedit/js/views/AppView.js8
-rw-r--r--core/modules/quickedit/js/views/EditorView.js13
-rw-r--r--core/modules/quickedit/js/views/FieldDecorationView.js3
-rw-r--r--core/modules/quickedit/src/Ajax/EntitySavedCommand.php4
-rw-r--r--core/modules/quickedit/src/Ajax/FieldFormSavedCommand.php5
-rw-r--r--core/modules/quickedit/src/Form/QuickEditFieldForm.php10
-rw-r--r--core/modules/quickedit/src/QuickEditController.php28
-rw-r--r--core/modules/quickedit/src/Tests/QuickEditAutocompleteTermTest.php3
-rw-r--r--core/modules/quickedit/src/Tests/QuickEditLoadingTest.php10
-rw-r--r--core/modules/user/src/Form/UserMultipleCancelConfirm.php10
-rw-r--r--core/modules/user/src/Plugin/Action/CancelUser.php10
-rw-r--r--core/modules/user/src/PrivateTempStore.php216
-rw-r--r--core/modules/user/src/PrivateTempStoreFactory.php89
-rw-r--r--core/modules/user/src/SharedTempStore.php (renamed from core/modules/user/src/TempStore.php)36
-rw-r--r--core/modules/user/src/SharedTempStoreFactory.php (renamed from core/modules/user/src/TempStoreFactory.php)22
-rw-r--r--core/modules/user/src/TempStoreException.php5
-rw-r--r--core/modules/user/src/Tests/TempStoreDatabaseTest.php10
-rw-r--r--core/modules/user/tests/src/Unit/PrivateTempStoreTest.php283
-rw-r--r--core/modules/user/tests/src/Unit/SharedTempStoreTest.php (renamed from core/modules/user/tests/src/Unit/TempStoreTest.php)12
-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.php8
-rw-r--r--core/modules/views_ui/src/Tests/CachedDataUITest.php2
-rw-r--r--core/modules/views_ui/src/ViewEditForm.php12
-rw-r--r--core/modules/views_ui/src/ViewUI.php5
-rw-r--r--core/modules/views_ui/views_ui.services.yml2
38 files changed, 811 insertions, 180 deletions
diff --git a/core/lib/Drupal/Core/Session/SessionManager.php b/core/lib/Drupal/Core/Session/SessionManager.php
index 07790cd..706e7ab 100644
--- a/core/lib/Drupal/Core/Session/SessionManager.php
+++ b/core/lib/Drupal/Core/Session/SessionManager.php
@@ -126,8 +126,8 @@ class SessionManager extends NativeSessionStorage implements SessionManagerInter
$_session_user = new AnonymousUserSession();
// Randomly generate a session identifier for this request. This is
- // necessary because \Drupal\user\TempStoreFactory::get() wants to know
- // the future session ID of a lazily started session in advance.
+ // necessary because \Drupal\user\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/modules/node/node.services.yml b/core/modules/node/node.services.yml
index 41a6c37..9547490 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.tempstore']
+ arguments: ['@user.private_tempstore']
tags:
- { name: paramconverter }
node.page_cache_request_policy.deny_node_preview:
diff --git a/core/modules/node/src/Form/DeleteMultiple.php b/core/modules/node/src/Form/DeleteMultiple.php
index 8116db8..abe8db1 100644
--- a/core/modules/node/src/Form/DeleteMultiple.php
+++ b/core/modules/node/src/Form/DeleteMultiple.php
@@ -12,7 +12,7 @@ use Drupal\Core\Form\ConfirmFormBase;
use Drupal\Core\Url;
use Drupal\Component\Utility\String;
use Drupal\Core\Form\FormStateInterface;
-use Drupal\user\TempStoreFactory;
+use Drupal\user\PrivateTempStoreFactory;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -31,7 +31,7 @@ class DeleteMultiple extends ConfirmFormBase {
/**
* The tempstore factory.
*
- * @var \Drupal\user\TempStoreFactory
+ * @var \Drupal\user\PrivateTempStoreFactory
*/
protected $tempStoreFactory;
@@ -45,12 +45,12 @@ class DeleteMultiple extends ConfirmFormBase {
/**
* Constructs a DeleteMultiple form object.
*
- * @param \Drupal\user\TempStoreFactory $temp_store_factory
+ * @param \Drupal\user\PrivateTempStoreFactory $temp_store_factory
* The tempstore factory.
* @param \Drupal\Core\Entity\EntityManagerInterface $manager
* The entity manager.
*/
- public function __construct(TempStoreFactory $temp_store_factory, EntityManagerInterface $manager) {
+ public function __construct(PrivateTempStoreFactory $temp_store_factory, EntityManagerInterface $manager) {
$this->tempStoreFactory = $temp_store_factory;
$this->storage = $manager->getStorage('node');
}
@@ -60,7 +60,7 @@ class DeleteMultiple extends ConfirmFormBase {
*/
public static function create(ContainerInterface $container) {
return new static(
- $container->get('user.tempstore'),
+ $container->get('user.private_tempstore'),
$container->get('entity.manager')
);
}
diff --git a/core/modules/node/src/NodeForm.php b/core/modules/node/src/NodeForm.php
index 9517b51..17066ab 100644
--- a/core/modules/node/src/NodeForm.php
+++ b/core/modules/node/src/NodeForm.php
@@ -12,7 +12,7 @@ use Drupal\Core\Entity\ContentEntityForm;
use Drupal\Core\Entity\EntityManagerInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\user\Entity\User;
-use Drupal\user\TempStoreFactory;
+use Drupal\user\PrivateTempStoreFactory;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
@@ -23,7 +23,7 @@ class NodeForm extends ContentEntityForm {
/**
* The tempstore factory.
*
- * @var \Drupal\user\TempStoreFactory
+ * @var \Drupal\user\PrivateTempStoreFactory
*/
protected $tempStoreFactory;
@@ -37,10 +37,10 @@ class NodeForm extends ContentEntityForm {
*
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
* The entity manager.
- * @param \Drupal\user\TempStoreFactory $temp_store_factory
+ * @param \Drupal\user\PrivateTempStoreFactory $temp_store_factory
* The factory for the temp store object.
*/
- public function __construct(EntityManagerInterface $entity_manager, TempStoreFactory $temp_store_factory) {
+ public function __construct(EntityManagerInterface $entity_manager, PrivateTempStoreFactory $temp_store_factory) {
parent::__construct($entity_manager);
$this->tempStoreFactory = $temp_store_factory;
}
@@ -51,7 +51,7 @@ class NodeForm extends ContentEntityForm {
public static function create(ContainerInterface $container) {
return new static(
$container->get('entity.manager'),
- $container->get('user.tempstore')
+ $container->get('user.private_tempstore')
);
}
@@ -426,9 +426,7 @@ class NodeForm extends ContentEntityForm {
// Remove the preview entry from the temp store, if any.
$store = $this->tempStoreFactory->get('node_preview');
- if ($store->get($node->uuid())) {
- $store->delete($node->uuid());
- }
+ $store->delete($node->uuid());
}
else {
// In the unlikely case something went wrong on save, the node will be
diff --git a/core/modules/node/src/ParamConverter/NodePreviewConverter.php b/core/modules/node/src/ParamConverter/NodePreviewConverter.php
index edba0ff..6746fae 100644
--- a/core/modules/node/src/ParamConverter/NodePreviewConverter.php
+++ b/core/modules/node/src/ParamConverter/NodePreviewConverter.php
@@ -8,9 +8,9 @@
namespace Drupal\node\ParamConverter;
use Drupal\Core\Entity\EntityManagerInterface;
+use Drupal\user\PrivateTempStoreFactory;
use Symfony\Component\Routing\Route;
use Drupal\Core\ParamConverter\ParamConverterInterface;
-use Drupal\user\TempStoreFactory;
/**
* Provides upcasting for a node entity in preview.
@@ -20,17 +20,17 @@ class NodePreviewConverter implements ParamConverterInterface {
/**
* Stores the tempstore factory.
*
- * @var \Drupal\user\TempStoreFactory
+ * @var \Drupal\user\PrivateTempStoreFactory
*/
protected $tempStoreFactory;
/**
* Constructs a new NodePreviewConverter.
*
- * @param \Drupal\user\TempStoreFactory $temp_store_factory
+ * @param \Drupal\user\PrivateTempStoreFactory $temp_store_factory
* The factory for the temp store object.
*/
- public function __construct(TempStoreFactory $temp_store_factory) {
+ public function __construct(PrivateTempStoreFactory $temp_store_factory) {
$this->tempStoreFactory = $temp_store_factory;
}
diff --git a/core/modules/node/src/Plugin/Action/DeleteNode.php b/core/modules/node/src/Plugin/Action/DeleteNode.php
index f01d0d1..d633dc8 100644
--- a/core/modules/node/src/Plugin/Action/DeleteNode.php
+++ b/core/modules/node/src/Plugin/Action/DeleteNode.php
@@ -10,7 +10,7 @@ namespace Drupal\node\Plugin\Action;
use Drupal\Core\Action\ActionBase;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Session\AccountInterface;
-use Drupal\user\TempStoreFactory;
+use Drupal\user\PrivateTempStoreFactory;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
@@ -28,7 +28,7 @@ class DeleteNode extends ActionBase implements ContainerFactoryPluginInterface {
/**
* The tempstore object.
*
- * @var \Drupal\user\TempStore
+ * @var \Drupal\user\SharedTempStore
*/
protected $tempStore;
@@ -48,12 +48,12 @@ class DeleteNode extends ActionBase implements ContainerFactoryPluginInterface {
* The plugin ID for the plugin instance.
* @param mixed $plugin_definition
* The plugin implementation definition.
- * @param \Drupal\user\TempStoreFactory $temp_store_factory
+ * @param \Drupal\user\PrivateTempStoreFactory $temp_store_factory
* The tempstore factory.
* @param AccountInterface $current_user
* Current user.
*/
- public function __construct(array $configuration, $plugin_id, $plugin_definition, TempStoreFactory $temp_store_factory, AccountInterface $current_user) {
+ public function __construct(array $configuration, $plugin_id, $plugin_definition, PrivateTempStoreFactory $temp_store_factory, AccountInterface $current_user) {
$this->currentUser = $current_user;
$this->tempStore = $temp_store_factory->get('node_multiple_delete_confirm');
@@ -68,7 +68,7 @@ class DeleteNode extends ActionBase implements ContainerFactoryPluginInterface {
$configuration,
$plugin_id,
$plugin_definition,
- $container->get('user.tempstore'),
+ $container->get('user.private_tempstore'),
$container->get('current_user')
);
}
diff --git a/core/modules/node/src/Tests/PagePreviewTest.php b/core/modules/node/src/Tests/PagePreviewTest.php
index 1b7929b..13a051b 100644
--- a/core/modules/node/src/Tests/PagePreviewTest.php
+++ b/core/modules/node/src/Tests/PagePreviewTest.php
@@ -257,4 +257,26 @@ class PagePreviewTest extends NodeTestBase {
$this->assertFieldByName('revision_log[0][value]', $edit['revision_log[0][value]'], 'Revision log field displayed.');
}
+ /**
+ * Checks the node preview accessible for simultaneous node editing.
+ */
+ public function testSimultaneousPreview() {
+ $title_key = 'title[0][value]';
+ $node = $this->drupalCreateNode(array());
+
+ $edit = array($title_key => 'New page title');
+ $this->drupalPostForm('node/' . $node->id() . '/edit', $edit, t('Preview'));
+ $this->assertText($edit[$title_key]);
+
+ $user2 = $this->drupalCreateUser(array('edit any page content'));
+ $this->drupalLogin($user2);
+ $this->drupalGet('node/' . $node->id() . '/edit');
+ $this->assertFieldByName($title_key, $node->label(), 'No title leaked from previous user.');
+
+ $edit2 = array($title_key => 'Another page title');
+ $this->drupalPostForm('node/' . $node->id() . '/edit', $edit2, t('Preview'));
+ $this->assertUrl(\Drupal::url('entity.node.preview', ['node_preview' => $node->uuid(), 'view_mode_id' => 'default'], ['absolute' => TRUE]));
+ $this->assertText($edit2[$title_key]);
+ }
+
}
diff --git a/core/modules/quickedit/js/editors/formEditor.js b/core/modules/quickedit/js/editors/formEditor.js
index 7660bce..8dc3fb5 100644
--- a/core/modules/quickedit/js/editors/formEditor.js
+++ b/core/modules/quickedit/js/editors/formEditor.js
@@ -95,12 +95,13 @@
fieldID: fieldModel.get('fieldID'),
$el: this.$el,
nocssjs: false,
- // Reset an existing entry for this entity in the TempStore (if any) when
- // loading the field. Logically speaking, this should happen in a separate
- // request because this is an entity-level operation, not a field-level
- // operation. But that would require an additional request, that might not
- // even be necessary: it is only when a user loads a first changed field
- // for an entity that this needs to happen: precisely now!
+ // Reset an existing entry for this entity in the PrivateTempStore (if
+ // any) when loading the field. Logically speaking, this should happen
+ // in a separate request because this is an entity-level operation, not
+ // a field-level operation. But that would require an additional
+ // request, that might not even be necessary: it is only when a user
+ // loads a first changed field for an entity that this needs to happen:
+ // precisely now!
reset: !fieldModel.get('entity').get('inTempStore')
};
Drupal.quickedit.util.form.load(formOptions, function (form, ajax) {
diff --git a/core/modules/quickedit/js/models/EntityModel.js b/core/modules/quickedit/js/models/EntityModel.js
index 052ab3a..e850065 100644
--- a/core/modules/quickedit/js/models/EntityModel.js
+++ b/core/modules/quickedit/js/models/EntityModel.js
@@ -33,22 +33,24 @@
// Indicates whether this instance of this entity is currently being
// edited in-place.
isActive: false,
- // Whether one or more fields have already been stored in TempStore.
+ // Whether one or more fields have already been stored in
+ // PrivateTempStore.
inTempStore: false,
- // Whether one or more fields have already been stored in TempStore *or*
- // the field that's currently being edited is in the 'changed' or a later
- // state. In other words, this boolean indicates whether a "Save" button is
- // necessary or not.
+ // Whether one or more fields have already been stored in PrivateTempStore
+ // *or* the field that's currently being edited is in the 'changed' or a
+ // later state. In other words, this boolean indicates whether a "Save"
+ // button is necessary or not.
isDirty: false,
// Whether the request to the server has been made to commit this entity.
// Used to prevent multiple such requests.
isCommitting: false,
// The current processing state of an entity.
state: 'closed',
- // The IDs of the fields whose new values have been stored in TempStore. We
- // must store this on the EntityModel as well (even though it already is on
- // the FieldModel) because when a field is rerendered, its FieldModel is
- // destroyed and this allows us to transition it back to the proper state.
+ // The IDs of the fields whose new values have been stored in
+ // PrivateTempStore. We must store this on the EntityModel as well (even
+ // though it already is on the FieldModel) because when a field is
+ // rerendered, its FieldModel is destroyed and this allows us to
+ // transition it back to the proper state.
fieldsInTempStore: [],
// A flag the tells the application that this EntityModel must be reloaded
// in order to restore the original values to its fields in the client.
@@ -118,7 +120,7 @@
fieldModel.set('state', 'candidate');
});
// For fields that are in a changed state, field values must first be
- // stored in TempStore.
+ // stored in PrivateTempStore.
fields.chain()
.filter(function (fieldModel) {
return _.intersection([fieldModel.get('state')], Drupal.quickedit.app.changedFieldStates).length;
@@ -205,16 +207,17 @@
var previous = fieldModel.previous('state');
var fieldsInTempStore = entityModel.get('fieldsInTempStore');
// If the fieldModel changed to the 'saved' state: remember that this
- // field was saved to TempStore.
+ // field was saved to PrivateTempStore.
if (current === 'saved') {
- // Mark the entity as saved in TempStore, so that we can pass the
- // proper "reset TempStore" boolean value when communicating with the
- // server.
+ // Mark the entity as saved in PrivateTempStore, so that we can pass the
+ // proper "reset PrivateTempStore" boolean value when communicating with
+ // the server.
entityModel.set('inTempStore', true);
- // Mark the field as saved in TempStore, so that visual indicators
- // signifying just that may be rendered.
+ // Mark the field as saved in PrivateTempStore, so that visual
+ // indicators signifying just that may be rendered.
fieldModel.set('inTempStore', true);
- // Remember that this field is in TempStore, restore when rerendered.
+ // Remember that this field is in PrivateTempStore, restore when
+ // rerendered.
fieldsInTempStore.push(fieldModel.get('fieldID'));
fieldsInTempStore = _.uniq(fieldsInTempStore);
entityModel.set('fieldsInTempStore', fieldsInTempStore);
@@ -271,11 +274,11 @@
// Set the isDirty attribute when appropriate so that it is known when
// to display the "Save" button in the entity toolbar.
// Note that once a field has been changed, there's no way to discard
- // that change, hence it will have to be saved into TempStore, or the
- // in-place editing of this field will have to be stopped completely.
- // In other words: once any field enters the 'changed' field, then for
- // the remainder of the in-place editing session, the entity is by
- // definition dirty.
+ // that change, hence it will have to be saved into PrivateTempStore,
+ // or the in-place editing of this field will have to be stopped
+ // completely. In other words: once any field enters the 'changed'
+ // field, then for the remainder of the in-place editing session, the
+ // entity is by definition dirty.
if (fieldState === 'changed') {
entityModel.set('isDirty', true);
}
@@ -380,9 +383,9 @@
entitySaverAjax.commands.quickeditEntitySaved = function (ajax, response, status) {
// Clean up.
$(ajax.element).off('quickedit-save.quickedit');
- // All fields have been moved from TempStore to permanent storage, update
- // the "inTempStore" attribute on FieldModels, on the EntityModel and
- // clear EntityModel's "fieldInTempStore" attribute.
+ // All fields have been moved from PrivateTempStore to permanent
+ // storage, update the "inTempStore" attribute on FieldModels, on the
+ // EntityModel and clear EntityModel's "fieldInTempStore" attribute.
entityModel.get('fields').each(function (fieldModel) {
fieldModel.set('inTempStore', false);
});
@@ -566,13 +569,14 @@
// User has clicked the 'Save' button (and has thus changed at least one
// field).
// - Trigger: user.
- // - Guarantees: see 'opened', plus: either a changed field is in TempStore,
- // or the user has just modified a field without activating (switching to)
- // another field.
- // - Expected behavior: 1) if any of the fields are not yet in TempStore,
- // save them to TempStore, 2) if then any of the fields has the 'invalid'
- // state, then change the entity state back to 'opened', otherwise: save
- // the entity by committing it from TempStore into permanent storage.
+ // - Guarantees: see 'opened', plus: either a changed field is in
+ // PrivateTempStore, or the user has just modified a field without
+ // activating (switching to) another field.
+ // - Expected behavior: 1) if any of the fields are not yet in
+ // PrivateTempStore, save them to PrivateTempStore, 2) if then any of
+ // the fields has the 'invalid' state, then change the entity state back
+ // to 'opened', otherwise: save the entity by committing it from
+ // PrivateTempStore into permanent storage.
'committing',
// User has clicked the 'Close' button, or has clicked the 'Save' button and
// that was successfully completed.
diff --git a/core/modules/quickedit/js/models/FieldModel.js b/core/modules/quickedit/js/models/FieldModel.js
index 5737383..6bd4e44 100644
--- a/core/modules/quickedit/js/models/FieldModel.js
+++ b/core/modules/quickedit/js/models/FieldModel.js
@@ -210,14 +210,15 @@
// - Guarantees: see 'candidate', plus in-place editor is ready for use.
// - Expected behavior: visual indicator of change.
'changed',
- // User is saving changed field data in in-place editor to TempStore. The
- // save mechanism of the in-place editor is called.
+ // User is saving changed field data in in-place editor to
+ // PrivateTempStore. The save mechanism of the in-place editor is called.
// - Trigger: user.
// - Guarantees: see 'candidate' and 'active'.
// - Expected behavior: saving indicator, in-place editor is saving field
- // data into TempStore. Upon successful saving (without validation
- // errors), the in-place editor transitions the field's state to 'saved',
- // but to 'invalid' upon failed saving (with validation errors).
+ // data into PrivateTempStore. Upon successful saving (without
+ // validation errors), the in-place editor transitions the field's state
+ // to 'saved', but to 'invalid' upon failed saving (with validation
+ // errors).
'saving',
// In-place editor has successfully saved the changed field.
// - Trigger: in-place editor.
diff --git a/core/modules/quickedit/js/util.js b/core/modules/quickedit/js/util.js
index 3b3aa3a..2f76665 100644
--- a/core/modules/quickedit/js/util.js
+++ b/core/modules/quickedit/js/util.js
@@ -82,7 +82,7 @@
* - Boolean nocssjs: (required) boolean indicating whether no CSS and JS
* should be returned (necessary when the form is invisible to the user).
* - Boolean reset: (required) boolean indicating whether the data stored
- * for this field's entity in TempStore should be used or reset.
+ * for this field's entity in PrivateTempStore should be used or reset.
* @param Function callback
* A callback function that will receive the form to be inserted, as well as
* the ajax object, necessary if the callback wants to perform other AJAX
diff --git a/core/modules/quickedit/js/views/AppView.js b/core/modules/quickedit/js/views/AppView.js
index 9668251..c911da5 100644
--- a/core/modules/quickedit/js/views/AppView.js
+++ b/core/modules/quickedit/js/views/AppView.js
@@ -12,10 +12,10 @@
// Indicates whether the page should be reloaded after in-place editing has
// shut down. A page reload is necessary to re-instate the original HTML of the
// edited fields if in-place editing has been canceled and one or more of the
- // entity's fields were saved to TempStore: one of them may have been changed to
- // the empty value and hence may have been rerendered as the empty string, which
- // makes it impossible for Quick Edit to know where to restore the original
- // HTML.
+ // entity's fields were saved to PrivateTempStore: one of them may have been
+ // changed to the empty value and hence may have been rerendered as the empty
+ // string, which makes it impossible for Quick Edit to know where to restore
+ // the original HTML.
var reload = false;
Drupal.quickedit.AppView = Backbone.View.extend({
diff --git a/core/modules/quickedit/js/views/EditorView.js b/core/modules/quickedit/js/views/EditorView.js
index 5122938..4bb410c 100644
--- a/core/modules/quickedit/js/views/EditorView.js
+++ b/core/modules/quickedit/js/views/EditorView.js
@@ -197,12 +197,13 @@
$el: this.$el,
nocssjs: true,
other_view_modes: fieldModel.findOtherViewModes(),
- // Reset an existing entry for this entity in the TempStore (if any) when
- // saving the field. Logically speaking, this should happen in a separate
- // request because this is an entity-level operation, not a field-level
- // operation. But that would require an additional request, that might not
- // even be necessary: it is only when a user saves a first changed field
- // for an entity that this needs to happen: precisely now!
+ // Reset an existing entry for this entity in the PrivateTempStore (if
+ // any) when saving the field. Logically speaking, this should happen in
+ // a separate request because this is an entity-level operation, not a
+ // field-level operation. But that would require an additional request,
+ // that might not even be necessary: it is only when a user saves a
+ // first changed field for an entity that this needs to happen:
+ // precisely now!
reset: !this.fieldModel.get('entity').get('inTempStore')
};
diff --git a/core/modules/quickedit/js/views/FieldDecorationView.js b/core/modules/quickedit/js/views/FieldDecorationView.js
index a3d8d2e..93549e3 100644
--- a/core/modules/quickedit/js/views/FieldDecorationView.js
+++ b/core/modules/quickedit/js/views/FieldDecorationView.js
@@ -99,7 +99,8 @@
/**
* Adds a class to the edited element that indicates whether the field has
* been changed by the user (i.e. locally) or the field has already been
- * changed and stored before by the user (i.e. remotely, stored in TempStore).
+ * changed and stored before by the user (i.e. remotely, stored in
+ * PrivateTempStore).
*/
renderChanged: function () {
this.$el.toggleClass('quickedit-changed', this.model.get('isChanged') || this.model.get('inTempStore'));
diff --git a/core/modules/quickedit/src/Ajax/EntitySavedCommand.php b/core/modules/quickedit/src/Ajax/EntitySavedCommand.php
index e5b399f..cf7ad18 100644
--- a/core/modules/quickedit/src/Ajax/EntitySavedCommand.php
+++ b/core/modules/quickedit/src/Ajax/EntitySavedCommand.php
@@ -8,8 +8,8 @@
namespace Drupal\quickedit\Ajax;
/**
- * AJAX command to indicate the entity was loaded from TempStore and saved into
- * the database.
+ * AJAX command to indicate the entity was loaded from PrivateTempStore and
+ * saved into the database.
*/
class EntitySavedCommand extends BaseCommand {
diff --git a/core/modules/quickedit/src/Ajax/FieldFormSavedCommand.php b/core/modules/quickedit/src/Ajax/FieldFormSavedCommand.php
index 3e6dee9..f0dc386 100644
--- a/core/modules/quickedit/src/Ajax/FieldFormSavedCommand.php
+++ b/core/modules/quickedit/src/Ajax/FieldFormSavedCommand.php
@@ -8,8 +8,9 @@
namespace Drupal\quickedit\Ajax;
/**
- * AJAX command to indicate a field was saved into TempStore without validation
- * errors and pass the rerendered field to Quick Edit's JavaScript app.
+ * AJAX command to indicate a field was saved into PrivateTempStore without
+ * validation errors and pass the rerendered field to Quick Edit's JavaScript
+ * app.
*/
class FieldFormSavedCommand extends BaseCommand {
diff --git a/core/modules/quickedit/src/Form/QuickEditFieldForm.php b/core/modules/quickedit/src/Form/QuickEditFieldForm.php
index 6d9d2c3..54e7170 100644
--- a/core/modules/quickedit/src/Form/QuickEditFieldForm.php
+++ b/core/modules/quickedit/src/Form/QuickEditFieldForm.php
@@ -16,7 +16,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\TempStoreFactory;
+use Drupal\user\PrivateTempStoreFactory;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
@@ -27,7 +27,7 @@ class QuickEditFieldForm extends FormBase {
/**
* Stores the tempstore factory.
*
- * @var \Drupal\user\TempStoreFactory
+ * @var \Drupal\user\PrivateTempStoreFactory
*/
protected $tempStoreFactory;
@@ -48,14 +48,14 @@ class QuickEditFieldForm extends FormBase {
/**
* Constructs a new EditFieldForm.
*
- * @param \Drupal\user\TempStoreFactory $temp_store_factory
+ * @param \Drupal\user\PrivateTempStoreFactory $temp_store_factory
* The tempstore factory.
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
* The module handler.
* @param \Drupal\Core\Entity\EntityStorageInterface $node_type_storage
* The node type storage.
*/
- public function __construct(TempStoreFactory $temp_store_factory, ModuleHandlerInterface $module_handler, EntityStorageInterface $node_type_storage) {
+ public function __construct(PrivateTempStoreFactory $temp_store_factory, ModuleHandlerInterface $module_handler, EntityStorageInterface $node_type_storage) {
$this->moduleHandler = $module_handler;
$this->nodeTypeStorage = $node_type_storage;
$this->tempStoreFactory = $temp_store_factory;
@@ -66,7 +66,7 @@ class QuickEditFieldForm extends FormBase {
*/
public static function create(ContainerInterface $container) {
return new static(
- $container->get('user.tempstore'),
+ $container->get('user.private_tempstore'),
$container->get('module_handler'),
$container->get('entity.manager')->getStorage('node_type')
);
diff --git a/core/modules/quickedit/src/QuickEditController.php b/core/modules/quickedit/src/QuickEditController.php
index 339eab4..3747609 100644
--- a/core/modules/quickedit/src/QuickEditController.php
+++ b/core/modules/quickedit/src/QuickEditController.php
@@ -9,6 +9,7 @@ namespace Drupal\quickedit;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Form\FormState;
+use Drupal\user\PrivateTempStoreFactory;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
@@ -19,7 +20,6 @@ use Drupal\quickedit\Ajax\FieldFormCommand;
use Drupal\quickedit\Ajax\FieldFormSavedCommand;
use Drupal\quickedit\Ajax\FieldFormValidationErrorsCommand;
use Drupal\quickedit\Ajax\EntitySavedCommand;
-use Drupal\user\TempStoreFactory;
/**
* Returns responses for Quick Edit module routes.
@@ -27,9 +27,9 @@ use Drupal\user\TempStoreFactory;
class QuickEditController extends ControllerBase {
/**
- * The TempStore factory.
+ * The PrivateTempStore factory.
*
- * @var \Drupal\user\TempStoreFactory
+ * @var \Drupal\user\PrivateTempStoreFactory
*/
protected $tempStoreFactory;
@@ -50,14 +50,14 @@ class QuickEditController extends ControllerBase {
/**
* Constructs a new QuickEditController.
*
- * @param \Drupal\user\TempStoreFactory $temp_store_factory
- * The TempStore factory.
+ * @param \Drupal\user\PrivateTempStoreFactory $temp_store_factory
+ * The PrivateTempStore factory.
* @param \Drupal\quickedit\MetadataGeneratorInterface $metadata_generator
* The in-place editing metadata generator.
* @param \Drupal\quickedit\EditorSelectorInterface $editor_selector
* The in-place editor selector.
*/
- public function __construct(TempStoreFactory $temp_store_factory, MetadataGeneratorInterface $metadata_generator, EditorSelectorInterface $editor_selector) {
+ public function __construct(PrivateTempStoreFactory $temp_store_factory, MetadataGeneratorInterface $metadata_generator, EditorSelectorInterface $editor_selector) {
$this->tempStoreFactory = $temp_store_factory;
$this->metadataGenerator = $metadata_generator;
$this->editorSelector = $editor_selector;
@@ -68,7 +68,7 @@ class QuickEditController extends ControllerBase {
*/
public static function create(ContainerInterface $container) {
return new static(
- $container->get('user.tempstore'),
+ $container->get('user.private_tempstore'),
$container->get('quickedit.metadata.generator'),
$container->get('quickedit.editor.selector')
);
@@ -167,8 +167,8 @@ class QuickEditController extends ControllerBase {
public function fieldForm(EntityInterface $entity, $field_name, $langcode, $view_mode_id, Request $request) {
$response = new AjaxResponse();
- // Replace entity with TempStore copy if available and not resetting, init
- // TempStore copy otherwise.
+ // Replace entity with PrivateTempStore copy if available and not resetting,
+ // init PrivateTempStore copy otherwise.
$tempstore_entity = $this->tempStoreFactory->get('quickedit')->get($entity->uuid());
if ($tempstore_entity && $request->request->get('reset') !== 'true') {
$entity = $tempstore_entity;
@@ -184,8 +184,8 @@ class QuickEditController extends ControllerBase {
$form = $this->formBuilder()->buildForm('Drupal\quickedit\Form\QuickEditFieldForm', $form_state);
if ($form_state->isExecuted()) {
- // The form submission saved the entity in TempStore. Return the
- // updated view of the field from the TempStore copy.
+ // The form submission saved the entity in PrivateTempStore. Return the
+ // updated view of the field from the PrivateTempStore copy.
$entity = $this->tempStoreFactory->get('quickedit')->get($entity->uuid());
// Closure to render the field given a view mode.
@@ -267,7 +267,7 @@ class QuickEditController extends ControllerBase {
}
/**
- * Saves an entity into the database, from TempStore.
+ * Saves an entity into the database, from PrivateTempStore.
*
* @param \Drupal\Core\Entity\EntityInterface $entity
* The entity being edited.
@@ -276,8 +276,8 @@ class QuickEditController extends ControllerBase {
* The Ajax response.
*/
public function entitySave(EntityInterface $entity) {
- // Take the entity from TempStore and save in entity storage. fieldForm()
- // ensures that the TempStore copy exists ahead.
+ // Take the entity from PrivateTempStore and save in entity storage.
+ // fieldForm() ensures that the PrivateTempStore copy exists ahead.
$tempstore = $this->tempStoreFactory->get('quickedit');
$tempstore->get($entity->uuid())->save();
$tempstore->delete($entity->uuid());
diff --git a/core/modules/quickedit/src/Tests/QuickEditAutocompleteTermTest.php b/core/modules/quickedit/src/Tests/QuickEditAutocompleteTermTest.php
index 473cc08..3c42409 100644
--- a/core/modules/quickedit/src/Tests/QuickEditAutocompleteTermTest.php
+++ b/core/modules/quickedit/src/Tests/QuickEditAutocompleteTermTest.php
@@ -170,7 +170,8 @@ class QuickEditAutocompleteTermTest extends WebTestBase {
$this->assertText('new term');
$this->assertNoLink('new term');
- // Load the form again, which should now get it back from TempStore.
+ // Load the form again, which should now get it back from
+ // PrivateTempStore.
$quickedit_uri = 'quickedit/form/node/'. $this->node->id() . '/' . $this->fieldName . '/' . $this->node->language()->getId() . '/full';
$post = array('nocssjs' => 'true') + $this->getAjaxPageStatePostData();
$response = $this->drupalPost($quickedit_uri, 'application/vnd.drupal-ajax', $post);
diff --git a/core/modules/quickedit/src/Tests/QuickEditLoadingTest.php b/core/modules/quickedit/src/Tests/QuickEditLoadingTest.php
index 0cb2c63..3606f01 100644
--- a/core/modules/quickedit/src/Tests/QuickEditLoadingTest.php
+++ b/core/modules/quickedit/src/Tests/QuickEditLoadingTest.php
@@ -214,7 +214,7 @@ class QuickEditLoadingTest extends WebTestBase {
$post += $edit + $this->getAjaxPageStatePostData();
// Submit field form and check response. This should store the updated
- // entity in TempStore on the server.
+ // entity in PrivateTempStore on the server.
$response = $this->drupalPost('quickedit/form/' . 'node/1/body/en/full', 'application/vnd.drupal-ajax', $post);
$this->assertResponse(200);
$ajax_commands = Json::decode($response);
@@ -227,7 +227,7 @@ class QuickEditLoadingTest extends WebTestBase {
$this->drupalGet('node/1');
$this->assertText('How are you?');
- // Save the entity by moving the TempStore values to entity storage.
+ // Save the entity by moving the PrivateTempStore values to entity storage.
$post = array('nocssjs' => 'true');
$response = $this->drupalPost('quickedit/entity/' . 'node/1', 'application/json', $post);
$this->assertResponse(200);
@@ -249,7 +249,7 @@ class QuickEditLoadingTest extends WebTestBase {
// Now configure this node type to create new revisions automatically,
// then again retrieve the field form, fill it, submit it (so it ends up
- // in TempStore) and then save the entity. Now there should be two
+ // in PrivateTempStore) and then save the entity. Now there should be two
// revisions.
$node_type = entity_load('node_type', 'article');
$node_type->setNewRevision(TRUE);
@@ -359,7 +359,7 @@ class QuickEditLoadingTest extends WebTestBase {
$post += $edit + $this->getAjaxPageStatePostData();
// Submit field form and check response. This should store the
- // updated entity in TempStore on the server.
+ // updated entity in PrivateTempStore on the server.
$response = $this->drupalPost('quickedit/form/' . 'node/1/title/en/full', 'application/vnd.drupal-ajax', $post);
$this->assertResponse(200);
$ajax_commands = Json::decode($response);
@@ -371,7 +371,7 @@ class QuickEditLoadingTest extends WebTestBase {
$this->drupalGet('node/1');
$this->assertNoText('Obligatory question');
- // Save the entity by moving the TempStore values to entity storage.
+ // Save the entity by moving the PrivateTempStore values to entity storage.
$post = array('nocssjs' => 'true');
$response = $this->drupalPost('quickedit/entity/' . 'node/1', 'application/json', $post);
$this->assertResponse(200);
diff --git a/core/modules/user/src/Form/UserMultipleCancelConfirm.php b/core/modules/user/src/Form/UserMultipleCancelConfirm.php
index da26ee7..432544b 100644
--- a/core/modules/user/src/Form/UserMultipleCancelConfirm.php
+++ b/core/modules/user/src/Form/UserMultipleCancelConfirm.php
@@ -12,7 +12,7 @@ use Drupal\Core\Entity\EntityManagerInterface;
use Drupal\Core\Form\ConfirmFormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;
-use Drupal\user\TempStoreFactory;
+use Drupal\user\PrivateTempStoreFactory;
use Drupal\user\UserStorageInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -24,7 +24,7 @@ class UserMultipleCancelConfirm extends ConfirmFormBase {
/**
* The temp store factory.
*
- * @var \Drupal\user\TempStoreFactory
+ * @var \Drupal\user\PrivateTempStoreFactory
*/
protected $tempStoreFactory;
@@ -45,14 +45,14 @@ class UserMultipleCancelConfirm extends ConfirmFormBase {
/**
* Constructs a new UserMultipleCancelConfirm.
*
- * @param \Drupal\user\TempStoreFactory $temp_store_factory
+ * @param \Drupal\user\PrivateTempStoreFactory $temp_store_factory
* The temp store factory.
* @param \Drupal\user\UserStorageInterface $user_storage
* The user storage.
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
* The entity manager.
*/
- public function __construct(TempStoreFactory $temp_store_factory, UserStorageInterface $user_storage, EntityManagerInterface $entity_manager) {
+ public function __construct(PrivateTempStoreFactory $temp_store_factory, UserStorageInterface $user_storage, EntityManagerInterface $entity_manager) {
$this->tempStoreFactory = $temp_store_factory;
$this->userStorage = $user_storage;
$this->entityManager = $entity_manager;
@@ -63,7 +63,7 @@ class UserMultipleCancelConfirm extends ConfirmFormBase {
*/
public static function create(ContainerInterface $container) {
return new static(
- $container->get('user.tempstore'),
+ $container->get('user.private_tempstore'),
$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 3219b62..e057106 100644
--- a/core/modules/user/src/Plugin/Action/CancelUser.php
+++ b/core/modules/user/src/Plugin/Action/CancelUser.php
@@ -10,7 +10,7 @@ namespace Drupal\user\Plugin\Action;
use Drupal\Core\Action\ActionBase;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Session\AccountInterface;
-use Drupal\user\TempStoreFactory;
+use Drupal\user\PrivateTempStoreFactory;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
@@ -28,7 +28,7 @@ class CancelUser extends ActionBase implements ContainerFactoryPluginInterface {
/**
* The tempstore factory.
*
- * @var \Drupal\user\TempStoreFactory
+ * @var \Drupal\user\PrivateTempStoreFactory
*/
protected $tempStoreFactory;
@@ -48,12 +48,12 @@ class CancelUser extends ActionBase implements ContainerFactoryPluginInterface {
* The plugin ID for the plugin instance.
* @param mixed $plugin_definition
* The plugin implementation definition.
- * @param \Drupal\user\TempStoreFactory $temp_store_factory
+ * @param \Drupal\user\PrivateTempStoreFactory $temp_store_factory
* The tempstore factory.
* @param AccountInterface $current_user
* Current user.
*/
- public function __construct(array $configuration, $plugin_id, $plugin_definition, TempStoreFactory $temp_store_factory, AccountInterface $current_user) {
+ public function __construct(array $configuration, $plugin_id, $plugin_definition, PrivateTempStoreFactory $temp_store_factory, AccountInterface $current_user) {
$this->currentUser = $current_user;
$this->tempStoreFactory = $temp_store_factory;
@@ -68,7 +68,7 @@ class CancelUser extends ActionBase implements ContainerFactoryPluginInterface {
$configuration,
$plugin_id,
$plugin_definition,
- $container->get('user.tempstore'),
+ $container->get('user.private_tempstore'),
$container->get('current_user')
);
}
diff --git a/core/modules/user/src/PrivateTempStore.php b/core/modules/user/src/PrivateTempStore.php
new file mode 100644
index 0000000..e99d5fc
--- /dev/null
+++ b/core/modules/user/src/PrivateTempStore.php
@@ -0,0 +1,216 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\user\PrivateTempStore.
+ */
+
+namespace Drupal\user;
+
+use Drupal\Component\Utility\String;
+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\user\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 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 $lockBackend
+ * 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 int $expire
+ * The time to live for items, in seconds.
+ */
+ public function __construct(KeyValueStoreExpirableInterface $storage, LockBackendInterface $lockBackend, AccountProxyInterface $current_user, RequestStack $request_stack, $expire = 604800) {
+ $this->storage = $storage;
+ $this->lockBackend = $lockBackend;
+ $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.
+ */
+ 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(String::format("Couldn't acquire lock to update item %key in %collection temporary storage.", array(
+ '%key' => $key,
+ '%collection' => $this->storage->getCollectionName(),
+ )));
+ }
+ }
+
+ $value = (object) array(
+ 'owner' => $this->getOwner(),
+ 'data' => $value,
+ 'updated' => 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.
+ */
+ 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(String::format("Couldn't acquire lock to delete item %key from %collection temporary storage.", array(
+ '%key' => $key,
+ '%collection' => $this->storage->getCollectionName(),
+ )));
+ }
+ }
+ $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/modules/user/src/PrivateTempStoreFactory.php b/core/modules/user/src/PrivateTempStoreFactory.php
new file mode 100644
index 0000000..bd62633
--- /dev/null
+++ b/core/modules/user/src/PrivateTempStoreFactory.php
@@ -0,0 +1,89 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\user\PrivateTempStoreFactory.
+ */
+
+namespace Drupal\user;
+
+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 collecton.
+ */
+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 $lockBackend
+ */
+ 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\Database\Connection $connection
+ * The connection object used for this data.
+ * @param \Drupal\Core\Lock\LockBackendInterface $lockBackend
+ * The lock object used for this data.
+ * @param int $expire
+ * The time to live for items, in seconds.
+ */
+ function __construct(KeyValueExpirableFactoryInterface $storage_factory, LockBackendInterface $lockBackend, AccountProxyInterface $current_user, RequestStack $request_stack, $expire = 604800) {
+ $this->storageFactory = $storage_factory;
+ $this->lockBackend = $lockBackend;
+ $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\user\PrivateTempStore
+ * An instance of the key/value store.
+ */
+ function get($collection) {
+ // Store the data for this collection in the database.
+ $storage = $this->storageFactory->get("user.private_tempstore.$collection");
+ return new PrivateTempStore($storage, $this->lockBackend, $this->currentUser, $this->requestStack, $this->expire);
+ }
+
+}
diff --git a/core/modules/user/src/TempStore.php b/core/modules/user/src/SharedTempStore.php
index da87691..0049d79 100644
--- a/core/modules/user/src/TempStore.php
+++ b/core/modules/user/src/SharedTempStore.php
@@ -2,7 +2,7 @@
/**
* @file
- * Contains Drupal\user\TempStore.
+ * Contains Drupal\user\SharedTempStore.
*/
namespace Drupal\user;
@@ -14,29 +14,33 @@ use Drupal\Core\Lock\LockBackendInterface;
/**
* Stores and retrieves temporary data for a given owner.
*
- * A TempStore can be used to make temporary, non-cache data available across
- * requests. The data for the TempStore is stored in one key/value collection.
- * TempStore data expires automatically after a given timeframe.
+ * 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 TempStore is different from a cache, because the data in it is not yet
- * saved permanently and so it cannot be rebuilt. Typically, the TempStore
- * 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 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 TempStore belongs to a particular owner (e.g. a user, session, or
+ * 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 TempStore can check
+ * 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.
*/
-class TempStore {
+class SharedTempStore {
/**
* The key/value storage object used for this data.
@@ -90,7 +94,7 @@ class TempStore {
}
/**
- * Retrieves a value from this TempStore for a given key.
+ * Retrieves a value from this SharedTempStore for a given key.
*
* @param string $key
* The key of the data to retrieve.
@@ -105,7 +109,7 @@ class TempStore {
}
/**
- * Retrieves a value from this TempStore for a given key.
+ * Retrieves a value from this SharedTempStore for a given key.
*
* Only returns the value if the value is owned by $this->owner.
*
@@ -142,7 +146,7 @@ class TempStore {
}
/**
- * Stores a particular key/value pair in this TempStore.
+ * 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.
@@ -170,7 +174,7 @@ class TempStore {
}
/**
- * Stores a particular key/value pair in this TempStore.
+ * Stores a particular key/value pair in this SharedTempStore.
*
* @param string $key
* The key of the data to store.
diff --git a/core/modules/user/src/TempStoreFactory.php b/core/modules/user/src/SharedTempStoreFactory.php
index 5f19199..3a18c4c 100644
--- a/core/modules/user/src/TempStoreFactory.php
+++ b/core/modules/user/src/SharedTempStoreFactory.php
@@ -2,7 +2,7 @@
/**
* @file
- * Definition of Drupal\user\TempStoreFactory.
+ * Definition of Drupal\user\SharedTempStoreFactory.
*/
namespace Drupal\user;
@@ -12,9 +12,9 @@ use Drupal\Core\KeyValueStore\KeyValueExpirableFactoryInterface;
use Drupal\Core\Lock\LockBackendInterface;
/**
- * Creates a key/value storage object for the current user or anonymous session.
+ * Creates a shared temporary storage for a collection.
*/
-class TempStoreFactory {
+class SharedTempStoreFactory {
/**
* The storage factory creating the backend to store the data.
@@ -38,7 +38,7 @@ class TempStoreFactory {
protected $expire;
/**
- * Constructs a Drupal\user\TempStoreFactory object.
+ * Constructs a Drupal\user\SharedTempStoreFactory object.
*
* @param \Drupal\Core\Database\Connection $connection
* The connection object used for this data.
@@ -54,17 +54,17 @@ class TempStoreFactory {
}
/**
- * Creates a TempStore for the current user or anonymous session.
+ * 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 TempStore. By default, the TempStore is
- * owned by the currently authenticated user, or by the active anonymous
- * session if no user is logged in.
+ * (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\user\TempStore
+ * @return \Drupal\user\SharedTempStore
* An instance of the key/value store.
*/
function get($collection, $owner = NULL) {
@@ -75,8 +75,8 @@ class TempStoreFactory {
}
// Store the data for this collection in the database.
- $storage = $this->storageFactory->get("user.tempstore.$collection");
- return new TempStore($storage, $this->lockBackend, $owner, $this->expire);
+ $storage = $this->storageFactory->get("user.shared_tempstore.$collection");
+ return new SharedTempStore($storage, $this->lockBackend, $owner, $this->expire);
}
}
diff --git a/core/modules/user/src/TempStoreException.php b/core/modules/user/src/TempStoreException.php
index 497a2ef..a552b7b 100644
--- a/core/modules/user/src/TempStoreException.php
+++ b/core/modules/user/src/TempStoreException.php
@@ -8,6 +8,9 @@
namespace Drupal\user;
/**
- * Defines the exception thrown if the TempStore cannot acquire a lock.
+ * Thrown by SharedTempStore and PrivateTempStore if they cannot acquire a lock.
+ *
+ * @see \Drupal\user\SharedTempStore
+ * @see \Drupal\user\PrivateTempStore
*/
class TempStoreException extends \Exception {}
diff --git a/core/modules/user/src/Tests/TempStoreDatabaseTest.php b/core/modules/user/src/Tests/TempStoreDatabaseTest.php
index ad6f56b..b12cbf2 100644
--- a/core/modules/user/src/Tests/TempStoreDatabaseTest.php
+++ b/core/modules/user/src/Tests/TempStoreDatabaseTest.php
@@ -10,7 +10,7 @@ namespace Drupal\user\Tests;
use Drupal\Component\Serialization\PhpSerialize;
use Drupal\Core\KeyValueStore\KeyValueExpirableFactory;
use Drupal\simpletest\KernelTestBase;
-use Drupal\user\TempStoreFactory;
+use Drupal\user\SharedTempStoreFactory;
use Drupal\Core\Lock\DatabaseLockBackend;
use Drupal\Core\Database\Database;
@@ -32,7 +32,7 @@ class TempStoreDatabaseTest extends KernelTestBase {
/**
* A key/value store factory.
*
- * @var \Drupal\user\TempStoreFactory
+ * @var \Drupal\user\SharedTempStoreFactory
*/
protected $storeFactory;
@@ -76,14 +76,14 @@ class TempStoreDatabaseTest extends KernelTestBase {
*/
public function testUserTempStore() {
// Create a key/value collection.
- $factory = new TempStoreFactory(new KeyValueExpirableFactory(\Drupal::getContainer()), new DatabaseLockBackend(Database::getConnection()));
+ $factory = new SharedTempStoreFactory(new KeyValueExpirableFactory(\Drupal::getContainer()), new DatabaseLockBackend(Database::getConnection()));
$collection = $this->randomMachineName();
// Create two mock users.
for ($i = 0; $i <= 1; $i++) {
$users[$i] = mt_rand(500, 5000000);
- // Storing the TempStore objects in a class member variable causes a
+ // 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.
@@ -142,7 +142,7 @@ class TempStoreDatabaseTest extends KernelTestBase {
// assert it is no longer accessible.
db_update('key_value_expire')
->fields(array('expire' => REQUEST_TIME - 1))
- ->condition('collection', "user.tempstore.$collection")
+ ->condition('collection', "user.shared_tempstore.$collection")
->condition('name', $key)
->execute();
$this->assertFalse($stores[0]->get($key));
diff --git a/core/modules/user/tests/src/Unit/PrivateTempStoreTest.php b/core/modules/user/tests/src/Unit/PrivateTempStoreTest.php
new file mode 100644
index 0000000..51a1b50
--- /dev/null
+++ b/core/modules/user/tests/src/Unit/PrivateTempStoreTest.php
@@ -0,0 +1,283 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Tests\user\Unit\PrivateTempStoreTest.
+ */
+
+namespace Drupal\Tests\user\Unit;
+
+use Drupal\Tests\UnitTestCase;
+use Drupal\user\PrivateTempStore;
+use Symfony\Component\HttpFoundation\RequestStack;
+
+/**
+ * @coversDefaultClass \Drupal\user\PrivateTempStore
+ * @group user
+ */
+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 user temp store.
+ *
+ * @var \Drupal\user\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();
+
+ $this->tempStore = new PrivateTempStore($this->keyValue, $this->lock, $this->currentUser, $this->requestStack, 604800);
+
+ $this->ownObject = (object) array(
+ 'data' => 'test_data',
+ 'owner' => $this->currentUser->id(),
+ 'updated' => 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
+ * @expectedException \Drupal\user\TempStoreException
+ */
+ 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->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
+ * @expectedException \Drupal\user\TempStoreException
+ */
+ 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->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/modules/user/tests/src/Unit/TempStoreTest.php b/core/modules/user/tests/src/Unit/SharedTempStoreTest.php
index 68b4e70..a402a06 100644
--- a/core/modules/user/tests/src/Unit/TempStoreTest.php
+++ b/core/modules/user/tests/src/Unit/SharedTempStoreTest.php
@@ -2,19 +2,19 @@
/**
* @file
- * Contains \Drupal\Tests\user\Unit\TempStoreTest.
+ * Contains \Drupal\Tests\user\Unit\SharedTempStoreTest.
*/
namespace Drupal\Tests\user\Unit;
use Drupal\Tests\UnitTestCase;
-use Drupal\user\TempStore;
+use Drupal\user\SharedTempStore;
/**
- * @coversDefaultClass \Drupal\user\TempStore
+ * @coversDefaultClass \Drupal\user\SharedTempStore
* @group user
*/
-class TempStoreTest extends UnitTestCase {
+class SharedTempStoreTest extends UnitTestCase {
/**
* The mock key value expirable backend.
@@ -33,7 +33,7 @@ class TempStoreTest extends UnitTestCase {
/**
* The user temp store.
*
- * @var \Drupal\user\TempStore
+ * @var \Drupal\user\SharedTempStore
*/
protected $tempStore;
@@ -67,7 +67,7 @@ class TempStoreTest extends UnitTestCase {
$this->keyValue = $this->getMock('Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface');
$this->lock = $this->getMock('Drupal\Core\Lock\LockBackendInterface');
- $this->tempStore = new TempStore($this->keyValue, $this->lock, $this->owner, 604800);
+ $this->tempStore = new SharedTempStore($this->keyValue, $this->lock, $this->owner, 604800);
$this->ownObject = (object) array(
'data' => 'test_data',
diff --git a/core/modules/user/user.services.yml b/core/modules/user/user.services.yml
index 8a4f4f0..5bec22c 100644
--- a/core/modules/user/user.services.yml
+++ b/core/modules/user/user.services.yml
@@ -58,8 +58,13 @@ services:
user.auth:
class: Drupal\user\UserAuth
arguments: ['@entity.manager', '@password']
- user.tempstore:
- class: Drupal\user\TempStoreFactory
+ user.private_tempstore:
+ class: Drupal\user\PrivateTempStoreFactory
+ arguments: ['@keyvalue.expirable', '@lock', '@current_user', '@request_stack', '%user.tempstore.expire%']
+ tags:
+ - { name: backend_overridable }
+ user.shared_tempstore:
+ class: Drupal\user\SharedTempStoreFactory
arguments: ['@keyvalue.expirable', '@lock', '%user.tempstore.expire%']
tags:
- { name: backend_overridable }
diff --git a/core/modules/views/src/Entity/View.php b/core/modules/views/src/Entity/View.php
index 05bc393..e6e6e29 100644
--- a/core/modules/views/src/Entity/View.php
+++ b/core/modules/views/src/Entity/View.php
@@ -401,7 +401,7 @@ class View extends ConfigEntityBase implements ViewEntityInterface {
public static function postDelete(EntityStorageInterface $storage, array $entities) {
parent::postDelete($storage, $entities);
- $tempstore = \Drupal::service('user.tempstore')->get('views');
+ $tempstore = \Drupal::service('user.shared_tempstore')->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 0d6d8db..82f1f6f 100644
--- a/core/modules/views_ui/src/Form/BreakLockForm.php
+++ b/core/modules/views_ui/src/Form/BreakLockForm.php
@@ -10,7 +10,7 @@ namespace Drupal\views_ui\Form;
use Drupal\Core\Entity\EntityConfirmFormBase;
use Drupal\Core\Entity\EntityManagerInterface;
use Drupal\Core\Form\FormStateInterface;
-use Drupal\user\TempStoreFactory;
+use Drupal\user\SharedTempStoreFactory;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
@@ -28,7 +28,7 @@ class BreakLockForm extends EntityConfirmFormBase {
/**
* Stores the user tempstore.
*
- * @var \Drupal\user\TempStore
+ * @var \Drupal\user\SharedTempStore
*/
protected $tempStore;
@@ -37,10 +37,10 @@ class BreakLockForm extends EntityConfirmFormBase {
*
* @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
* The Entity manager.
- * @param \Drupal\user\TempStoreFactory $temp_store_factory
+ * @param \Drupal\user\SharedTempStoreFactory $temp_store_factory
* The factory for the temp store object.
*/
- public function __construct(EntityManagerInterface $entity_manager, TempStoreFactory $temp_store_factory) {
+ public function __construct(EntityManagerInterface $entity_manager, SharedTempStoreFactory $temp_store_factory) {
$this->entityManager = $entity_manager;
$this->tempStore = $temp_store_factory->get('views');
}
@@ -51,7 +51,7 @@ class BreakLockForm extends EntityConfirmFormBase {
public static function create(ContainerInterface $container) {
return new static(
$container->get('entity.manager'),
- $container->get('user.tempstore')
+ $container->get('user.shared_tempstore')
);
}
diff --git a/core/modules/views_ui/src/ParamConverter/ViewUIConverter.php b/core/modules/views_ui/src/ParamConverter/ViewUIConverter.php
index 1a6fa99..c31a615 100644
--- a/core/modules/views_ui/src/ParamConverter/ViewUIConverter.php
+++ b/core/modules/views_ui/src/ParamConverter/ViewUIConverter.php
@@ -11,7 +11,7 @@ use Drupal\Core\Entity\EntityManagerInterface;
use Drupal\Core\ParamConverter\EntityConverter;
use Symfony\Component\Routing\Route;
use Drupal\Core\ParamConverter\ParamConverterInterface;
-use Drupal\user\TempStoreFactory;
+use Drupal\user\SharedTempStoreFactory;
use Drupal\views_ui\ViewUI;
/**
@@ -35,17 +35,17 @@ class ViewUIConverter extends EntityConverter implements ParamConverterInterface
/**
* Stores the tempstore factory.
*
- * @var \Drupal\user\TempStoreFactory
+ * @var \Drupal\user\SharedTempStoreFactory
*/
protected $tempStoreFactory;
/**
* Constructs a new ViewUIConverter.
*
- * @param \Drupal\user\TempStoreFactory $temp_store_factory
+ * @param \Drupal\user\SharedTempStoreFactory $temp_store_factory
* The factory for the temp store object.
*/
- public function __construct(EntityManagerInterface $entity_manager, TempStoreFactory $temp_store_factory) {
+ public function __construct(EntityManagerInterface $entity_manager, SharedTempStoreFactory $temp_store_factory) {
parent::__construct($entity_manager);
$this->tempStoreFactory = $temp_store_factory;
diff --git a/core/modules/views_ui/src/Tests/CachedDataUITest.php b/core/modules/views_ui/src/Tests/CachedDataUITest.php
index f6ca040..6330b7d 100644
--- a/core/modules/views_ui/src/Tests/CachedDataUITest.php
+++ b/core/modules/views_ui/src/Tests/CachedDataUITest.php
@@ -27,7 +27,7 @@ class CachedDataUITest extends UITestBase {
public function testCacheData() {
$views_admin_user_uid = $this->fullAdminUser->id();
- $temp_store = $this->container->get('user.tempstore')->get('views');
+ $temp_store = $this->container->get('user.shared_tempstore')->get('views');
// The view should not be locked.
$this->assertEqual($temp_store->getMetadata('test_view'), NULL, 'The view is not locked.');
diff --git a/core/modules/views_ui/src/ViewEditForm.php b/core/modules/views_ui/src/ViewEditForm.php
index 37fc363..5d27d30 100644
--- a/core/modules/views_ui/src/ViewEditForm.php
+++ b/core/modules/views_ui/src/ViewEditForm.php
@@ -19,7 +19,7 @@ use Drupal\Component\Utility\String;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\Element;
use Drupal\Core\Url;
-use Drupal\user\TempStoreFactory;
+use Drupal\user\SharedTempStoreFactory;
use Drupal\views\Views;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
@@ -33,7 +33,7 @@ class ViewEditForm extends ViewFormBase {
/**
* The views temp store.
*
- * @var \Drupal\user\TempStore
+ * @var \Drupal\user\SharedTempStore
*/
protected $tempStore;
@@ -54,14 +54,14 @@ class ViewEditForm extends ViewFormBase {
/**
* Constructs a new ViewEditForm object.
*
- * @param \Drupal\user\TempStoreFactory $temp_store_factory
+ * @param \Drupal\user\SharedTempStoreFactory $temp_store_factory
* The factory for the temp store object.
* @param \Symfony\Component\HttpFoundation\RequestStack $requestStack
* The request stack object.
* @param \Drupal\Core\Datetime\DateFormatter $date_formatter
* The date Formatter service.
*/
- public function __construct(TempStoreFactory $temp_store_factory, RequestStack $requestStack, DateFormatter $date_formatter) {
+ public function __construct(SharedTempStoreFactory $temp_store_factory, RequestStack $requestStack, DateFormatter $date_formatter) {
$this->tempStore = $temp_store_factory->get('views');
$this->requestStack = $requestStack;
$this->dateFormatter = $date_formatter;
@@ -72,7 +72,7 @@ class ViewEditForm extends ViewFormBase {
*/
public static function create(ContainerInterface $container) {
return new static(
- $container->get('user.tempstore'),
+ $container->get('user.shared_tempstore'),
$container->get('request_stack'),
$container->get('date.formatter')
);
@@ -770,7 +770,7 @@ class ViewEditForm extends ViewFormBase {
* Submit handler for form buttons that do not complete a form workflow.
*
* The Edit View form is a multistep form workflow, but with state managed by
- * the TempStore rather than $form_state->setRebuild(). Without this
+ * the SharedTempStore rather than $form_state->setRebuild(). Without this
* submit handler, buttons that add or remove displays would redirect to the
* destination parameter (e.g., when the Edit View form is linked to from a
* contextual link). This handler can be added to buttons whose form submission
diff --git a/core/modules/views_ui/src/ViewUI.php b/core/modules/views_ui/src/ViewUI.php
index 52c7928..b8c6cd2 100644
--- a/core/modules/views_ui/src/ViewUI.php
+++ b/core/modules/views_ui/src/ViewUI.php
@@ -70,7 +70,8 @@ class ViewUI implements ViewEntityInterface {
* If this view is locked for editing.
*
* If this view is locked it will contain the result of
- * \Drupal\user\TempStore::getMetadata(). Which can be a stdClass or NULL.
+ * \Drupal\user\SharedTempStore::getMetadata(). Which can be a stdClass or
+ * NULL.
*
* @var stdClass
*/
@@ -879,7 +880,7 @@ class ViewUI implements ViewEntityInterface {
unset($executable->default_display);
$executable->query = NULL;
unset($executable->displayHandlers);
- \Drupal::service('user.tempstore')->get('views')->set($this->id(), $this);
+ \Drupal::service('user.shared_tempstore')->get('views')->set($this->id(), $this);
}
/**
diff --git a/core/modules/views_ui/views_ui.services.yml b/core/modules/views_ui/views_ui.services.yml
index e75c7af..7a91adb 100644
--- a/core/modules/views_ui/views_ui.services.yml
+++ b/core/modules/views_ui/views_ui.services.yml
@@ -1,6 +1,6 @@
services:
paramconverter.views_ui:
class: Drupal\views_ui\ParamConverter\ViewUIConverter
- arguments: ['@entity.manager', '@user.tempstore']
+ arguments: ['@entity.manager', '@user.shared_tempstore']
tags:
- { name: paramconverter, priority: 10 }