comparison core/modules/user/src/PrivateTempStore.php @ 14:1fec387a4317

Update Drupal core to 8.5.2 via Composer
author Chris Cannam
date Mon, 23 Apr 2018 09:46:53 +0100
parents 7a779792577d
children
comparison
equal deleted inserted replaced
13:5fb285c0d0e3 14:1fec387a4317
1 <?php 1 <?php
2 2
3 namespace Drupal\user; 3 namespace Drupal\user;
4 4
5 use Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface; 5 use Drupal\Core\TempStore\PrivateTempStore as CorePrivateTempStore;
6 use Drupal\Core\Lock\LockBackendInterface; 6
7 use Drupal\Core\Session\AccountProxyInterface; 7 @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);
8 use Symfony\Component\HttpFoundation\RequestStack; 8
9 /**
10 * In order to preserve BC alias the core exception.
11 */
12 if (!class_exists('\Drupal\user\TempStoreException')) {
13 class_alias('\Drupal\Core\TempStore\TempStoreException', '\Drupal\user\TempStoreException');
14 }
9 15
10 /** 16 /**
11 * Stores and retrieves temporary data for a given owner. 17 * Stores and retrieves temporary data for a given owner.
12 * 18 *
13 * A PrivateTempStore can be used to make temporary, non-cache data available 19 * @deprecated in Drupal 8.5.x, to be removed before Drupal 9.0.0.
14 * across requests. The data for the PrivateTempStore is stored in one 20 * Use \Drupal\Core\TempStore\PrivateTempStore instead.
15 * key/value collection. PrivateTempStore data expires automatically after a
16 * given timeframe.
17 * 21 *
18 * The PrivateTempStore is different from a cache, because the data in it is not 22 * @see \Drupal\Core\TempStore\PrivateTempStore
19 * yet saved permanently and so it cannot be rebuilt. Typically, the 23 * @see https://www.drupal.org/node/2935639
20 * PrivateTempStore might be used to store work in progress that is later saved
21 * permanently elsewhere, e.g. autosave data, multistep forms, or in-progress
22 * changes to complex configuration that are not ready to be saved.
23 *
24 * The PrivateTempStore differs from the SharedTempStore in that all keys are
25 * ensured to be unique for a particular user and users can never share data. If
26 * you want to be able to share data between users or use it for locking, use
27 * \Drupal\user\SharedTempStore.
28 */ 24 */
29 class PrivateTempStore { 25 class PrivateTempStore extends CorePrivateTempStore {
30
31 /**
32 * The key/value storage object used for this data.
33 *
34 * @var \Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface
35 */
36 protected $storage;
37
38 /**
39 * The lock object used for this data.
40 *
41 * @var \Drupal\Core\Lock\LockBackendInterface
42 */
43 protected $lockBackend;
44
45 /**
46 * The current user.
47 *
48 * @var \Drupal\Core\Session\AccountProxyInterface
49 */
50 protected $currentUser;
51
52 /**
53 * The request stack.
54 *
55 * @var \Symfony\Component\HttpFoundation\RequestStack
56 */
57 protected $requestStack;
58
59 /**
60 * The time to live for items in seconds.
61 *
62 * By default, data is stored for one week (604800 seconds) before expiring.
63 *
64 * @var int
65 */
66 protected $expire;
67
68 /**
69 * Constructs a new object for accessing data from a key/value store.
70 *
71 * @param \Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface $storage
72 * The key/value storage object used for this data. Each storage object
73 * represents a particular collection of data and will contain any number
74 * of key/value pairs.
75 * @param \Drupal\Core\Lock\LockBackendInterface $lock_backend
76 * The lock object used for this data.
77 * @param \Drupal\Core\Session\AccountProxyInterface $current_user
78 * The current user account.
79 * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
80 * The request stack.
81 * @param int $expire
82 * The time to live for items, in seconds.
83 */
84 public function __construct(KeyValueStoreExpirableInterface $storage, LockBackendInterface $lock_backend, AccountProxyInterface $current_user, RequestStack $request_stack, $expire = 604800) {
85 $this->storage = $storage;
86 $this->lockBackend = $lock_backend;
87 $this->currentUser = $current_user;
88 $this->requestStack = $request_stack;
89 $this->expire = $expire;
90 }
91
92 /**
93 * Retrieves a value from this PrivateTempStore for a given key.
94 *
95 * @param string $key
96 * The key of the data to retrieve.
97 *
98 * @return mixed
99 * The data associated with the key, or NULL if the key does not exist.
100 */
101 public function get($key) {
102 $key = $this->createkey($key);
103 if (($object = $this->storage->get($key)) && ($object->owner == $this->getOwner())) {
104 return $object->data;
105 }
106 }
107
108 /**
109 * Stores a particular key/value pair in this PrivateTempStore.
110 *
111 * @param string $key
112 * The key of the data to store.
113 * @param mixed $value
114 * The data to store.
115 *
116 * @throws \Drupal\user\TempStoreException
117 * Thrown when a lock for the backend storage could not be acquired.
118 */
119 public function set($key, $value) {
120 $key = $this->createkey($key);
121 if (!$this->lockBackend->acquire($key)) {
122 $this->lockBackend->wait($key);
123 if (!$this->lockBackend->acquire($key)) {
124 throw new TempStoreException("Couldn't acquire lock to update item '$key' in '{$this->storage->getCollectionName()}' temporary storage.");
125 }
126 }
127
128 $value = (object) [
129 'owner' => $this->getOwner(),
130 'data' => $value,
131 'updated' => (int) $this->requestStack->getMasterRequest()->server->get('REQUEST_TIME'),
132 ];
133 $this->storage->setWithExpire($key, $value, $this->expire);
134 $this->lockBackend->release($key);
135 }
136
137 /**
138 * Returns the metadata associated with a particular key/value pair.
139 *
140 * @param string $key
141 * The key of the data to store.
142 *
143 * @return mixed
144 * An object with the owner and updated time if the key has a value, or
145 * NULL otherwise.
146 */
147 public function getMetadata($key) {
148 $key = $this->createkey($key);
149 // Fetch the key/value pair and its metadata.
150 $object = $this->storage->get($key);
151 if ($object) {
152 // Don't keep the data itself in memory.
153 unset($object->data);
154 return $object;
155 }
156 }
157
158 /**
159 * Deletes data from the store for a given key and releases the lock on it.
160 *
161 * @param string $key
162 * The key of the data to delete.
163 *
164 * @return bool
165 * TRUE if the object was deleted or does not exist, FALSE if it exists but
166 * is not owned by $this->owner.
167 *
168 * @throws \Drupal\user\TempStoreException
169 * Thrown when a lock for the backend storage could not be acquired.
170 */
171 public function delete($key) {
172 $key = $this->createkey($key);
173 if (!$object = $this->storage->get($key)) {
174 return TRUE;
175 }
176 elseif ($object->owner != $this->getOwner()) {
177 return FALSE;
178 }
179 if (!$this->lockBackend->acquire($key)) {
180 $this->lockBackend->wait($key);
181 if (!$this->lockBackend->acquire($key)) {
182 throw new TempStoreException("Couldn't acquire lock to delete item '$key' from '{$this->storage->getCollectionName()}' temporary storage.");
183 }
184 }
185 $this->storage->delete($key);
186 $this->lockBackend->release($key);
187 return TRUE;
188 }
189
190 /**
191 * Ensures that the key is unique for a user.
192 *
193 * @param string $key
194 * The key.
195 *
196 * @return string
197 * The unique key for the user.
198 */
199 protected function createkey($key) {
200 return $this->getOwner() . ':' . $key;
201 }
202
203 /**
204 * Gets the current owner based on the current user or the session ID.
205 *
206 * @return string
207 * The owner.
208 */
209 protected function getOwner() {
210 return $this->currentUser->id() ?: $this->requestStack->getCurrentRequest()->getSession()->getId();
211 }
212
213 } 26 }