function botcha_form_alter_botcha in BOTCHA Spam Prevention 6
Same name and namespace in other branches
- 7 botcha.botcha.inc \botcha_form_alter_botcha()
Main BOTCHA worker - process the form and apply BOTCHA protection
1 call to botcha_form_alter_botcha()
- botcha_form_alter in ./
botcha.module - Implementation of hook_form_alter().
File
- ./
botcha.botcha.inc, line 550 - Implementation of botcha form logic.
Code
function botcha_form_alter_botcha(&$form, &$form_state, $form_id, $botcha) {
// When we are altering a form, there are one or two build IDs.
// $form['#build_id'] is for the new form (always present)
// $_POST['form_build_id'] is for previous form submission (only if the form is being submitted)
// Herein lies the problem - we need to build new form based on form's build_id to present
// to the user, but check the BOTCHA fields in previous form submission based on post's build_id.
$build_id = $form['#build_id'];
$build_id_subm = isset($_POST['form_build_id']) ? $_POST['form_build_id'] : FALSE;
$form_state['botcha_submit_values'] = array();
if ($build_id_subm) {
// Generate Secret for submitted build id
$secret = md5($build_id_subm . BOTCHA_SECRET);
$recipes = _botcha_recipes($form, $botcha, $secret);
// Save submitted values in our stash for later use in _validate, as we have to reset them here at _form_alter stage.
// It won't be possible to reset after validation as there is no reliable mechanism in Form API,
// i.e. form_set_value() does not change rendered form and form errors disable whole 'rebuild' business.
foreach ($recipes as $recipe) {
if (isset($recipe->form_elements)) {
foreach ($recipe->form_elements as $field => $value) {
if (isset($_POST[$field])) {
$form_state['botcha_submit_values'][$field] = $_POST[$field];
}
}
}
}
// Save recipes for later use in _validate
$form_state['#botcha_recipes_subm'] = $recipes;
}
// Generate Secret for this build id
$secret = md5($build_id . BOTCHA_SECRET);
$recipes = _botcha_recipes($form, $botcha, $secret);
// Save recipes for later use in _validate
$form_state['#botcha_recipes'] = $recipes;
// Common javascript?
// drupal_add_js(drupal_get_path('module', 'botcha') . '/botcha.js');
$added_botchas = array();
$jss = array();
$csss = array();
foreach ($recipes as $recipe) {
if (isset($recipe->form_elements)) {
foreach ($recipe->form_elements as $field => $value) {
unset($value['!valid_token']);
$form[$field] = $value;
if ($build_id_subm && isset($value['#default_value'])) {
// Reset our controls to defaults here (as explained above).
$form[$field]['#value'] = $value['#default_value'];
$form_state['post'][$field] = $value['#default_value'];
$_POST[$field] = $value['#default_value'];
}
}
}
if (isset($recipe->js)) {
drupal_add_js($recipe->js, 'inline');
$jss[] = $recipe->js;
}
if (isset($recipe->css)) {
drupal_set_html_head('<style type="text/css">' . $recipe->css . '</style>');
$csss[] = $recipe->css;
}
$added_botchas[] = $recipe->name;
}
// user_login forms open session in validate hooks instead of submit
// we should be the first to validate - add our hook to the beginning
if (is_array($form['#validate'])) {
array_unshift($form['#validate'], '_botcha_form_validate');
}
else {
$form['#validate'] = array(
'_botcha_form_validate',
);
}
$form_state['#botcha'] = $botcha;
// // Add a submit handler to remove form state storage.
// $form['#submit'][] = '_botcha_form_submit';
if (BOTCHA_LOGLEVEL >= 4) {
watchdog(BOTCHA_LOG, '%form_id form prepared by BOTCHA: added recipes - !botchas!more', array(
'%form_id' => $form_id,
'!botchas' => join(', ', $added_botchas),
'!more' => '' . (BOTCHA_LOGLEVEL >= 5 ? '<br /><br />' . 'POST=<pre>' . print_r(_botcha_filter_form_values_log($_POST), 1) . '</pre>' : '') . (BOTCHA_LOGLEVEL >= 5 ? '<br /><br />' . 'GET=<pre>' . print_r(_botcha_filter_form_values_log($_GET), 1) . '</pre>' : '') . (BOTCHA_LOGLEVEL >= 5 ? '<br /><br />' . 'SERVER=<pre>' . print_r($_SERVER, 1) . '</pre>' : '') . (BOTCHA_LOGLEVEL >= 5 ? '<br /><br />' . 'form=<pre>' . print_r(_botcha_filter_form_log($form), 1) . '</pre>' : '') . (BOTCHA_LOGLEVEL >= 5 && count($jss) ? '<br /><br />' . 'JS=<pre>' . join("\n", $jss) . '</pre>' : '') . (BOTCHA_LOGLEVEL >= 5 && count($csss) ? '<br /><br />' . 'CSS=<pre>' . join("\n", $csss) . '</pre>' : ''),
), WATCHDOG_NOTICE);
}
if ($build_id_subm != $build_id) {
$form_state['post']['form_build_id'] = $build_id;
// Issue the client a new build_id, make sure that the form has it set in the hidden field
}
_botcha_set_form_cache($build_id);
// Save build id
}