diff --git a/includes/form.inc b/includes/form.inc index 99570a5..6fc277e 100644 --- a/includes/form.inc +++ b/includes/form.inc @@ -501,22 +501,44 @@ function form_get_cache($form_build_id, &$form_state) { /** * Store a form in the cache. + * + * Besides a numeric value the expiration option accepts relative date formats + * like for php's strtotime, too. + * Using relative date formats enables you to set the cache expiration to a time + * independent from the time the cache is build. + * E.g. if you use 'tomorrow' as expiration time, the cache will expire next + * midnight independent if the cache was built 10am or 11:55pm. + * + * @see http://www.php.net/manual/en/datetime.formats.relative.php + * */ function form_set_cache($form_build_id, $form, $form_state) { - // 6 hours cache life time for forms should be plenty. - $expire = 21600; + // Evaluate the cache lifetime. + if (!empty($form_state['cache_expire'])) { + $expire = $form_state['cache_expire']; + } + else { + $expire = variable_get('form_cache_expire', 21600); + } + // Allow relative date formats. + if (!is_numeric($expire)) { + $expire = strtotime($expire); + } + else { + $expire = REQUEST_TIME + $expire; + } // Cache form structure. if (isset($form)) { if ($GLOBALS['user']->uid) { $form['#cache_token'] = drupal_get_token(); } - cache_set('form_' . $form_build_id, $form, 'cache_form', REQUEST_TIME + $expire); + cache_set('form_' . $form_build_id, $form, 'cache_form', $expire); } // Cache form state. if ($data = array_diff_key($form_state, array_flip(form_state_keys_no_cache()))) { - cache_set('form_state_' . $form_build_id, $data, 'cache_form', REQUEST_TIME + $expire); + cache_set('form_state_' . $form_build_id, $data, 'cache_form', $expire); } } diff --git a/modules/system/system.admin.inc b/modules/system/system.admin.inc index 0d3a8d7..1675ad9 100644 --- a/modules/system/system.admin.inc +++ b/modules/system/system.admin.inc @@ -1673,6 +1673,33 @@ function system_performance_settings() { '#description' => t('The maximum time an external cache can use an old version of a page.') ); + $form_cache_expire = variable_get('form_cache_expire', 21600); + $form['caching']['form_cache_expire'] = array( + '#type' => 'select', + '#title' => t('Expiration of cached forms'), + '#default_value' => $form_cache_expire, + '#options' => array('custom' => '<' . t('custom') . '>') + $period, + '#description' => t('The maximum time form and form_state are cached.') + ); + $form_cache_expire_custom = (is_numeric($form_cache_expire)) ? REQUEST_TIME + $form_cache_expire : strtotime($form_cache_expire); + $form['caching']['form_cache_expire_custom'] = array( + '#type' => 'textfield', + '#title' => t('Custom form cache expiration'), + '#default_value' => $form_cache_expire, + '#field_suffix' => t( + '%expire evaluates to %expiration_date', + array( + '%expire' => $form_cache_expire, + '%expiration_date' => date('Y/m/d - H:i:s', $form_cache_expire_custom), + ) + ), + '#description' => t('Define a relative date format like for php\'s strtotime.'), + '#states' => array( + 'visible' => array(':input[name="form_cache_expire"]' => array('value' => 'custom')), + ), + '#element_validate' => array('_system_performance_settings_validate_form_caching'), + ); + $directory = 'public://'; $is_writable = is_dir($directory) && is_writable($directory); $disabled = !$is_writable; @@ -1718,6 +1745,29 @@ function system_performance_settings() { } /** + * Validates the custom form expiration and stores it back into the used + * variable name + */ +function _system_performance_settings_validate_form_caching($element, &$form_state) { + if (!empty($element['#value']) && $form_state['values']['form_cache_expire'] == 'custom') { + $expire = $element['#value']; + if (!is_numeric($expire)) { + $expire = (int) strtotime($element['#value']); + } + else { + $expire += REQUEST_TIME; + } + if ($expire < REQUEST_TIME) { + form_error($element, t('The value of the custom form expiration evaluates to a time in the past. Please check the value.')); + } + else { + $form_state['values']['form_cache_expire'] = $element['#value']; + } + } + unset($form_state['values']['form_cache_expire_custom']); +} + +/** * Submit callback; clear system caches. * * @ingroup forms