You are here

function honeypot_add_form_protection in Honeypot 8

Same name and namespace in other branches
  1. 6 honeypot.module \honeypot_add_form_protection()
  2. 7 honeypot.module \honeypot_add_form_protection()
  3. 2.0.x honeypot.module \honeypot_add_form_protection()

Form builder function to add different types of protection to forms.

Parameters

array $options: Array of options to be added to form. Currently accepts 'honeypot' and 'time_restriction'.

1 call to honeypot_add_form_protection()
honeypot_form_alter in ./honeypot.module
Implements hook_form_alter().

File

./honeypot.module, line 123
Honeypot module, for deterring spam bots from completing Drupal forms.

Code

function honeypot_add_form_protection(&$form, FormStateInterface $form_state, array $options = []) {
  $account = \Drupal::currentUser();

  // Allow other modules to alter the protections applied to this form.
  \Drupal::moduleHandler()
    ->alter('honeypot_form_protections', $options, $form);

  // Don't add any protections if the user can bypass the Honeypot.
  if ($account
    ->hasPermission('bypass honeypot protection')) {
    return;
  }

  // Build the honeypot element.
  if (in_array('honeypot', $options)) {

    // Get the element name (default is generic 'url').
    $honeypot_element = \Drupal::config('honeypot.settings')
      ->get('element_name');

    // Build the honeypot element.
    $honeypot_class = $honeypot_element . '-textfield';
    $form[$honeypot_element] = [
      '#theme_wrappers' => [
        0 => 'form_element',
        'container' => [
          '#id' => NULL,
          '#attributes' => [
            'class' => [
              $honeypot_class,
            ],
            'style' => [
              'display: none !important;',
            ],
          ],
        ],
      ],
      '#type' => 'textfield',
      '#title' => t('Leave this field blank'),
      '#size' => 20,
      '#weight' => 100,
      '#attributes' => [
        'autocomplete' => 'off',
      ],
      '#element_validate' => [
        '_honeypot_honeypot_validate',
      ],
    ];
  }

  // Set the time restriction for this form (if it's not disabled).
  if (in_array('time_restriction', $options) && \Drupal::config('honeypot.settings')
    ->get('time_limit') != 0) {

    // Set the current time in a hidden value to be checked later.
    $input = $form_state
      ->getUserInput();
    if (empty($input['honeypot_time'])) {
      $identifier = Crypt::randomBytesBase64();
      \Drupal::service('keyvalue.expirable')
        ->get('honeypot_time_restriction')
        ->setWithExpire($identifier, time(), 3600 * 24);
    }
    else {
      $identifier = $input['honeypot_time'];
    }
    $form['honeypot_time'] = [
      '#type' => 'hidden',
      '#title' => t('Timestamp'),
      '#default_value' => $identifier,
      '#element_validate' => [
        '_honeypot_time_restriction_validate',
      ],
      '#cache' => [
        'max-age' => 0,
      ],
    ];

    // Disable page caching to make sure timestamp isn't cached.
    $account = \Drupal::currentUser();
    if ($account
      ->id() == 0) {

      // TODO D8 - Use DIC? See: http://drupal.org/node/1539454
      // Should this now set 'omit_vary_cookie' instead?
      Drupal::service('page_cache_kill_switch')
        ->trigger();
    }
  }

  // Allow other modules to react to addition of form protection.
  if (!empty($options)) {
    \Drupal::moduleHandler()
      ->invokeAll('honeypot_add_form_protection', [
      $options,
      $form,
    ]);
  }
}