Commit 59b7e23b authored by webchick's avatar webchick

#367567 by sun, effulgentsia, yched, and quicksketch: Use AJAX framework for 'Add more' links.

parent 5d001d94
...@@ -216,7 +216,6 @@ function ajax_get_form() { ...@@ -216,7 +216,6 @@ function ajax_get_form() {
// The form needs to be processed; prepare for that by setting a few internal // The form needs to be processed; prepare for that by setting a few internal
// variables. // variables.
$form_state['input'] = $_POST; $form_state['input'] = $_POST;
$form_state['args'] = $form['#args'];
$form_id = $form['#form_id']; $form_id = $form['#form_id'];
return array($form, $form_state, $form_id, $form_build_id); return array($form, $form_state, $form_id, $form_build_id);
......
...@@ -72,7 +72,7 @@ function drupal_get_form($form_id) { ...@@ -72,7 +72,7 @@ function drupal_get_form($form_id) {
$args = func_get_args(); $args = func_get_args();
// Remove $form_id from the arguments. // Remove $form_id from the arguments.
array_shift($args); array_shift($args);
$form_state['args'] = $args; $form_state['build_info']['args'] = $args;
return drupal_build_form($form_id, $form_state); return drupal_build_form($form_id, $form_state);
} }
...@@ -93,11 +93,17 @@ function drupal_get_form($form_id) { ...@@ -93,11 +93,17 @@ function drupal_get_form($form_id) {
* search_forms(), and user_forms(). * search_forms(), and user_forms().
* @param &$form_state * @param &$form_state
* An array which stores information about the form. This is passed as a * An array which stores information about the form. This is passed as a
* reference so that the caller can use it to examine what the form changed * reference so that the caller can use it to examine what in the form changed
* when the form submission process is complete. * when the form submission process is complete.
* The following parameters may be set in $form_state to affect how the form * The following parameters may be set in $form_state to affect how the form
* is rendered: * is rendered:
* - args: An array of arguments to pass to the form builder. * - build_info: A keyed array of build information that is necessary to
* rebuild the form from cache when the original context may no longer be
* available:
* - args: An array of arguments to pass to the form builder.
* - file: An optional include file that contains the form and is
* automatically loaded by form_get_cache(). Defaults to the current menu
* router item's 'file' definition, if existent.
* - input: An array of input that corresponds to $_POST or $_GET, depending * - input: An array of input that corresponds to $_POST or $_GET, depending
* on the 'method' chosen (see below). * on the 'method' chosen (see below).
* - method: The HTTP form method to use for finding the input for this form. * - method: The HTTP form method to use for finding the input for this form.
...@@ -161,23 +167,22 @@ function drupal_build_form($form_id, &$form_state) { ...@@ -161,23 +167,22 @@ function drupal_build_form($form_id, &$form_state) {
// object, we're hitting the form for the first time and we need // object, we're hitting the form for the first time and we need
// to build it from scratch. // to build it from scratch.
if (!isset($form)) { if (!isset($form)) {
$form = drupal_retrieve_form($form_id, $form_state);
$form_build_id = 'form-' . md5(uniqid(mt_rand(), TRUE));
$form['#build_id'] = $form_build_id;
// Record the filepath of the include file containing the original form, // Record the filepath of the include file containing the original form,
// so the form builder callbacks can be loaded when the form is being // so the form builder callbacks can be loaded when the form is being
// rebuilt on a different path (such as 'system/ajax'). // rebuilt from cache on a different path (such as 'system/ajax').
// @see form_get_cache() // @see form_get_cache()
// @see drupal_retrieve_form()
// menu_get_item() is not available at installation time. // menu_get_item() is not available at installation time.
if (!defined('MAINTENANCE_MODE')) { if (!isset($form_state['build_info']['file']) && !defined('MAINTENANCE_MODE')) {
$item = menu_get_item(); $item = menu_get_item();
if (!empty($item['file'])) { if (!empty($item['file'])) {
$form['#include_file'] = $item['file']; $form_state['build_info']['file'] = $item['file'];
} }
} }
$form = drupal_retrieve_form($form_id, $form_state);
$form_build_id = 'form-' . md5(uniqid(mt_rand(), TRUE));
$form['#build_id'] = $form_build_id;
// Fix the form method, if it is 'get' in $form_state, but not in $form. // Fix the form method, if it is 'get' in $form_state, but not in $form.
if ($form_state['method'] == 'get' && !isset($form['#method'])) { if ($form_state['method'] == 'get' && !isset($form['#method'])) {
$form['#method'] = 'get'; $form['#method'] = 'get';
...@@ -217,7 +222,6 @@ function drupal_build_form($form_id, &$form_state) { ...@@ -217,7 +222,6 @@ function drupal_build_form($form_id, &$form_state) {
// complete. We need to construct a fresh copy of the form, passing // complete. We need to construct a fresh copy of the form, passing
// in the latest $form_state in addition to any other variables passed // in the latest $form_state in addition to any other variables passed
// into drupal_get_form(). // into drupal_get_form().
if ((!empty($form_state['storage']) || $form_state['rebuild']) && $form_state['submitted'] && !form_get_errors()) { if ((!empty($form_state['storage']) || $form_state['rebuild']) && $form_state['submitted'] && !form_get_errors()) {
$form = drupal_rebuild_form($form_id, $form_state); $form = drupal_rebuild_form($form_id, $form_state);
} }
...@@ -242,6 +246,7 @@ function form_state_defaults() { ...@@ -242,6 +246,7 @@ function form_state_defaults() {
'args' => array(), 'args' => array(),
'rebuild' => FALSE, 'rebuild' => FALSE,
'redirect' => NULL, 'redirect' => NULL,
'build_info' => array(),
'storage' => NULL, 'storage' => NULL,
'submitted' => FALSE, 'submitted' => FALSE,
'programmed' => FALSE, 'programmed' => FALSE,
...@@ -265,9 +270,6 @@ function form_state_defaults() { ...@@ -265,9 +270,6 @@ function form_state_defaults() {
* $form_state['clicked_button']['#array_parents'] will help you to find which * $form_state['clicked_button']['#array_parents'] will help you to find which
* part. * part.
* *
* When getting a form from the cache, the $form_id must be shifted off from
* $form['#args'], so the resulting array can be given to $form_state['args'].
*
* @param $form_id * @param $form_id
* The unique string identifying the desired form. If a function * The unique string identifying the desired form. If a function
* with that name exists, it is called to build the form array. * with that name exists, it is called to build the form array.
...@@ -323,19 +325,19 @@ function drupal_rebuild_form($form_id, &$form_state, $form_build_id = NULL) { ...@@ -323,19 +325,19 @@ function drupal_rebuild_form($form_id, &$form_state, $form_build_id = NULL) {
function form_get_cache($form_build_id, &$form_state) { function form_get_cache($form_build_id, &$form_state) {
if ($cached = cache_get('form_' . $form_build_id, 'cache_form')) { if ($cached = cache_get('form_' . $form_build_id, 'cache_form')) {
$form = $cached->data; $form = $cached->data;
// If the original form is contained in an optional include file, load the
// file and re-populate $form_state for subsequent rebuilds.
// @see drupal_build_form()
// @see drupal_retrieve_form()
if (!empty($form['#include_file']) && file_exists($form['#include_file'])) {
require_once DRUPAL_ROOT . '/' . $form['#include_file'];
$form_state['include_file'] = $form['#include_file'];
}
global $user; global $user;
if ((isset($form['#cache_token']) && drupal_valid_token($form['#cache_token'])) || (!isset($form['#cache_token']) && !$user->uid)) { if ((isset($form['#cache_token']) && drupal_valid_token($form['#cache_token'])) || (!isset($form['#cache_token']) && !$user->uid)) {
if ($cached = cache_get('storage_' . $form_build_id, 'cache_form')) { if ($cached = cache_get('form_state_' . $form_build_id, 'cache_form')) {
$form_state['storage'] = $cached->data; // Re-populate $form_state for subsequent rebuilds.
$form_state['build_info'] = $cached->data['build_info'];
$form_state['storage'] = $cached->data['storage'];
// If the original form is contained in an include file, load the file.
// @see drupal_build_form()
if (!empty($form_state['build_info']['file']) && file_exists($form_state['build_info']['file'])) {
require_once DRUPAL_ROOT . '/' . $form_state['build_info']['file'];
}
} }
return $form; return $form;
} }
...@@ -343,7 +345,7 @@ function form_get_cache($form_build_id, &$form_state) { ...@@ -343,7 +345,7 @@ function form_get_cache($form_build_id, &$form_state) {
} }
/** /**
* Store a form in the cache * Store a form in the cache.
*/ */
function form_set_cache($form_build_id, $form, $form_state) { function form_set_cache($form_build_id, $form, $form_state) {
// 6 hours cache life time for forms should be plenty. // 6 hours cache life time for forms should be plenty.
...@@ -353,8 +355,12 @@ function form_set_cache($form_build_id, $form, $form_state) { ...@@ -353,8 +355,12 @@ function form_set_cache($form_build_id, $form, $form_state) {
$form['#cache_token'] = drupal_get_token(); $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', REQUEST_TIME + $expire);
if (!empty($form_state['storage'])) { if (!empty($form_state['build_info']) || !empty($form_state['storage'])) {
cache_set('storage_' . $form_build_id, $form_state['storage'], 'cache_form', REQUEST_TIME + $expire); $data = array(
'build_info' => $form_state['build_info'],
'storage' => $form_state['storage'],
);
cache_set('form_state_' . $form_build_id, $data, 'cache_form', REQUEST_TIME + $expire);
} }
} }
...@@ -403,11 +409,11 @@ function form_set_cache($form_build_id, $form, $form_state) { ...@@ -403,11 +409,11 @@ function form_set_cache($form_build_id, $form, $form_state) {
* @endcode * @endcode
*/ */
function drupal_form_submit($form_id, &$form_state) { function drupal_form_submit($form_id, &$form_state) {
if (!isset($form_state['args'])) { if (!isset($form_state['build_info']['args'])) {
$args = func_get_args(); $args = func_get_args();
array_shift($args); array_shift($args);
array_shift($args); array_shift($args);
$form_state['args'] = $args; $form_state['build_info']['args'] = $args;
} }
$form = drupal_retrieve_form($form_id, $form_state); $form = drupal_retrieve_form($form_id, $form_state);
...@@ -447,7 +453,7 @@ function drupal_retrieve_form($form_id, &$form_state) { ...@@ -447,7 +453,7 @@ function drupal_retrieve_form($form_id, &$form_state) {
// We save two copies of the incoming arguments: one for modules to use // We save two copies of the incoming arguments: one for modules to use
// when mapping form ids to constructor functions, and another to pass to // when mapping form ids to constructor functions, and another to pass to
// the constructor function itself. // the constructor function itself.
$args = $form_state['args']; $args = $form_state['build_info']['args'];
// We first check to see if there's a function named after the $form_id. // We first check to see if there's a function named after the $form_id.
// If there is, we simply pass the arguments on to it to get the form. // If there is, we simply pass the arguments on to it to get the form.
...@@ -495,15 +501,6 @@ function drupal_retrieve_form($form_id, &$form_state) { ...@@ -495,15 +501,6 @@ function drupal_retrieve_form($form_id, &$form_state) {
// Otherwise, call the function named after the form id. // Otherwise, call the function named after the form id.
$form = call_user_func_array(isset($callback) ? $callback : $form_id, $args); $form = call_user_func_array(isset($callback) ? $callback : $form_id, $args);
$form['#form_id'] = $form_id; $form['#form_id'] = $form_id;
$form['#args'] = $form_state['args'];
// Whenever this form is (re)built, restore the include file property from
// $form_state, if existent.
// @see drupal_build_form()
// @see form_get_cache()
if (!empty($form_state['include_file'])) {
$form['#include_file'] = $form_state['include_file'];
}
return $form; return $form;
} }
......
...@@ -394,7 +394,7 @@ function install_run_task($task, &$install_state) { ...@@ -394,7 +394,7 @@ function install_run_task($task, &$install_state) {
// We need to pass $install_state by reference in order for forms to // We need to pass $install_state by reference in order for forms to
// modify it, since the form API will use it in call_user_func_array(), // modify it, since the form API will use it in call_user_func_array(),
// which requires that referenced variables be passed explicitly. // which requires that referenced variables be passed explicitly.
'args' => array(&$install_state), 'build_info' => array('args' => array(&$install_state)),
'no_redirect' => TRUE, 'no_redirect' => TRUE,
); );
$form = drupal_build_form($function, $form_state); $form = drupal_build_form($function, $form_state);
......
...@@ -31,7 +31,7 @@ function color_theme() { ...@@ -31,7 +31,7 @@ function color_theme() {
* Implement hook_form_FORM_ID_alter(). * Implement hook_form_FORM_ID_alter().
*/ */
function color_form_system_theme_settings_alter(&$form, &$form_state) { function color_form_system_theme_settings_alter(&$form, &$form_state) {
if (isset($form_state['args'][0]) && ($theme = $form_state['args'][0]) && color_get_info($theme) && function_exists('gd_info')) { if (isset($form_state['build_info']['args'][0]) && ($theme = $form_state['build_info']['args'][0]) && color_get_info($theme) && function_exists('gd_info')) {
$form['color'] = array( $form['color'] = array(
'#type' => 'fieldset', '#type' => 'fieldset',
'#title' => t('Color scheme'), '#title' => t('Color scheme'),
......
...@@ -430,7 +430,7 @@ function openid_authentication($response) { ...@@ -430,7 +430,7 @@ function openid_authentication($response) {
} }
elseif (variable_get('user_register', 1)) { elseif (variable_get('user_register', 1)) {
// Register new user // Register new user
$form_state['args'] = array(); $form_state['build_info']['args'] = array();
$form_state['redirect'] = NULL; $form_state['redirect'] = NULL;
$form_state['values']['name'] = (empty($response['openid.sreg.nickname'])) ? $identity : $response['openid.sreg.nickname']; $form_state['values']['name'] = (empty($response['openid.sreg.nickname'])) ? $identity : $response['openid.sreg.nickname'];
$form_state['values']['mail'] = (empty($response['openid.sreg.email'])) ? '' : $response['openid.sreg.email']; $form_state['values']['mail'] = (empty($response['openid.sreg.email'])) ? '' : $response['openid.sreg.email'];
......
...@@ -104,12 +104,12 @@ function openid_user_delete_form($form, $form_state, $account, $aid = 0) { ...@@ -104,12 +104,12 @@ function openid_user_delete_form($form, $form_state, $account, $aid = 0) {
function openid_user_delete_form_submit($form, &$form_state) { function openid_user_delete_form_submit($form, &$form_state) {
$query = db_delete('authmap') $query = db_delete('authmap')
->condition('uid', $form_state['args'][0]->uid) ->condition('uid', $form_state['build_info']['args'][0]->uid)
->condition('aid', $form_state['args'][1]) ->condition('aid', $form_state['build_info']['args'][1])
->condition('module', 'openid') ->condition('module', 'openid')
->execute(); ->execute();
if ($query) { if ($query) {
drupal_set_message(t('OpenID deleted.')); drupal_set_message(t('OpenID deleted.'));
} }
$form_state['redirect'] = 'user/' . $form_state['args'][0]->uid . '/openid'; $form_state['redirect'] = 'user/' . $form_state['build_info']['args'][0]->uid . '/openid';
} }
...@@ -347,7 +347,7 @@ function form_storage_test_form_submit($form, &$form_state) { ...@@ -347,7 +347,7 @@ function form_storage_test_form_submit($form, &$form_state) {
*/ */
function form_test_wrapper_callback($form_id) { function form_test_wrapper_callback($form_id) {
$form_state = array( $form_state = array(
'args' => array(), 'build_info' => array('args' => array()),
'wrapper_callback' => 'form_test_wrapper_callback_wrapper', 'wrapper_callback' => 'form_test_wrapper_callback_wrapper',
); );
return drupal_build_form($form_id, $form_state); return drupal_build_form($form_id, $form_state);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment