Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge branch 'wip-MDL-38303-m24' of git://github.com/samhemelryk/mood…

…le into MOODLE_24_STABLE
  • Loading branch information...
commit ea8393591f6e9730d31a184210b2ffc161db5636 2 parents ecbf8ae + d55276e
@damyon damyon authored
Showing with 113 additions and 0 deletions.
  1. +54 −0 cache/classes/loaders.php
  2. +59 −0 cache/tests/cache_test.php
View
54 cache/classes/loaders.php
@@ -1411,6 +1411,17 @@ public function delete_many(array $keys, $recurse = true) {
*/
class cache_session extends cache {
/**
+ * The user the session has been established for.
+ * @var int
+ */
+ protected static $loadeduserid = null;
+
+ /**
+ * The userid this cache is currently using.
+ * @var int
+ */
+ protected $currentuserid = null;
+ /**
* Override the cache::construct method.
*
* This function gets overriden so that we can process any invalidation events if need be.
@@ -1426,6 +1437,8 @@ class cache_session extends cache {
* @return void
*/
public function __construct(cache_definition $definition, cache_store $store, $loader = null) {
+ // First up copy the loadeduserid to the current user id.
+ $this->currentuserid = self::$loadeduserid;
parent::__construct($definition, $store, $loader);
if ($definition->has_invalidation_events()) {
$lastinvalidation = $this->get('lastsessioninvalidation');
@@ -1474,6 +1487,47 @@ public function __construct(cache_definition $definition, cache_store $store, $l
$this->set('lastsessioninvalidation', cache::now());
}
}
+
+ /**
+ * Parses the key turning it into a string (or array is required) suitable to be passed to the cache store.
+ *
+ * This function is called for every operation that uses keys. For this reason we use this function to also check
+ * that the current user is the same as the user who last used this cache.
+ *
+ * @param string|int $key As passed to get|set|delete etc.
+ * @return string|array String unless the store supports multi-identifiers in which case an array if returned.
+ */
+ protected function parse_key($key) {
+ $this->check_tracked_user();
+ return parent::parse_key($key);
+ }
+
+ /**
+ * Check that this cache instance is tracking the current user.
+ */
+ protected function check_tracked_user() {
+ if (isset($_SESSION['USER']->id)) {
+ // Get the id of the current user.
+ $new = $_SESSION['USER']->id;
+ } else {
+ // No user set up yet.
+ $new = 0;
+ }
+ if ($new !== self::$loadeduserid) {
+ // The current user doesn't match the tracker userid for this request.
+ if (!is_null(self::$loadeduserid)) {
+ // Purge the data we have for the old user.
+ // This way we don't bloat the session.
+ $this->purge();
+ }
+ self::$loadeduserid = $new;
+ $this->currentuserid = $new;
+ } else if ($new !== $this->currentuserid) {
+ // The current user matches the loaded user but not the user last used by this cache.
+ $this->purge();
+ $this->currentuserid = $new;
+ }
+ }
}
/**
View
59 cache/tests/cache_test.php
@@ -849,4 +849,63 @@ public function test_multiple_loaders() {
$this->assertTrue($cache->set('test', 'test'));
$this->assertEquals('test', $cache->get('test'));
}
+
+ /**
+ * Test switching users with session caches.
+ */
+ public function test_session_cache_switch_user() {
+ $this->resetAfterTest(true);
+ $cache = cache::make_from_params(cache_store::MODE_SESSION, 'phpunit', 'sessioncache');
+ $user1 = $this->getDataGenerator()->create_user();
+ $user2 = $this->getDataGenerator()->create_user();
+
+ // Log in as the first user.
+ $this->setUser($user1);
+ $sesskey1 = sesskey();
+
+ // Set a basic value in the cache.
+ $cache->set('var', 1);
+ $this->assertTrue($cache->has('var'));
+ $this->assertEquals(1, $cache->get('var'));
+
+ // Change to the second user.
+ $this->setUser($user2);
+ $sesskey2 = sesskey();
+
+ // Make sure the cache doesn't give us the data for the last user.
+ $this->assertNotEquals($sesskey1, $sesskey2);
+ $this->assertFalse($cache->has('var'));
+ $this->assertEquals(false, $cache->get('var'));
+ }
+
+ /**
+ * Test multiple session caches when switching user.
+ */
+ public function test_session_cache_switch_user_multiple() {
+ $this->resetAfterTest(true);
+ $cache1 = cache::make_from_params(cache_store::MODE_SESSION, 'phpunit', 'sessioncache1');
+ $cache2 = cache::make_from_params(cache_store::MODE_SESSION, 'phpunit', 'sessioncache2');
+ $user1 = $this->getDataGenerator()->create_user();
+ $user2 = $this->getDataGenerator()->create_user();
+
+ // Log in as the first user.
+ $this->setUser($user1);
+ $sesskey1 = sesskey();
+
+ // Set a basic value in the caches.
+ $cache1->set('var', 1);
+ $cache2->set('var', 2);
+ $this->assertEquals(1, $cache1->get('var'));
+ $this->assertEquals(2, $cache2->get('var'));
+
+ // Change to the second user.
+ $this->setUser($user2);
+ $sesskey2 = sesskey();
+
+ // Make sure the cache doesn't give us the data for the last user.
+ // Also make sure that switching the user has lead to both caches being purged.
+ $this->assertNotEquals($sesskey1, $sesskey2);
+ $this->assertEquals(false, $cache1->get('var'));
+ $this->assertEquals(false, $cache2->get('var'));
+ }
}
Please sign in to comment.
Something went wrong with that request. Please try again.