summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorcatch2012-03-23 16:52:50 +0900
committercatch2012-03-23 16:52:50 +0900
commit1198964079ef8506f6c6f795fe5c3c99d3cfbbea (patch)
treeefbdc1adf71ee850105fb07b738f082c637c28fe
parent2178d43211083881b45bd37483819b8961d585b0 (diff)
Issue #1015946 by pillarsdotnet, catch, bfroehle, Jej, jose.guevara, Damien Tournoud: Fixed Eliminate $user->cache and {session}.cache in favor of $_SESSION['cache_expiration()'][].
-rw-r--r--core/includes/bootstrap.inc1
-rw-r--r--core/includes/session.inc1
-rw-r--r--core/lib/Drupal/Core/Cache/DatabaseBackend.php47
-rw-r--r--core/modules/simpletest/tests/cache.test34
-rw-r--r--core/modules/system/system.install13
5 files changed, 73 insertions, 23 deletions
diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc
index 4967991..6954c4d 100644
--- a/core/includes/bootstrap.inc
+++ b/core/includes/bootstrap.inc
@@ -1956,7 +1956,6 @@ function drupal_anonymous_user() {
$user->hostname = ip_address();
$user->roles = array();
$user->roles[DRUPAL_ANONYMOUS_RID] = 'anonymous user';
- $user->cache = 0;
return $user;
}
diff --git a/core/includes/session.inc b/core/includes/session.inc
index 2d03a1e..b07997c 100644
--- a/core/includes/session.inc
+++ b/core/includes/session.inc
@@ -176,7 +176,6 @@ function _drupal_session_write($sid, $value) {
// Either ssid or sid or both will be added from $key below.
$fields = array(
'uid' => $user->uid,
- 'cache' => isset($user->cache) ? $user->cache : 0,
'hostname' => ip_address(),
'session' => $value,
'timestamp' => REQUEST_TIME,
diff --git a/core/lib/Drupal/Core/Cache/DatabaseBackend.php b/core/lib/Drupal/Core/Cache/DatabaseBackend.php
index 73c7139..44a4111 100644
--- a/core/lib/Drupal/Core/Cache/DatabaseBackend.php
+++ b/core/lib/Drupal/Core/Cache/DatabaseBackend.php
@@ -95,18 +95,17 @@ class DatabaseBackend implements CacheBackendInterface {
if (!isset($cache->data)) {
return FALSE;
}
- // If enforcing a minimum cache lifetime, validate that the data is
- // currently valid for this user before we return it by making sure the cache
- // entry was created before the timestamp in the current session's cache
- // timer. The cache variable is loaded into the $user object by
- // _drupal_session_read() in session.inc. If the data is permanent or we're
- // not enforcing a minimum cache lifetime always return the cached data.
+ // If the cached data is temporary and subject to a per-user minimum
+ // lifetime, compare the cache entry timestamp with the user session
+ // cache_expiration timestamp. If the cache entry is too old, ignore it.
$config = config('system.performance');
- if ($cache->expire != CACHE_PERMANENT && $config->get('cache_lifetime') && $user->cache > $cache->created) {
- // This cache data is too old and thus not valid for us, ignore it.
+ if ($cache->expire != CACHE_PERMANENT && $config->get('cache_lifetime') && isset($_SESSION['cache_expiration'][$this->bin]) && $_SESSION['cache_expiration'][$this->bin] > $cache->created) {
+ // Ignore cache data that is too old and thus not valid for this user.
return FALSE;
}
+ // If the data is permanent or not subject to a minimum cache lifetime,
+ // unserialize and return the cached data.
if ($cache->serialized) {
$cache->data = unserialize($cache->data);
}
@@ -186,11 +185,10 @@ class DatabaseBackend implements CacheBackendInterface {
*/
function expire() {
if (variable_get('cache_lifetime', 0)) {
- // We store the time in the current user's $user->cache variable which
- // will be saved into the sessions bin by _drupal_session_write(). We then
- // simulate that the cache was flushed for this user by not returning
- // cached data that was cached before the timestamp.
- $GLOBALS['user']->cache = REQUEST_TIME;
+ // We store the time in the current user's session. We then simulate
+ // that the cache was flushed for this user by not returning cached
+ // data that was cached before the timestamp.
+ $_SESSION['cache_expiration'][$this->bin] = REQUEST_TIME;
$cache_flush = variable_get('cache_flush_' . $this->bin, 0);
if ($cache_flush == 0) {
@@ -220,12 +218,31 @@ class DatabaseBackend implements CacheBackendInterface {
* Implements Drupal\Core\Cache\CacheBackendInterface::garbageCollection().
*/
function garbageCollection() {
- global $user;
+ $cache_lifetime = config('system.performance')->get('cache_lifetime');
+ // Clean-up the per-user cache expiration session data, so that the session
+ // handler can properly clean-up the session data for anonymous users.
+ if (isset($_SESSION['cache_expiration'])) {
+ $expire = REQUEST_TIME - $cache_lifetime;
+ foreach ($_SESSION['cache_expiration'] as $bin => $timestamp) {
+ if ($timestamp < $expire) {
+ unset($_SESSION['cache_expiration'][$bin]);
+ }
+ }
+ if (!$_SESSION['cache_expiration']) {
+ unset($_SESSION['cache_expiration']);
+ }
+ }
+
+ // Garbage collection of temporary items is only necessary when enforcing
+ // a minimum cache lifetime.
+ if (!$cache_lifetime) {
+ return;
+ }
// When cache lifetime is in force, avoid running garbage collection too
// often since this will remove temporary cache items indiscriminately.
$cache_flush = variable_get('cache_flush_' . $this->bin, 0);
- if ($cache_flush && ($cache_flush + variable_get('cache_lifetime', 0) <= REQUEST_TIME)) {
+ if ($cache_flush && ($cache_flush + $cache_lifetime <= REQUEST_TIME)) {
// Reset the variable immediately to prevent a meltdown in heavy load situations.
variable_set('cache_flush_' . $this->bin, 0);
// Time to flush old cache data
diff --git a/core/modules/simpletest/tests/cache.test b/core/modules/simpletest/tests/cache.test
index 81f2377..7040aef 100644
--- a/core/modules/simpletest/tests/cache.test
+++ b/core/modules/simpletest/tests/cache.test
@@ -336,6 +336,40 @@ class CacheClearCase extends CacheTestCase {
$this->assertFalse($this->checkCacheExists($cid, $this->default_value, $bin), t('All cache entries removed from @bin.', array('@bin' => $bin)));
}
}
+
+ /**
+ * Test minimum cache lifetime.
+ */
+ function testMinimumCacheLifetime() {
+ // Set a minimum/maximum cache lifetime.
+ $this->setupLifetime(300);
+ // Login as a newly-created user.
+ $account = $this->drupalCreateUser(array());
+ $this->drupalLogin($account);
+
+ // Set two cache objects in different bins.
+ $data = $this->randomName(100);
+ cache()->set($data, $data, CACHE_TEMPORARY);
+ $cached = cache()->get($data);
+ $this->assertTrue(isset($cached->data) && $cached->data === $data, 'Cached item retrieved.');
+ cache('page')->set($data, $data, CACHE_TEMPORARY);
+
+ // Expire temporary items in the 'page' bin.
+ cache('page')->expire();
+
+ // Since the database cache uses REQUEST_TIME, set the $_SESSION variable
+ // manually to force it to the current time.
+ $_SESSION['cache_expiration']['cache_page'] = time();
+
+ // Items in the default cache bin should not be expired.
+ $cached = cache()->get($data);
+ $this->assertTrue(isset($cached->data) && $cached->data == $data, 'Cached item retrieved');
+
+ // Despite the minimum cache lifetime, the item in the 'page' bin should
+ // be invalidated for the current user.
+ $cached = cache('page')->get($data);
+ $this->assertFalse($cached, 'Cached item was invalidated');
+ }
}
/**
diff --git a/core/modules/system/system.install b/core/modules/system/system.install
index 14d4853..905d11d 100644
--- a/core/modules/system/system.install
+++ b/core/modules/system/system.install
@@ -1506,12 +1506,6 @@ function system_schema() {
'not null' => TRUE,
'default' => 0,
),
- 'cache' => array(
- 'description' => "The time of this user's last post. This is used when the site has specified a minimum_cache_lifetime. See Drupal\Core\Cache\CacheBackendInterface::get().",
- 'type' => 'int',
- 'not null' => TRUE,
- 'default' => 0,
- ),
'session' => array(
'description' => 'The serialized contents of $_SESSION, an array of name/value pairs that persists across page requests by this session ID. Drupal loads $_SESSION from here at the start of each request and saves it at the end.',
'type' => 'blob',
@@ -1760,6 +1754,13 @@ function system_update_8004() {
}
}
+ /**
+ * Remove the obsolete {session}.cache column.
+ */
+function system_update_8005() {
+ db_drop_field('session', 'cache');
+}
+
/**
* @} End of "defgroup updates-7.x-to-8.x"
* The next series of updates should start at 9000.