You are here

function _botcha_recipe3 in BOTCHA Spam Prevention 6

Same name and namespace in other branches
  1. 7 botcha.botcha.inc \_botcha_recipe3()

Botcha recipe.

1 string reference to '_botcha_recipe3'
_botcha_recipes in ./botcha.botcha.inc

File

./botcha.botcha.inc, line 286
Implementation of botcha form logic.

Code

function _botcha_recipe3($form, $secret, $error_field) {
  $form_id = $form['#id'];
  if (strpos($form_id, '-node-form') !== false) {
    $js_form_id = 'node-form';
  }
  else {
    $js_form_id = $form_id;
  }
  $myseed = 'itr_r3' . substr($secret, 0, 7);
  $spf = md5($myseed . substr('secret', 0, -4));
  $field_class = 'a' . substr($spf, 1, 4) . '_field';

  // 'a' for Firefox ignores ".<number>" class in CSS filter!
  $field_name = substr($spf, 0, 3) . '_name';
  $field_name_url = substr($spf, 1, 4) . '_name';
  $field_prefx = substr($spf, 10, mt_rand(3, 6));
  $secure_token = substr($spf, 4, -2) . '_form';
  $js_name = substr($myseed, 0, 10) . substr($spf, 6, 8);

  // Script name
  // Chop the token in 3 parts
  $chop1 = 2;
  $chop2 = mt_rand(5, 8);
  $js_tok1 = substr($secure_token, 0, $chop1);
  $field_dflt = $field_prefx . substr($secure_token, $chop1, $chop2);

  // What server sends to JS in the field.
  $js_tok2 = substr($secure_token, $chop1 + $chop2);

  // JS has to reconstruct the token form tok1, part of field_dflt, tok2
  $js_match = substr($field_dflt, 0, strlen($field_prefx) + mt_rand(2, $chop2));

  // What JS matches in the field
  $js_pos = strlen($field_prefx);

  // What position is the part of the token
  $recipe = new stdClass();
  $recipe->name = 'obscure_url_field';
  $recipe->description = t('Insert a new field into form action URL');
  $recipe->description_bots = t('Bots will not run JS and miss the field');
  $recipe->description_how = t('%parts is added to the form.', array(
    '%parts' => 'JS',
  )) . ' ' . t('JS enters key value into the field.');
  $recipe->error_field = $error_field;
  $recipe->error_text = _botcha_error_text_errorcode($spf) . '<li>' . _botcha_error_text_javascript() . '<li>' . _botcha_error_text();

  // Add hidden field to keep part of the token
  $recipe->form_elements = array(
    $field_name => array(
      '#type' => 'hidden',
      '#default_value' => $field_dflt,
      // Store part of secure_token
      '#attributes' => array(
        'class' => $field_class,
      ),
      '#weight' => 20,
    ),
  );

  // Describe URL field. JS will return token in URL field.
  $recipe->url_elements = array(
    $field_name_url => array(
      '#type' => 'textfield',
      '#default_value' => '',
      '!valid_token' => $secure_token,
    ),
  );
  $selector = "input.{$field_class}";
  $submit = _botcha_url($form['#action'], array(
    'query' => array(
      $field_name_url => '__replace__',
    ),
  ));
  $submit = preg_replace('/__replace__/', $js_tok1 . '\'+v+\'' . $js_tok2, $submit);
  $recipe->js = <<<END
Drupal.behaviors.{<span class="php-variable">$js_name</span>} = function() {
  \$("{<span class="php-variable">$selector</span>}").each(function() {
    f=\$(this)[0];
    if (f.value.indexOf("{<span class="php-variable">$js_match</span>}")==0){
      v=f.value.substring({<span class="php-variable">$js_pos</span>});
      form=\$(this).parents("form#{<span class="php-variable">$js_form_id</span>}")[0];
      \$(form)[0].action ='{<span class="php-variable">$submit</span>}';
    }
  });
};
END;
  return $recipe;
}