Regrettably, my machine didn't cooperate when I tried to record this presentation. I don't think the slides will do you much good without the stuff I said, but a few people asked for them.
---
Depending on who you ask, Drupal is either a framework or a platform, but no matter how you look at it, there are things about it that suck. Hear Brock Boland talk about the pain points of coding for Drupal 6, how things have improved in Drupal 7, and what's expected to be better in Drupal 8.
18. DIY
function ahah_callback_method() {
// AHAH processing prep
$form_state = array('storage' => NULL, 'submitted' => FALSE);
$form_build_id = $_POST['form_build_id'];
$form = form_get_cache($form_build_id, $form_state);
$args = $form['#parameters'];
$form_id = array_shift($args);
$form_state['post'] = $form['#post'] = $_POST;
$form['#programmed'] = $form['#redirect'] = FALSE;
drupal_process_form($form_id, $form, $form_state);
$form = drupal_rebuild_form($form_id, $form_state, $args,
$form_build_id);
// Now you can do stuff
}
Thursday, November 10, 11
19. ahah_helper module
/**
// $form_state['submit_handlers'] and $form_state['validate_handlers'].
* Given a POST of a Drupal form (with both a form_build_id set), this
// This problem does not exist when AHAH is disabled, because then the
* function rebuilds the form and then only renders the given form item. If no
// assumption is true, and then you generally provide a button as an
* form item is given, the entire form is rendered.
// alternative to the AHAH behavior.
*
$form_state['submitted'] = TRUE;
* Is used directly in a menu callback in ahah_helper's sole menu item. Can
// Continued from the above: when an AHAH update of the form is triggered
* also be used in more advanced menu callbacks, for example to render
// without using a button, you generally don't want any validation to kick
* multiple form items of the same form and return them separately.
// in. A typical example is adding new fields, possibly even required ones.
*
// You don't want errors to be thrown at the user until they actually submit
* @param $parents
// their values. (Well, actually you want to be smart about this: sometimes
*/
// you do want instant validation, but that's an even bigger pain to solve
function ahah_helper_render($form_item_to_render = FALSE) {
// here so I'll leave that for later…)
$form_state = array('storage' => NULL, 'submitted' => FALSE);
if (!isset($_POST['op'])) {
$form_build_id = $_POST['form_build_id'];
// For the default "{$form_id}_validate" and "{$form_id}_submit" handlers.
$form['#validate'] = NULL;
// Get the form from the cache.
$form['#submit'] = NULL;
$form = form_get_cache($form_build_id, $form_state);
// For customly set #validate and #submit handlers.
$args = $form['#parameters'];
$form_state['submit_handlers'] = NULL;
$form_id = array_shift($args);
$form_state['validate_handlers'] = NULL;
// Disable #required and #element_validate validation.
// Are we on the node form?
_ahah_helper_disable_validation($form);
$node_form = FALSE;
}
if (preg_match('/_node_form$/', $form_id)) {
$node_form = TRUE;
// Build, validate and if possible, submit the form.
module_load_include('inc', 'node', 'node.pages');
drupal_process_form($form_id, $form, $form_state);
}
if ($node_form) {
// get the node from the submitted values
// We will run some of the submit handlers so we need to disable redirecting.
$node = node_form_submit_build_node($form, $form_state);
$form['#redirect'] = FALSE;
// We need to process the form, prepare for that by setting a few internals
// hack to stop taxonomy from resetting when the form is rebuilt
// variables.
$form_state['node']['taxonomy'] = taxonomy_preview_terms($node);
$form['#post'] = $_POST;
}
$form['#programmed'] = FALSE;
$form_state['post'] = $_POST;
// This call recreates the form relying solely on the form_state that the
// drupal_process_form set up.
// $form_state['storage']['#ahah_helper']['file'] has been set, to know
//$form = drupal_rebuild_form($form_id, $form_state, $args, $form_build_id);
// which file should be loaded. This is necessary because we'll use the form
$form = drupal_rebuild_form($form_id, $form_state, $args, $form_build_id);
// definition itself rather than the cached $form.
if (isset($form_state['storage']['#ahah_helper']['file'])) {
// Get the form item we want to render.
require_once($form_state['storage']['#ahah_helper']['file']);
$form_item = _ahah_helper_get_form_item($form, $form_item_to_render);
}
// Get the JS settings so we can merge them.
// If the form is being rebuilt due to something else than a pressed button,
$javascript = drupal_add_js(NULL, NULL, 'header');
// e.g. a select that was changed, then $_POST['op'] will be empty. As a
$settings = call_user_func_array('array_merge_recursive',
// result, Forms API won't be able to detect any pressed buttons. Eventually
$javascript['setting']);
// it will call _form_builder_ie_cleanup(), which will automatically, yet
// inappropriately assign the first in the form as the clicked button. The
drupal_json(array(
// reasoning is that since the form has been submitted, a button surely must
'status' => TRUE,
// have been clicked. This is of course an invalid reasoning in the context
'data' => theme('status_messages') . drupal_render($form_item),
// of AHAH forms.
'settings' => array('ahah' => $settings['ahah']),
// To work around this, we *always* set $form_state['submitted'] to true,
));
// this will prevent _form_builder_ie_cleanup() from assigning a wrong
}
// button. When a button is pressed (thus $_POST['op'] is set), then this
// button will still set $form_state['submitted'],
Thursday, November 10, 11