diff --git a/core/lib/Drupal/Core/TempStore/SessionlessTempStore.php b/core/lib/Drupal/Core/TempStore/SessionlessTempStore.php new file mode 100644 index 0000000..22dc8a2 --- /dev/null +++ b/core/lib/Drupal/Core/TempStore/SessionlessTempStore.php @@ -0,0 +1,41 @@ +subsystem = $subsystem; + $this->sid = $sid; + } + + /** + * Overrides TempStore::getLockOwner(). + * + * Ignore the session table completely. + */ + public function getLockOwner($key, $exclude_owner = FALSE) { + return db_query('SELECT sid FROM {temp_store} WHERE subsystem = :subsystem AND temp_key = :temp_key', array( + ':subsystem' => $this->subsystem, + ':temp_key' => $key, + ))->fetchField(); + } +} diff --git a/core/lib/Drupal/Core/TempStore/TempStore.php b/core/lib/Drupal/Core/TempStore/TempStore.php index e668afc..049d2d8 100644 --- a/core/lib/Drupal/Core/TempStore/TempStore.php +++ b/core/lib/Drupal/Core/TempStore/TempStore.php @@ -7,8 +7,6 @@ namespace Drupal\Core\TempStore; -use Exception; - /** * Handles reading and writing to a non-volatile temporary storage area. * @@ -43,13 +41,6 @@ class TempStore { protected $sid; /** - * Whether or not the $sid is actually a session ID or some other identifier. - * - * @var bool - */ - public $useSessionTable; - - /** * Constructs a TempStore interaction object. * * @param string $subsystem @@ -63,15 +54,7 @@ class TempStore { */ function __construct($subsystem, $sid = NULL) { $this->subsystem = $subsystem; - - if (!isset($sid)) { - $this->sid = session_id(); - $this->useSessionTable = TRUE; - } - else { - $this->sid = $sid; - $this->useSessionTable = FALSE; - } + $this->sid = isset($sid) ? $sid : session_id(); } /** @@ -193,31 +176,26 @@ class TempStore { * * @param string $key * The key to the stored object. See TempStore::set() for details. + * @param bool $exclude_owner + * (optional) Whether or not to disregard the current user when determining + * the lock owner. Defaults to FALSE. * * @return stdClass|string|null - * The user ID of the data owner if it is in use, or NULL otherwise. + * An object with the user ID and updated date if found, otherwise NULL. */ - public function getLockOwner($key) { - if ($this->useSessionTable) { - $uid = db_query('SELECT s.uid, t.updated FROM {temp_store} t INNER JOIN {sessions} s ON t.sid = s.sid WHERE s.sid <> :session_id AND t.subsystem = :subsystem AND t.temp_key = :temp_key ORDER BY t.updated ASC', - array( - ':session_id' => $this->sid, - ':subsystem' => $this->subsystem, - ':temp_key' => $key, - ) - ) - ->fetchObject(); + public function getLockOwner($key, $exclude_owner = FALSE) { + $lock_owner = db_query('SELECT s.uid, t.updated FROM {temp_store} t INNER JOIN {sessions} s ON t.sid = s.sid WHERE t.subsystem = :subsystem AND t.temp_key = :temp_key ORDER BY t.updated ASC', array( + ':subsystem' => $this->subsystem, + ':temp_key' => $key, + ))->fetchObject(); + + // If the current user owns the lock and is excluded, report that the object + // is not locked. + if ($exclude_owner && isset($lock_owner->uid) && $lock_owner->uid == $GLOBALS['user']->uid) { + return; } - else { - $uid = db_query("SELECT sid FROM {temp_store} WHERE subsystem = :subsystem AND temp_key = :temp_key", - array( - ':subsystem' => $this->subsystem, - ':temp_key' => $key, - ) - ) - ->fetchField(); - } - return $uid; + + return $lock_owner; } /** diff --git a/core/lib/Drupal/Core/TempStore/TempStoreException.php b/core/lib/Drupal/Core/TempStore/TempStoreException.php new file mode 100644 index 0000000..fe65c56 --- /dev/null +++ b/core/lib/Drupal/Core/TempStore/TempStoreException.php @@ -0,0 +1,16 @@ +drupalLogin($this->actingUser); $subsystem = $this->randomName(); - $temp_store = new TempStore($subsystem); + $temp_store = new TempStore($subsystem, $this->session_id); // An empty storage should return nothing. $this->assertFalse($temp_store->get($this->randomName())); @@ -83,19 +83,6 @@ class TempStoreTest extends WebTestBase { $temp_store->delete($random_key); $this->assertFalse($temp_store->get($random_key)); - // Add some data to check the behavior for different users. - $temp_store->set($random_key, $random_object); - - // Change the user, to be sure the tempstore is not returning the same data - // for different users. - $this->drupalLogin($this->anotherUser); - $this->assertFalse($temp_store->get($random_key)); - - // Change the user back, to be sure the tempstore is not returning the same - // data for different sessions. - $this->drupalLogin($this->actingUser); - $this->assertFalse($temp_store->get($random_key)); - // Create multiple keys to test the deleteAll functionality. $keys = array(); for ($i = 0; $i < 4; $i++) { @@ -130,14 +117,21 @@ class TempStoreTest extends WebTestBase { $this->assertTrue($temp_store->get($new_key)); // Test the getLockOwner method. - $tempStore_one = new TempStore($subsystem, $this->actingUser->uid); - $tempStore_two = new TempStore($subsystem, $this->anotherUser->uid); + $tempStore_one = new TempStore($subsystem, $this->session_id); + + // Allow two users to be logged in at once. + $this->curlClose(); + $this->loggedInUser = FALSE; + + $this->drupalLogin($this->anotherUser); + $tempStore_two = new TempStore($subsystem, $this->session_id); + $key_user_one = $this->randomName(); $key_user_two = $this->randomName(); $tempStore_one->set($key_user_one, $this->randomObject()); $tempStore_two->set($key_user_two, $this->randomObject()); - $this->assertEqual($tempStore_one->getLockOwner($key_user_one), $this->actingUser->uid); - $this->assertEqual($tempStore_two->getLockOwner($key_user_two), $this->anotherUser->uid); + $this->assertEqual($tempStore_one->getLockOwner($key_user_one)->uid, $this->actingUser->uid); + $this->assertEqual($tempStore_two->getLockOwner($key_user_two)->uid, $this->anotherUser->uid); } }