summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDries2013-03-27 18:57:12 (GMT)
committerDries2013-03-27 18:57:12 (GMT)
commit5818a99bfc9919babd7faa7df4b9743bedd6016c (patch)
tree2ccf0b8c9a3cb1a15390794d50f4270b6ed9c460
parent0bb14c814d789c82ca7f5a447cdb0e7512e702c8 (diff)
Issue #512026 by Berdir, effulgentsia, sun, marcingy, Eric_A, xjm, katbailey, Damien Tournoud, alexpott, beejeebus, pillarsdotnet: Move () storage from cache to new state/key-value system.
-rw-r--r--core/includes/common.inc3
-rw-r--r--core/includes/form.inc21
-rw-r--r--core/includes/install.core.inc10
-rw-r--r--core/lib/Drupal/Core/CoreBundle.php2
-rw-r--r--core/lib/Drupal/Core/KeyValueStore/KeyValueNullExpirableFactory.php28
-rw-r--r--core/lib/Drupal/Core/KeyValueStore/NullStorageExpirable.php109
-rw-r--r--core/modules/system/lib/Drupal/system/Tests/Cache/ClearTest.php2
-rw-r--r--core/modules/system/lib/Drupal/system/Tests/Form/FormCacheTest.php89
-rw-r--r--core/modules/system/system.install9
-rw-r--r--core/modules/views/lib/Drupal/views/Tests/Handler/FilterEqualityTest.php2
-rw-r--r--core/modules/views/lib/Drupal/views/Tests/Handler/FilterInOperatorTest.php2
-rw-r--r--core/modules/views/lib/Drupal/views/Tests/Handler/FilterNumericTest.php2
-rw-r--r--core/modules/views/lib/Drupal/views/Tests/Handler/FilterStringTest.php2
13 files changed, 253 insertions, 28 deletions
diff --git a/core/includes/common.inc b/core/includes/common.inc
index 80f3d0e..86fc44a 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -6369,8 +6369,7 @@ function drupal_flush_all_caches() {
// sufficient, since new extensions cannot have any primed caches yet.
module_invoke_all('cache_flush');
foreach (Cache::getBins() as $service_id => $cache_backend) {
- // @todo remove form after http://drupal.org/node/512026 is in.
- if ($service_id != 'cache.form' && $service_id != 'cache.menu') {
+ if ($service_id != 'cache.menu') {
$cache_backend->deleteAll();
}
}
diff --git a/core/includes/form.inc b/core/includes/form.inc
index 51d9829..19993c6 100644
--- a/core/includes/form.inc
+++ b/core/includes/form.inc
@@ -530,14 +530,12 @@ function drupal_rebuild_form($form_id, &$form_state, $old_form = NULL) {
* Fetches a form from the cache.
*/
function form_get_cache($form_build_id, &$form_state) {
- if ($cached = cache('form')->get('form_' . $form_build_id)) {
- $form = $cached->data;
-
+ if ($form = Drupal::keyValueExpirable('form')->get($form_build_id)) {
global $user;
if ((isset($form['#cache_token']) && drupal_valid_token($form['#cache_token'])) || (!isset($form['#cache_token']) && !$user->uid)) {
- if ($cached = cache('form')->get('form_state_' . $form_build_id)) {
+ if ($stored_form_state = Drupal::keyValueExpirable('form_state')->get($form_build_id)) {
// Re-populate $form_state for subsequent rebuilds.
- $form_state = $cached->data + $form_state;
+ $form_state = $stored_form_state + $form_state;
// If the original form is contained in include files, load the files.
// @see form_load_include()
@@ -569,12 +567,12 @@ function form_set_cache($form_build_id, $form, $form_state) {
if ($GLOBALS['user']->uid) {
$form['#cache_token'] = drupal_get_token();
}
- cache('form')->set('form_' . $form_build_id, $form, REQUEST_TIME + $expire);
+ Drupal::keyValueExpirable('form')->setWithExpire($form_build_id, $form, $expire);
}
// Cache form state.
if ($data = array_diff_key($form_state, array_flip(form_state_keys_no_cache()))) {
- cache('form')->set('form_state_' . $form_build_id, $data, REQUEST_TIME + $expire);
+ Drupal::keyValueExpirable('form_state')->setWithExpire($form_build_id, $data, $expire);
}
}
@@ -916,15 +914,6 @@ function drupal_process_form($form_id, &$form, &$form_state) {
// Execute form submit handlers.
form_execute_handlers('submit', $form, $form_state);
- // We'll clear out the cached copies of the form and its stored data
- // here, as we've finished with them. The in-memory copies are still
- // here, though.
- $config = config('system.performance');
- if (!$config->get('cache.page.use_internal') && !empty($form_state['values']['form_build_id'])) {
- cache('form')->delete('form_' . $form_state['values']['form_build_id']);
- cache('form')->delete('form_state_' . $form_state['values']['form_build_id']);
- }
-
// If batches were set in the submit handlers, we process them now,
// possibly ending execution. We make sure we do not react to the batch
// that is already being processed (if a batch operation performs a
diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc
index bf8ef66..2395f70 100644
--- a/core/includes/install.core.inc
+++ b/core/includes/install.core.inc
@@ -350,7 +350,7 @@ function install_begin_request(&$install_state) {
// Register the 'language_manager' service.
$container->register('language_manager', 'Drupal\Core\Language\LanguageManager');
- foreach (array('bootstrap', 'config', 'cache', 'form', 'menu', 'page', 'path') as $bin) {
+ foreach (array('bootstrap', 'config', 'cache', 'menu', 'page', 'path') as $bin) {
$container
->register("cache.$bin", 'Drupal\Core\Cache\MemoryBackend')
->addArgument($bin);
@@ -379,6 +379,14 @@ function install_begin_request(&$install_state) {
))
->addMethodCall('setUserAgent', array('Drupal (+http://drupal.org/)'));
+ // Register the expirable key value store used by form cache.
+ $container
+ ->register('keyvalue.expirable', 'Drupal\Core\KeyValueStore\KeyValueExpirableFactory')
+ ->addArgument(new Reference('service_container'));
+ $container
+ ->register('keyvalue.expirable.null', 'Drupal\Core\KeyValueStore\KeyValueNullExpirableFactory');
+ $conf['keyvalue_expirable_default'] = 'keyvalue.expirable.null';
+
Drupal::setContainer($container);
}
diff --git a/core/lib/Drupal/Core/CoreBundle.php b/core/lib/Drupal/Core/CoreBundle.php
index 35b1b6d..91a7d01 100644
--- a/core/lib/Drupal/Core/CoreBundle.php
+++ b/core/lib/Drupal/Core/CoreBundle.php
@@ -451,7 +451,7 @@ class CoreBundle extends Bundle {
$container
->register('cache.backend.memory', 'Drupal\Core\Cache\MemoryBackendFactory');
// Register a service for each bin for injecting purposes.
- foreach (array('bootstrap', 'config', 'cache', 'form', 'menu', 'page', 'path') as $bin) {
+ foreach (array('bootstrap', 'config', 'cache', 'menu', 'page', 'path') as $bin) {
CacheFactory::registerBin($container, $bin);
}
diff --git a/core/lib/Drupal/Core/KeyValueStore/KeyValueNullExpirableFactory.php b/core/lib/Drupal/Core/KeyValueStore/KeyValueNullExpirableFactory.php
new file mode 100644
index 0000000..27310da
--- /dev/null
+++ b/core/lib/Drupal/Core/KeyValueStore/KeyValueNullExpirableFactory.php
@@ -0,0 +1,28 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\KeyValueStore\KeyValueNullExpirableFactory.
+ */
+
+namespace Drupal\Core\KeyValueStore;
+
+/**
+ * Defines the key/value store factory for the null backend.
+ */
+class KeyValueNullExpirableFactory {
+
+ /**
+ * Constructs a new key/value expirable null storage object for a given
+ * collection name.
+ *
+ * @param string $collection
+ * The name of the collection holding key and value pairs.
+ *
+ * @return \Drupal\Core\KeyValueStore\DatabaseStorageExpirable
+ * A key/value store implementation for the given $collection.
+ */
+ public function get($collection) {
+ return new NullStorageExpirable($collection);
+ }
+}
diff --git a/core/lib/Drupal/Core/KeyValueStore/NullStorageExpirable.php b/core/lib/Drupal/Core/KeyValueStore/NullStorageExpirable.php
new file mode 100644
index 0000000..d66ab59
--- /dev/null
+++ b/core/lib/Drupal/Core/KeyValueStore/NullStorageExpirable.php
@@ -0,0 +1,109 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\KeyValueStore\NullStorageExpirable.
+ */
+
+namespace Drupal\Core\KeyValueStore;
+
+/**
+ * Defines a null key/value store implementation.
+ */
+class NullStorageExpirable implements KeyValueStoreExpirableInterface {
+
+ /**
+ * The actual storage of key-value pairs.
+ *
+ * @var array
+ */
+ protected $data = array();
+
+ /**
+ * The name of the collection holding key and value pairs.
+ *
+ * @var string
+ */
+ protected $collection;
+
+ /**
+ * Creates a new expirable null key/value store.
+ */
+ public function __construct($collection) {
+ $this->collection = $collection;
+ }
+
+ /**
+ * Implements Drupal\Core\KeyValueStore\KeyValueStoreInterface::get().
+ */
+ public function get($key) {
+ return NULL;
+ }
+
+ /**
+ * Implements Drupal\Core\KeyValueStore\KeyValueStoreInterface::getMultiple().
+ */
+ public function getMultiple(array $keys) {
+ return array();
+ }
+
+ /**
+ * Implements Drupal\Core\KeyValueStore\KeyValueStoreInterface::getAll().
+ */
+ public function getAll() {
+ return array();
+ }
+
+ /**
+ * Implements Drupal\Core\KeyValueStore\KeyValueStoreInterface::set().
+ */
+ public function set($key, $value) { }
+
+ /**
+ * Implements Drupal\Core\KeyValueStore\KeyValueStoreInterface::setIfNotExists().
+ */
+ public function setIfNotExists($key, $value) { }
+
+ /**
+ * Implements Drupal\Core\KeyValueStore\KeyValueStoreInterface::setMultiple().
+ */
+ public function setMultiple(array $data) { }
+
+ /**
+ * Implements Drupal\Core\KeyValueStore\KeyValueStoreInterface::delete().
+ */
+ public function delete($key) { }
+
+ /**
+ * Implements Drupal\Core\KeyValueStore\KeyValueStoreInterface::deleteMultiple().
+ */
+ public function deleteMultiple(array $keys) { }
+
+ /**
+ * Implements Drupal\Core\KeyValueStore\KeyValueStoreInterface::deleteAll().
+ */
+ public function deleteAll() { }
+
+ /**
+ * Implements Drupal\Core\KeyValueStore\KeyValueStoreInterface::getCollectionName().
+ */
+ public function getCollectionName() {
+ return $this->collection;
+ }
+
+ /**
+ * Implements Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface::setMultipleWithExpire().
+ */
+ public function setMultipleWithExpire(array $data, $expire) { }
+
+ /**
+ * Implements Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface::setWithExpire().
+ */
+ public function setWithExpire($key, $value, $expire) { }
+
+ /**
+ * Implements Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface::setWithExpireIfNotExists().
+ */
+ public function setWithExpireIfNotExists($key, $value, $expire) { }
+
+}
diff --git a/core/modules/system/lib/Drupal/system/Tests/Cache/ClearTest.php b/core/modules/system/lib/Drupal/system/Tests/Cache/ClearTest.php
index 3e45fa0..ec1107c 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Cache/ClearTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Cache/ClearTest.php
@@ -35,8 +35,6 @@ class ClearTest extends CacheTestBase {
function testFlushAllCaches() {
// Create cache entries for each flushed cache bin.
$bins = Cache::getBins();
- // @todo remove after http://drupal.org/node/512026
- unset($bins['form']);
$this->assertTrue($bins, 'cache_get_bins() returned bins to flush.');
$bins['menu'] = $this->container->get('cache.menu');
foreach ($bins as $bin => $cache_backend) {
diff --git a/core/modules/system/lib/Drupal/system/Tests/Form/FormCacheTest.php b/core/modules/system/lib/Drupal/system/Tests/Form/FormCacheTest.php
new file mode 100644
index 0000000..1a851c9
--- /dev/null
+++ b/core/modules/system/lib/Drupal/system/Tests/Form/FormCacheTest.php
@@ -0,0 +1,89 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\system\Tests\Form\FormCacheTest.
+ */
+
+namespace Drupal\system\Tests\Form;
+
+use Drupal\simpletest\DrupalUnitTestBase;
+
+/**
+ * Tests form caching.
+ */
+class FormCacheTest extends DrupalUnitTestBase {
+
+ /**
+ * Modules to enable.
+ *
+ * @var array
+ */
+ public static $modules = array('system', 'user');
+
+ public static function getInfo() {
+ return array(
+ 'name' => 'Form cache tests',
+ 'description' => 'Tests form_set_cache() and form_get_cache()',
+ 'group' => 'Form API',
+ );
+ }
+
+ public function setUp() {
+ parent::setUp();
+ $this->installSchema('system', array('key_value_expire'));
+
+ $this->form_build_id = $this->randomName();
+ $this->form = array(
+ '#property' => $this->randomName(),
+ );
+ $this->form_state = form_state_defaults();
+ $this->form_state['example'] = $this->randomName();
+ }
+
+ /**
+ * Tests the form cache with a logged-in user.
+ */
+ function testCacheToken() {
+ $GLOBALS['user']->uid = 1;
+ form_set_cache($this->form_build_id, $this->form, $this->form_state);
+
+ $cached_form_state = form_state_defaults();
+ $cached_form = form_get_cache($this->form_build_id, $cached_form_state);
+ $this->assertEqual($this->form['#property'], $cached_form['#property']);
+ $this->assertTrue(!empty($cached_form['#cache_token']), 'Form has a cache token');
+ $this->assertEqual($this->form_state['example'], $cached_form_state['example']);
+
+ // Test that the form cache isn't loaded when the session/token has changed.
+ // Change the private key. (We cannot change the session ID because this
+ // will break the parent site test runner batch.)
+ state()->set('system.private_key', 'invalid');
+ $cached_form_state = form_state_defaults();
+ $cached_form = form_get_cache($this->form_build_id, $cached_form_state);
+ $this->assertFalse($cached_form, 'No form returned from cache');
+ $this->assertTrue(empty($cached_form_state['example']));
+
+ // Test that loading the cache with a different form_id fails.
+ $wrong_form_build_id = $this->randomName(9);
+ $cached_form_state = form_state_defaults();
+ $this->assertFalse(form_get_cache($wrong_form_build_id, $cached_form_state), 'No form returned from cache');
+ $this->assertTrue(empty($cached_form_state['example']), 'Cached form state was not loaded');
+ }
+
+ /**
+ * Tests the form cache without a logged-in user.
+ */
+ function testNoCacheToken() {
+ $GLOBALS['user']->uid = 0;
+
+ $this->form_state['example'] = $this->randomName();
+ form_set_cache($this->form_build_id, $this->form, $this->form_state);
+
+ $cached_form_state = form_state_defaults();
+ $cached_form = form_get_cache($this->form_build_id, $cached_form_state);
+ $this->assertEqual($this->form['#property'], $cached_form['#property']);
+ $this->assertTrue(empty($cached_form['#cache_token']), 'Form has no cache token');
+ $this->assertEqual($this->form_state['example'], $cached_form_state['example']);
+ }
+
+}
diff --git a/core/modules/system/system.install b/core/modules/system/system.install
index eeb8616..1ae2ad7 100644
--- a/core/modules/system/system.install
+++ b/core/modules/system/system.install
@@ -684,8 +684,6 @@ function system_schema() {
$schema['cache_bootstrap']['description'] = 'Cache table for data required to bootstrap Drupal, may be routed to a shared memory cache.';
$schema['cache_config'] = $schema['cache'];
$schema['cache_config']['description'] = 'Cache table for configuration data.';
- $schema['cache_form'] = $schema['cache'];
- $schema['cache_form']['description'] = 'Cache table for the form system to store recently built forms and their storage data, to be used in subsequent page requests.';
$schema['cache_page'] = $schema['cache'];
$schema['cache_page']['description'] = 'Cache table used to store compressed pages for anonymous users, if page caching is enabled.';
$schema['cache_menu'] = $schema['cache'];
@@ -2172,6 +2170,13 @@ function system_update_8052() {
}
/**
+ * Remove {cache_form} table.
+ */
+function system_update_8052() {
+ db_drop_table('cache_form');
+}
+
+/**
* @} End of "defgroup updates-7.x-to-8.x".
* The next series of updates should start at 9000.
*/
diff --git a/core/modules/views/lib/Drupal/views/Tests/Handler/FilterEqualityTest.php b/core/modules/views/lib/Drupal/views/Tests/Handler/FilterEqualityTest.php
index f0f4814..1b398e9 100644
--- a/core/modules/views/lib/Drupal/views/Tests/Handler/FilterEqualityTest.php
+++ b/core/modules/views/lib/Drupal/views/Tests/Handler/FilterEqualityTest.php
@@ -38,7 +38,7 @@ class FilterEqualityTest extends ViewUnitTestBase {
protected function setUp() {
parent::setUp();
- $this->installSchema('system', array('menu_router', 'variable'));
+ $this->installSchema('system', array('menu_router', 'variable', 'key_value_expire'));
}
function viewsData() {
diff --git a/core/modules/views/lib/Drupal/views/Tests/Handler/FilterInOperatorTest.php b/core/modules/views/lib/Drupal/views/Tests/Handler/FilterInOperatorTest.php
index fb154c1..0c1f32a 100644
--- a/core/modules/views/lib/Drupal/views/Tests/Handler/FilterInOperatorTest.php
+++ b/core/modules/views/lib/Drupal/views/Tests/Handler/FilterInOperatorTest.php
@@ -39,7 +39,7 @@ class FilterInOperatorTest extends ViewUnitTestBase {
protected function setUp() {
parent::setUp();
- $this->installSchema('system', array('menu_router', 'variable'));
+ $this->installSchema('system', array('menu_router', 'variable', 'key_value_expire'));
}
function viewsData() {
diff --git a/core/modules/views/lib/Drupal/views/Tests/Handler/FilterNumericTest.php b/core/modules/views/lib/Drupal/views/Tests/Handler/FilterNumericTest.php
index e12c94a..a82d23f 100644
--- a/core/modules/views/lib/Drupal/views/Tests/Handler/FilterNumericTest.php
+++ b/core/modules/views/lib/Drupal/views/Tests/Handler/FilterNumericTest.php
@@ -39,7 +39,7 @@ class FilterNumericTest extends ViewUnitTestBase {
protected function setUp() {
parent::setUp();
- $this->installSchema('system', array('menu_router', 'variable'));
+ $this->installSchema('system', array('menu_router', 'variable', 'key_value_expire'));
}
function viewsData() {
diff --git a/core/modules/views/lib/Drupal/views/Tests/Handler/FilterStringTest.php b/core/modules/views/lib/Drupal/views/Tests/Handler/FilterStringTest.php
index 57489bb..a573108 100644
--- a/core/modules/views/lib/Drupal/views/Tests/Handler/FilterStringTest.php
+++ b/core/modules/views/lib/Drupal/views/Tests/Handler/FilterStringTest.php
@@ -38,7 +38,7 @@ class FilterStringTest extends ViewUnitTestBase {
protected function setUp() {
parent::setUp();
- $this->installSchema('system', array('menu_router', 'variable'));
+ $this->installSchema('system', array('menu_router', 'variable', 'key_value_expire'));
}
function viewsData() {