You are here

public function AnonymousPublishingClService::validate in Anonymous Publishing 8

Common validation of submission form for nodes and comments.

Only called when content is first posted (not when it it is activated via link).

Parameters

mixed $entity: The entity to validate (node or comment).

Return value

bool TRUE if the form validates, FALSE otherwise.

File

modules/anonymous_publishing_cl/src/Services/AnonymousPublishingClService.php, line 225

Class

AnonymousPublishingClService
Helper methods for Anonymous Publishing CL.

Namespace

Drupal\anonymous_publishing_cl\Services

Code

public function validate(&$form, FormStateInterface $form_state) {
  $settings = $this->configFactory
    ->get('anonymous_publishing_cl.settings');

  // Check if validation is needed here.
  $need_validation = $this
    ->isValidationNeeded($form);
  if (!$need_validation) {
    return TRUE;
  }

  // Extract email and email_confirm_field values
  $email = $form_state
    ->getValue('anonymous_publishing_email');
  $email_spam_bot = $form_state
    ->getValue('anonymous_publishing_email_confirm_field');

  // Check and act if spam bot detected.
  if (!empty($email_spam_bot)) {

    // Log the spam bot.
    $this->logger
      ->warning('Bot with email "@email".', array(
      '@email' => $email,
    ));

    // Insert or update the bot submission in DB.
    $query = $this->database
      ->select('anonymous_publishing_bots');
    $query
      ->fields('anonymous_publishing_bots', array(
      'id',
    ));
    $query
      ->condition('ip', $this->request
      ->getClientIp());
    $id = $query
      ->execute()
      ->fetchField();
    if ($id) {
      $this->database
        ->update('anonymous_publishing_bots')
        ->fields(array(
        'last' => \Drupal::time()
          ->getRequestTime(),
      ))
        ->expression('visits', 'visits + 1')
        ->condition('id', $id)
        ->execute();
    }
    else {
      $this->database
        ->insert('anonymous_publishing_bots')
        ->fields(array(
        'ip',
        'visits',
        'first',
        'last',
      ), array(
        $this->request
          ->getClientIp(),
        1,
        \Drupal::time()
          ->getRequestTime(),
        \Drupal::time()
          ->getRequestTime(),
      ))
        ->execute();
    }
    $form_state
      ->setErrorByName(anonymous_publishing_email, "I smell a bot.  Please log in to post.");
    return $this
      ->redirect('<front>');
  }

  // If the entity is newly inserted (ie not edition).
  $nid = $form_state
    ->getFormObject()
    ->getEntity()
    ->id();
  if (empty($nid)) {

    // If email given if for registered user, and if this is not permitted:
    // Do not authorize.
    user_load_by_mail($email);
    $options = $settings
      ->get('general_options');
    if (user_load_by_mail($email) && !$options['aregist']) {
      $form_state
        ->setErrorByName('anonymous_publishing_email', t('This email is already in use.  If this is you, please log in to post.'));
      return FALSE;
    }

    // Retrieve all previous submissions made with this email address.
    $ip = $this->request
      ->getClientIp();
    $query = $this->database
      ->select('anonymous_publishing_emails');
    $query
      ->fields('anonymous_publishing_emails');
    $query
      ->condition('email', $email);
    if ($options['blockip']) {
      $condition = new Condition('OR');
      $condition
        ->condition('ipaddress', $ip);
      $query
        ->condition($condition);
    }
    $result = $query
      ->execute()
      ->fetchAll();
    $num_prev_submissions = count($result);

    // Block if at least one record indicate that this should be blocked.
    $blocked = 0;
    $now = date('Y-m-d');
    if ($num_prev_submissions) {
      foreach ($result as $record) {
        $auid = $record->auid;
        $blocked += $record->blocked;
        $this->database
          ->update('anonymous_publishing_emails')
          ->fields(array(
          'lastseen' => $now,
        ))
          ->condition('auid', $auid)
          ->execute();
      }
    }
    else {

      // Block is this post is considered as flooding.
      $flood_limit = $settings
        ->get('flood_limit');
      $flooded = FALSE;
      if ($flood_limit != -1) {
        $blockingByIp = $settings
          ->get('blockip');
        if ($blockingByIp) {
          if (!$this->flood
            ->isAllowed('anonymous_publishing_ip', $flood_limit, 3600)) {
            $flooded = TRUE;
          }
        }
        else {
          if (!$this->flood
            ->isAllowed('anonymous_publishing_em', $flood_limit, 3600, $email)) {
            $flooded = TRUE;
          }
        }
        $this->flood
          ->register('anonymous_publishing_ip', 3600);
        $this->flood
          ->register('anonymous_publishing_em', 3600, $email);
      }

      // Check if the post is a flood.
      if ($flooded) {
        $form_state
          ->setErrorByName('anonymous_publishing_email', t('This website only allows @flood_limit postings of content from non-registered users within one hour.  This restriction may be lifted if you register.', array(
          '@flood_limit' => $flood_limit,
        )));
        return FALSE;
      }
      return FALSE;
    }

    // Check if the IP is banned.
    if ($blocked) {
      $form_state
        ->setErrorByName('anonymous_publishing_email', t('This email/ip-address is banned from posting content on this site.  Please contact the site administrator if you believe this is an error.'));
      return FALSE;
    }
  }
  return TRUE;
}