comparison core/modules/user/src/SharedTempStore.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\SharedTempStore as CoreSharedTempStore;
6 use Drupal\Core\Lock\LockBackendInterface; 6
7 use Symfony\Component\HttpFoundation\RequestStack; 7 @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);
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 }
8 15
9 /** 16 /**
10 * Stores and retrieves temporary data for a given owner. 17 * Stores and retrieves temporary data for a given owner.
11 * 18 *
12 * A SharedTempStore 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.
13 * across requests. The data for the SharedTempStore is stored in one key/value 20 * Use \Drupal\Core\TempStore\SharedTempStore instead.
14 * collection. SharedTempStore data expires automatically after a given
15 * timeframe.
16 * 21 *
17 * The SharedTempStore is different from a cache, because the data in it is not 22 * @see \Drupal\Core\TempStore\SharedTempStore
18 * yet saved permanently and so it cannot be rebuilt. Typically, the 23 * @see https://www.drupal.org/node/2935639
19 * SharedTempStore might be used to store work in progress that is later saved
20 * permanently elsewhere, e.g. autosave data, multistep forms, or in-progress
21 * changes to complex configuration that are not ready to be saved.
22 *
23 * Each SharedTempStore belongs to a particular owner (e.g. a user, session, or
24 * process). Multiple owners may use the same key/value collection, and the
25 * owner is stored along with the key/value pair.
26 *
27 * Every key is unique within the collection, so the SharedTempStore can check
28 * whether a particular key is already set by a different owner. This is
29 * useful for informing one owner that the data is already in use by another;
30 * for example, to let one user know that another user is in the process of
31 * editing certain data, or even to restrict other users from editing it at
32 * the same time. It is the responsibility of the implementation to decide
33 * when and whether one owner can use or update another owner's data.
34 *
35 * If you want to be able to ensure that the data belongs to the current user,
36 * use \Drupal\user\PrivateTempStore.
37 */ 24 */
38 class SharedTempStore { 25 class SharedTempStore extends CoreSharedTempStore {
39
40 /**
41 * The key/value storage object used for this data.
42 *
43 * @var \Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface
44 */
45 protected $storage;
46
47 /**
48 * The lock object used for this data.
49 *
50 * @var \Drupal\Core\Lock\LockBackendInterface
51 */
52 protected $lockBackend;
53
54 /**
55 * The request stack.
56 *
57 * @var \Symfony\Component\HttpFoundation\RequestStack
58 */
59 protected $requestStack;
60
61 /**
62 * The owner key to store along with the data (e.g. a user or session ID).
63 *
64 * @var mixed
65 */
66 protected $owner;
67
68 /**
69 * The time to live for items in seconds.
70 *
71 * By default, data is stored for one week (604800 seconds) before expiring.
72 *
73 * @var int
74 */
75 protected $expire;
76
77 /**
78 * Constructs a new object for accessing data from a key/value store.
79 *
80 * @param \Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface $storage
81 * The key/value storage object used for this data. Each storage object
82 * represents a particular collection of data and will contain any number
83 * of key/value pairs.
84 * @param \Drupal\Core\Lock\LockBackendInterface $lock_backend
85 * The lock object used for this data.
86 * @param mixed $owner
87 * The owner key to store along with the data (e.g. a user or session ID).
88 * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
89 * The request stack.
90 * @param int $expire
91 * The time to live for items, in seconds.
92 */
93 public function __construct(KeyValueStoreExpirableInterface $storage, LockBackendInterface $lock_backend, $owner, RequestStack $request_stack, $expire = 604800) {
94 $this->storage = $storage;
95 $this->lockBackend = $lock_backend;
96 $this->owner = $owner;
97 $this->requestStack = $request_stack;
98 $this->expire = $expire;
99 }
100
101 /**
102 * Retrieves a value from this SharedTempStore for a given key.
103 *
104 * @param string $key
105 * The key of the data to retrieve.
106 *
107 * @return mixed
108 * The data associated with the key, or NULL if the key does not exist.
109 */
110 public function get($key) {
111 if ($object = $this->storage->get($key)) {
112 return $object->data;
113 }
114 }
115
116 /**
117 * Retrieves a value from this SharedTempStore for a given key.
118 *
119 * Only returns the value if the value is owned by $this->owner.
120 *
121 * @param string $key
122 * The key of the data to retrieve.
123 *
124 * @return mixed
125 * The data associated with the key, or NULL if the key does not exist.
126 */
127 public function getIfOwner($key) {
128 if (($object = $this->storage->get($key)) && ($object->owner == $this->owner)) {
129 return $object->data;
130 }
131 }
132
133 /**
134 * Stores a particular key/value pair only if the key doesn't already exist.
135 *
136 * @param string $key
137 * The key of the data to check and store.
138 * @param mixed $value
139 * The data to store.
140 *
141 * @return bool
142 * TRUE if the data was set, or FALSE if it already existed.
143 */
144 public function setIfNotExists($key, $value) {
145 $value = (object) [
146 'owner' => $this->owner,
147 'data' => $value,
148 'updated' => (int) $this->requestStack->getMasterRequest()->server->get('REQUEST_TIME'),
149 ];
150 return $this->storage->setWithExpireIfNotExists($key, $value, $this->expire);
151 }
152
153 /**
154 * Stores a particular key/value pair in this SharedTempStore.
155 *
156 * Only stores the given key/value pair if it does not exist yet or is owned
157 * by $this->owner.
158 *
159 * @param string $key
160 * The key of the data to store.
161 * @param mixed $value
162 * The data to store.
163 *
164 * @return bool
165 * TRUE if the data was set, or FALSE if it already exists and is not owned
166 * by $this->user.
167 *
168 * @throws \Drupal\user\TempStoreException
169 * Thrown when a lock for the backend storage could not be acquired.
170 */
171 public function setIfOwner($key, $value) {
172 if ($this->setIfNotExists($key, $value)) {
173 return TRUE;
174 }
175
176 if (($object = $this->storage->get($key)) && ($object->owner == $this->owner)) {
177 $this->set($key, $value);
178 return TRUE;
179 }
180
181 return FALSE;
182 }
183
184 /**
185 * Stores a particular key/value pair in this SharedTempStore.
186 *
187 * @param string $key
188 * The key of the data to store.
189 * @param mixed $value
190 * The data to store.
191 *
192 * @throws \Drupal\user\TempStoreException
193 * Thrown when a lock for the backend storage could not be acquired.
194 */
195 public function set($key, $value) {
196 if (!$this->lockBackend->acquire($key)) {
197 $this->lockBackend->wait($key);
198 if (!$this->lockBackend->acquire($key)) {
199 throw new TempStoreException("Couldn't acquire lock to update item '$key' in '{$this->storage->getCollectionName()}' temporary storage.");
200 }
201 }
202
203 $value = (object) [
204 'owner' => $this->owner,
205 'data' => $value,
206 'updated' => (int) $this->requestStack->getMasterRequest()->server->get('REQUEST_TIME'),
207 ];
208 $this->storage->setWithExpire($key, $value, $this->expire);
209 $this->lockBackend->release($key);
210 }
211
212 /**
213 * Returns the metadata associated with a particular key/value pair.
214 *
215 * @param string $key
216 * The key of the data to store.
217 *
218 * @return mixed
219 * An object with the owner and updated time if the key has a value, or
220 * NULL otherwise.
221 */
222 public function getMetadata($key) {
223 // Fetch the key/value pair and its metadata.
224 $object = $this->storage->get($key);
225 if ($object) {
226 // Don't keep the data itself in memory.
227 unset($object->data);
228 return $object;
229 }
230 }
231
232 /**
233 * Deletes data from the store for a given key and releases the lock on it.
234 *
235 * @param string $key
236 * The key of the data to delete.
237 *
238 * @throws \Drupal\user\TempStoreException
239 * Thrown when a lock for the backend storage could not be acquired.
240 */
241 public function delete($key) {
242 if (!$this->lockBackend->acquire($key)) {
243 $this->lockBackend->wait($key);
244 if (!$this->lockBackend->acquire($key)) {
245 throw new TempStoreException("Couldn't acquire lock to delete item '$key' from {$this->storage->getCollectionName()} temporary storage.");
246 }
247 }
248 $this->storage->delete($key);
249 $this->lockBackend->release($key);
250 }
251
252 /**
253 * Deletes data from the store for a given key and releases the lock on it.
254 *
255 * Only delete the given key if it is owned by $this->owner.
256 *
257 * @param string $key
258 * The key of the data to delete.
259 *
260 * @return bool
261 * TRUE if the object was deleted or does not exist, FALSE if it exists but
262 * is not owned by $this->owner.
263 *
264 * @throws \Drupal\user\TempStoreException
265 * Thrown when a lock for the backend storage could not be acquired.
266 */
267 public function deleteIfOwner($key) {
268 if (!$object = $this->storage->get($key)) {
269 return TRUE;
270 }
271 elseif ($object->owner == $this->owner) {
272 $this->delete($key);
273 return TRUE;
274 }
275
276 return FALSE;
277 }
278
279 } 26 }