function captcha_process in CAPTCHA 6.2
Process callback for CAPTCHA form element.
1 string reference to 'captcha_process'
- captcha_elements in ./
captcha.module - Implementation of hook_elements().
File
- ./
captcha.module, line 173 - This module enables basic CAPTCHA functionality: administrators can add a CAPTCHA to desired forms that users without the 'skip CAPTCHA' permission (typically anonymous visitors) have to solve.
Code
function captcha_process($element, $edit, &$form_state, $complete_form) {
module_load_include('inc', 'captcha');
// Add Javascript for general CAPTCHA functionality.
drupal_add_js(drupal_get_path('module', 'captcha') . '/captcha.js');
// Prevent caching of the page with CAPTCHA elements.
// This needs to be done even if the CAPTCHA will be ommitted later:
// other untrusted users should not get a cached page when
// the current untrusted user can skip the current CAPTCHA.
global $conf;
$conf['cache'] = FALSE;
// Get the form ID of the form we are currently processing (which is not
// necessary the same form that is submitted (if any).
$this_form_id = $complete_form['form_id']['#value'];
// Get the CAPTCHA session ID.
// If there is a submitted form: try to retrieve and reuse the
// CAPTCHA session ID from the posted data.
list($posted_form_id, $posted_captcha_sid) = _captcha_get_posted_captcha_info($element, $form_state, $this_form_id);
if ($this_form_id == $posted_form_id && isset($posted_captcha_sid)) {
$captcha_sid = $posted_captcha_sid;
}
else {
// Generate a new CAPTCHA session if we could not reuse one from a posted form.
$captcha_sid = _captcha_generate_captcha_session($this_form_id, CAPTCHA_STATUS_UNSOLVED);
}
// Store CAPTCHA session ID as hidden field.
// Strictly speaking, it is not necessary to send the CAPTCHA session id
// with the form, as the one time CAPTCHA token (see lower) is enough.
// However, we still send it along, because it can help debugging
// problems on live sites with only access to the markup.
$element['captcha_sid'] = array(
'#type' => 'hidden',
'#value' => $captcha_sid,
);
// Get the token for a captcha_sid
$captcha_token = db_result(db_query("SELECT token FROM {captcha_sessions} WHERE csid = %d", $captcha_sid));
// Generate a new token if the token could not be retrieved (but not if the form has been submitted, because otherwise the session could be reused.)
if (!isset($captcha_token) && !$form_state['submitted']) {
// Additional one time CAPTCHA token: store in database and send with form.
$captcha_token = md5(mt_rand());
db_query("UPDATE {captcha_sessions} SET token='%s' WHERE csid=%d", $captcha_token, $captcha_sid);
}
$element['captcha_token'] = array(
'#type' => 'hidden',
'#value' => $captcha_token,
);
// Get implementing module and challenge for CAPTCHA.
list($captcha_type_module, $captcha_type_challenge) = _captcha_parse_captcha_type($element['#captcha_type']);
// Store CAPTCHA information for further processing in
// - $form_state['captcha_info'], which survives a form rebuild (e.g. node
// preview), useful in _captcha_get_posted_captcha_info().
// - $element['#captcha_info'], for post processing functions that do not
// receive a $form_state argument (e.g. the pre_render callback).
$form_state['captcha_info'] = array(
'this_form_id' => $this_form_id,
'posted_form_id' => $posted_form_id,
'captcha_sid' => $captcha_sid,
'module' => $captcha_type_module,
'captcha_type' => $captcha_type_challenge,
);
$element['#captcha_info'] = array(
'form_id' => $this_form_id,
'captcha_sid' => $captcha_sid,
);
if (_captcha_required_for_user($captcha_sid, $this_form_id) || $element['#captcha_admin_mode']) {
// Generate a CAPTCHA and its solution
// (note that the CAPTCHA session ID is given as third argument).
$captcha = module_invoke($captcha_type_module, 'captcha', 'generate', $captcha_type_challenge, $captcha_sid);
if (!isset($captcha['form']) || !isset($captcha['solution'])) {
// The selected module did not return what we expected: log about it and quit.
watchdog('CAPTCHA', 'CAPTCHA problem: unexpected result from hook_captcha() of module %module when trying to retrieve challenge type %type for form %form_id.', array(
'%type' => $captcha_type_challenge,
'%module' => $captcha_type_module,
'%form_id' => $this_form_id,
), WATCHDOG_ERROR);
return $element;
}
// Add form elements from challenge as children to CAPTCHA form element.
$element['captcha_widgets'] = $captcha['form'];
// Add a validation callback for the CAPTCHA form element (when not in admin mode).
if (!$element['#captcha_admin_mode']) {
$element['#element_validate'] = array(
'captcha_validate',
);
}
// Set a custom CAPTCHA validate function if requested.
if (isset($captcha['captcha_validate'])) {
$element['#captcha_validate'] = $captcha['captcha_validate'];
}
// Add pre_render callback for additional CAPTCHA processing.
$element['#pre_render'] = array(
'captcha_pre_render_process',
);
// Store the solution in the #captcha_info array.
$element['#captcha_info']['solution'] = $captcha['solution'];
// Make sure we can use a top level form value $form_state['values']['captcha_response'], even if the form has #tree=true.
$element['#tree'] = FALSE;
}
return $element;
}