diff --git a/includes/form.inc b/includes/form.inc index e749239ef9..3b2032eb72 100644 --- a/includes/form.inc +++ b/includes/form.inc @@ -555,8 +555,10 @@ function form_get_cache($form_build_id, &$form_state) { * Stores a form in the cache. */ function form_set_cache($form_build_id, $form, $form_state) { - // 6 hours cache life time for forms should be plenty. - $expire = 21600; + // The default cache_form expiration is 6 hours. On busy sites, the cache_form + // table can become very large. A shorter cache lifetime can help to keep the + // table's size under control. + $expire = variable_get('form_cache_expiration', 21600); // Ensure that the form build_id embedded in the form structure is the same as // the one passed in as a parameter. This is an additional safety measure to diff --git a/modules/simpletest/tests/form.test b/modules/simpletest/tests/form.test index a441ceeba4..e52c8c42e1 100644 --- a/modules/simpletest/tests/form.test +++ b/modules/simpletest/tests/form.test @@ -1421,6 +1421,59 @@ class FormsFormStoragePageCacheTestCase extends DrupalWebTestCase { } /** + * Test cache_form. + */ +class FormsFormCacheTestCase extends DrupalWebTestCase { + public static function getInfo() { + return array( + 'name' => 'Form caching', + 'description' => 'Tests storage and retrieval of forms from cache.', + 'group' => 'Form API', + ); + } + + function setUp() { + parent::setUp('form_test'); + } + + /** + * Tests storing and retrieving the form from cache. + */ + function testCacheForm() { + $form = drupal_get_form('form_test_cache_form'); + $form_state = array('foo' => 'bar', 'build_info' => array('baz')); + form_set_cache($form['#build_id'], $form, $form_state); + + $cached_form_state = array(); + $cached_form = form_get_cache($form['#build_id'], $cached_form_state); + + $this->assertEqual($cached_form['#build_id'], $form['#build_id'], 'Form retrieved from cache_form successfully.'); + $this->assertEqual($cached_form_state['foo'], 'bar', 'Data retrieved from cache_form successfully.'); + } + + /** + * Tests changing form_cache_expiration. + */ + function testCacheFormCustomExpiration() { + variable_set('form_cache_expiration', -1 * (24 * 60 * 60)); + + $form = drupal_get_form('form_test_cache_form'); + $form_state = array('foo' => 'bar', 'build_info' => array('baz')); + form_set_cache($form['#build_id'], $form, $form_state); + + // Clear expired entries from cache_form, which should include the entry we + // just stored. Without this, the form will still be retrieved from cache. + cache_clear_all(NULL, 'cache_form'); + + $cached_form_state = array(); + $cached_form = form_get_cache($form['#build_id'], $cached_form_state); + + $this->assertNull($cached_form, 'Expired form was not returned from cache.'); + $this->assertTrue(empty($cached_form_state), 'No data retrieved from cache for expired form.'); + } +} + +/** * Test wrapper form callbacks. */ class FormsFormWrapperTestCase extends DrupalWebTestCase { diff --git a/modules/simpletest/tests/form_test.module b/modules/simpletest/tests/form_test.module index 097e58841d..9f071826e5 100644 --- a/modules/simpletest/tests/form_test.module +++ b/modules/simpletest/tests/form_test.module @@ -919,6 +919,24 @@ function form_test_storage_page_cache_rebuild($form, &$form_state) { } /** + * A simple form for testing form caching. + */ +function form_test_cache_form($form, &$form_state) { + $form['title'] = array( + '#type' => 'textfield', + '#title' => 'Title', + '#required' => TRUE, + ); + + $form['submit'] = array( + '#type' => 'submit', + '#value' => 'Save', + ); + + return $form; +} + +/** * A form for testing form labels and required marks. */ function form_label_test_form() { diff --git a/sites/default/default.settings.php b/sites/default/default.settings.php index b044be3bc6..a152b287e9 100644 --- a/sites/default/default.settings.php +++ b/sites/default/default.settings.php @@ -479,6 +479,23 @@ ini_set('session.cookie_lifetime', 2000000); # $conf['block_cache_bypass_node_grants'] = TRUE; /** + * Expiration of cache_form entries: + * + * Drupal's Form API stores details of forms in cache_form and these entries are + * kept for at least 6 hours by default. Expired entries are cleared by cron. + * Busy sites can encounter problems with the cache_form table becoming very + * large. It's possible to mitigate this by setting a shorter expiration for + * cached forms. In some cases it may be desirable to set a longer cache + * expiration, for example to prolong cache_form entries for Ajax forms in + * cached HTML. + * + * @see form_set_cache() + * @see system_cron() + * @see ajax_get_form() + */ +# $conf['form_cache_expiration'] = 21600; + +/** * String overrides: * * To override specific strings on your site with or without enabling the Locale