You are here

cleantalk.module in Anti Spam by CleanTalk 7.2

Main CleanTalk integration module functions.

File

cleantalk.module
View source
<?php

/**
 * @file
 * Main CleanTalk integration module functions.
 */

/**
 * Implements hook_html_head_alter(&$head_elements).
 */
$cleantalk_executed = false;
error_reporting(E_ALL);

/**
Cleantalk Spam FireWall class
**/
class CleanTalkSFW {
  public $ip = 0;
  public $ip_str = '';
  public $ip_array = array();
  public $ip_str_array = array();
  public $blocked_ip = '';
  public $passed_ip = '';
  public $result = false;
  public function cleantalk_get_real_ip() {
    if (function_exists('apache_request_headers')) {
      $headers = apache_request_headers();
    }
    else {
      $headers = $_SERVER;
    }
    if (array_key_exists('X-Forwarded-For', $headers)) {
      $the_ip = explode(",", trim($headers['X-Forwarded-For']));
      $the_ip = trim($the_ip[0]);
      $this->ip_str_array[] = $the_ip;
      $this->ip_array[] = sprintf("%u", ip2long($the_ip));
    }
    if (array_key_exists('HTTP_X_FORWARDED_FOR', $headers)) {
      $the_ip = explode(",", trim($headers['HTTP_X_FORWARDED_FOR']));
      $the_ip = trim($the_ip[0]);
      $this->ip_str_array[] = $the_ip;
      $this->ip_array[] = sprintf("%u", ip2long($the_ip));
    }
    $the_ip = filter_var($_SERVER['REMOTE_ADDR'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4);
    $this->ip_str_array[] = $the_ip;
    $this->ip_array[] = sprintf("%u", ip2long($the_ip));
    if (isset($_GET['sfw_test_ip'])) {
      $the_ip = $_GET['sfw_test_ip'];
      $this->ip_str_array[] = $the_ip;
      $this->ip_array[] = sprintf("%u", ip2long($the_ip));
    }
  }
  public function check_ip() {
    $n = 1;
    $r = db_query("SHOW TABLES LIKE 'cleantalk_sfw'");
    $ob = $r
      ->fetchObject();
    if (isset($ob) && is_object($ob)) {
      for ($i = 0; $i < sizeof($this->ip_array); $i++) {
        $r = db_query("select count(network) as cnt from `cleantalk_sfw` where network = " . $this->ip_array[$i] . " & mask;");
        $cnt = intval($r
          ->fetchObject()->cnt);
        if ($cnt > 0) {
          $this->result = true;
          $this->blocked_ip = $this->ip_str_array[$i];
        }
        else {
          $this->passed_ip = $this->ip_str_array[$i];
        }
      }
    }
    if ($this->passed_ip != '') {
      $key = variable_get('cleantalk_authkey', '');
      @setcookie('ct_sfw_pass_key', md5($this->passed_ip . $key), 0, "/");
    }
  }
  public function sfw_die() {
    $key = variable_get('cleantalk_authkey', '');
    $sfw_die_page = file_get_contents(dirname(__FILE__) . "/sfw_die_page.html");
    $sfw_die_page = str_replace("{REMOTE_ADDRESS}", $this->blocked_ip, $sfw_die_page);
    $sfw_die_page = str_replace("{REQUEST_URI}", $_SERVER['REQUEST_URI'], $sfw_die_page);
    $sfw_die_page = str_replace("{SFW_COOKIE}", md5($this->blocked_ip . $key), $sfw_die_page);
    @setcookie('ct_sfw_passed', '0');
    @header('HTTP/1.0 403 Forbidden');
    print $sfw_die_page;
    die;
  }
  public static function sfw_update($ct_key) {
    $data = array(
      'auth_key' => $ct_key,
      'method_name' => '2s_blacklists_db',
    );
    $result = sendRawRequest('https://api.cleantalk.org/2.1', $data, false);
    $result = json_decode($result, true);
    if (isset($result['data'])) {
      if (count($result['data']) > 30) {
        db_truncate('cleantalk_sfw')
          ->execute();
        $result = $result['data'];
        $query = "INSERT INTO `cleantalk_sfw` VALUES ";
        for ($i = 0; $i < sizeof($result); $i++) {
          if ($i == sizeof($result) - 1) {
            $query .= "(" . $result[$i][0] . "," . $result[$i][1] . ");";
          }
          else {
            $query .= "(" . $result[$i][0] . "," . $result[$i][1] . "), ";
          }
        }
        $result = db_query($query);
      }
      variable_set('ct_sfw_last_updated', time());
    }
  }

  //Add entries to SFW log
  public static function sfw_update_logs($ip, $result) {
    if ($ip === NULL || $result === NULL) {
      error_log('SFW log update failed');
      return;
    }
    $blocked = $result == 'blocked' ? ' + 1' : '';
    $time = time();
    $query = "INSERT INTO `cleantalk_sfw_logs`\n\t\tSET \n\t\t\t`ip` = '{$ip}',\n\t\t\t`all` = 1,\n\t\t\t`blocked` = 1,\n\t\t\t`timestamp` = '" . $time . "'\n\t\tON DUPLICATE KEY \n\t\tUPDATE \n\t\t\t`all` = `all` + 1,\n\t\t\t`blocked` = `blocked`" . $blocked . ",\n\t\t\t`timestamp` = '" . $time . "'";
    $result = db_query($query);
  }

  //Send and wipe SFW log
  public static function send_logs($ct_key) {

    //Getting logs
    $tmp = db_query("SELECT * FROM `cleantalk_sfw_logs`");
    $result = $tmp
      ->fetchAll(PDO::FETCH_ASSOC);
    if (!empty($result)) {

      //Compile logs
      $data = array();
      foreach ($result as $key => $value) {
        $data[] = array(
          trim($value['ip']),
          $value['all'],
          $value['blocked'],
          $value['timestamp'],
        );
      }
      unset($key, $value, $result);

      //Final compile
      $qdata = array(
        'data' => json_encode($data),
        'rows' => count($data),
        'timestamp' => time(),
      );

      //Sendings request
      $result = sendRawRequest('https://api.cleantalk.org/?method_name=sfw_logs&auth_key=' . $ct_key, $qdata, false);
      $result = json_decode($result);

      //Checking answer and truncate table, reset counter
      if (isset($result->data) && isset($result->data->rows)) {
        if ($result->data->rows == count($data)) {
          db_query("TRUNCATE TABLE `cleantalk_sfw_logs`");
          variable_set('ct_sfw_last_logs_sent', time());
        }
      }
    }
  }

}

/**
 * Cleantalk base class
 *
 * @version 2.0.0
 * @package Cleantalk
 * @subpackage Base
 * @author Cleantalk team (welcome@cleantalk.org)
 * @copyright (C) 2014 CleanTalk team (http://cleantalk.org)
 * @license GNU/GPL: http://www.gnu.org/copyleft/gpl.html
 * @see https://github.com/CleanTalk/php-antispam 
 *
 */

/**
 * Response class
 */
class CleantalkResponse {

  /**
   *  Is stop words
   * @var int
   */
  public $stop_words = null;

  /**
   * Cleantalk comment
   * @var string
   */
  public $comment = null;

  /**
   * Is blacklisted
   * @var int
   */
  public $blacklisted = null;

  /**
   * Is allow, 1|0
   * @var int
   */
  public $allow = null;

  /**
   * Request ID
   * @var int
   */
  public $id = null;

  /**
   * Request errno
   * @var int
   */
  public $errno = null;

  /**
   * Error string
   * @var string
   */
  public $errstr = null;

  /**
   * Is fast submit, 1|0
   * @var string
   */
  public $fast_submit = null;

  /**
   * Is spam comment
   * @var string
   */
  public $spam = null;

  /**
   * Is JS
   * @var type
   */
  public $js_disabled = null;

  /**
   * Sms check
   * @var type
   */
  public $sms_allow = null;

  /**
   * Sms code result
   * @var type
   */
  public $sms = null;

  /**
   * Sms error code
   * @var type
   */
  public $sms_error_code = null;

  /**
   * Sms error code
   * @var type
   */
  public $sms_error_text = null;

  /**
   * Stop queue message, 1|0
   * @var int
   */
  public $stop_queue = null;

  /**
   * Account shuld by deactivated after registration, 1|0
   * @var int
   */
  public $inactive = null;

  /**
   * Account status
   * @var int
   */
  public $account_status = -1;

  /**
   * Create server response
   *
   * @param type $response
   * @param type $obj
   */
  function __construct($response = null, $obj = null) {
    if ($response && is_array($response) && count($response) > 0) {
      foreach ($response as $param => $value) {
        $this->{$param} = $value;
      }
    }
    else {
      $this->errno = $obj->errno;
      $this->errstr = $obj->errstr;
      $this->errstr = preg_replace("/.+(\\*\\*\\*.+\\*\\*\\*).+/", "\$1", $this->errstr);
      $this->stop_words = isset($obj->stop_words) ? utf8_decode($obj->stop_words) : null;
      $this->comment = isset($obj->comment) ? utf8_decode($obj->comment) : null;
      $this->blacklisted = isset($obj->blacklisted) ? $obj->blacklisted : null;
      $this->allow = isset($obj->allow) ? $obj->allow : 0;
      $this->id = isset($obj->id) ? $obj->id : null;
      $this->fast_submit = isset($obj->fast_submit) ? $obj->fast_submit : 0;
      $this->spam = isset($obj->spam) ? $obj->spam : 0;
      $this->js_disabled = isset($obj->js_disabled) ? $obj->js_disabled : 0;
      $this->sms_allow = isset($obj->sms_allow) ? $obj->sms_allow : null;
      $this->sms = isset($obj->sms) ? $obj->sms : null;
      $this->sms_error_code = isset($obj->sms_error_code) ? $obj->sms_error_code : null;
      $this->sms_error_text = isset($obj->sms_error_text) ? $obj->sms_error_text : null;
      $this->stop_queue = isset($obj->stop_queue) ? $obj->stop_queue : 0;
      $this->inactive = isset($obj->inactive) ? $obj->inactive : 0;
      $this->account_status = isset($obj->account_status) ? $obj->account_status : -1;
      if ($this->errno !== 0 && $this->errstr !== null && $this->comment === null) {
        $this->comment = '*** ' . $this->errstr . ' Antispam service cleantalk.org ***';
      }
    }
  }

}

/**
 * Request class
 */
class CleantalkRequest {

  /**
   *  All http request headers
   * @var string
   */
  public $all_headers = null;

  /**
   *  IP address of connection
   * @var string
   */

  //public $remote_addr = null;

  /**
   *  Last error number
   * @var integer
   */
  public $last_error_no = null;

  /**
   *  Last error time
   * @var integer
   */
  public $last_error_time = null;

  /**
   *  Last error text
   * @var string
   */
  public $last_error_text = null;

  /**
   * User message
   * @var string
   */
  public $message = null;

  /**
   * Post example with last comments
   * @var string
   */
  public $example = null;

  /**
   * Auth key
   * @var string
   */
  public $auth_key = null;

  /**
   * Engine
   * @var string
   */
  public $agent = null;

  /**
   * Is check for stoplist,
   * valid are 0|1
   * @var int
   */
  public $stoplist_check = null;

  /**
   * Language server response,
   * valid are 'en' or 'ru'
   * @var string
   */
  public $response_lang = null;

  /**
   * User IP
   * @var strings
   */
  public $sender_ip = null;

  /**
   * User email
   * @var strings
   */
  public $sender_email = null;

  /**
   * User nickname
   * @var string
   */
  public $sender_nickname = null;

  /**
   * Sender info JSON string
   * @var string
   */
  public $sender_info = null;

  /**
   * Post info JSON string
   * @var string
   */
  public $post_info = null;

  /**
   * Is allow links, email and icq,
   * valid are 1|0
   * @var int
   */
  public $allow_links = null;

  /**
   * Time form filling
   * @var int
   */
  public $submit_time = null;

  /**
   * Is enable Java Script,
   * valid are 0|1|2
   * Status:
   *  null - JS html code not inserted into phpBB templates
   *  0 - JS disabled at the client browser
   *  1 - JS enabled at the client broswer
   * @var int
   */
  public $js_on = null;

  /**
   * user time zone
   * @var string
   */
  public $tz = null;

  /**
   * Feedback string,
   * valid are 'requset_id:(1|0)'
   * @var string
   */
  public $feedback = null;

  /**
   * Phone number
   * @var type
   */
  public $phone = null;

  /**
   * Method name
   * @var string
   */
  public $method_name = 'check_message';

  /**
   * Fill params with constructor
   * @param type $params
   */
  public function __construct($params = null) {
    if (is_array($params) && count($params) > 0) {
      foreach ($params as $param => $value) {
        $this->{$param} = $value;
      }
    }
  }

}

/**
 * Cleantalk class create request
 */
class Cleantalk {

  /**
   * Debug level
   * @var int
   */
  public $debug = 0;

  /**
   * Maximum data size in bytes
   * @var int
   */
  private $dataMaxSise = 32768;

  /**
   * Data compression rate
   * @var int
   */
  private $compressRate = 6;

  /**
   * Server connection timeout in seconds
   * @var int
   */
  private $server_timeout = 3;

  /**
   * Cleantalk server url
   * @var string
   */
  public $server_url = null;

  /**
   * Last work url
   * @var string
   */
  public $work_url = null;

  /**
   * WOrk url ttl
   * @var int
   */
  public $server_ttl = null;

  /**
   * Time wotk_url changer
   * @var int
   */
  public $server_changed = null;

  /**
   * Flag is change server url
   * @var bool
   */
  public $server_change = false;

  /**
   * Use TRUE when need stay on server. Example: send feedback
   * @var bool
   */
  public $stay_on_server = false;

  /**
   * Codepage of the data
   * @var bool
   */
  public $data_codepage = null;

  /**
   * API version to use
   * @var string
   */
  public $api_version = '/api2.0';

  /**
   * Use https connection to servers
   * @var bool
   */
  public $ssl_on = false;

  /**
   * Minimal server response in miliseconds to catch the server
   *
   */
  public $min_server_timeout = 50;

  /**
   * Function checks whether it is possible to publish the message
   * @param CleantalkRequest $request
   * @return type
   */
  public function isAllowMessage(CleantalkRequest $request) {
    $this
      ->filterRequest($request);
    $msg = $this
      ->createMsg('check_message', $request);
    return $this
      ->httpRequest($msg);
  }

  /**
   * Function checks whether it is possible to publish the message
   * @param CleantalkRequest $request
   * @return type
   */
  public function isAllowUser(CleantalkRequest $request) {
    $this
      ->filterRequest($request);
    $msg = $this
      ->createMsg('check_newuser', $request);
    return $this
      ->httpRequest($msg);
  }

  /**
   * Function sends the results of manual moderation
   *
   * @param CleantalkRequest $request
   * @return type
   */
  public function sendFeedback(CleantalkRequest $request) {
    $this
      ->filterRequest($request);
    $msg = $this
      ->createMsg('send_feedback', $request);
    return $this
      ->httpRequest($msg);
  }

  /**
   *  Filter request params
   * @param CleantalkRequest $request
   * @return type
   */
  private function filterRequest(CleantalkRequest &$request) {

    // general and optional
    foreach ($request as $param => $value) {
      if (in_array($param, array(
        'message',
        'example',
        'agent',
        'sender_info',
        'sender_nickname',
        'post_info',
        'phone',
      )) && !empty($value)) {
        if (!is_string($value) && !is_integer($value)) {
          $request->{$param} = NULL;
        }
      }
      if (in_array($param, array(
        'stoplist_check',
        'allow_links',
      )) && !empty($value)) {
        if (!in_array($value, array(
          1,
          2,
        ))) {
          $request->{$param} = NULL;
        }
      }
      if (in_array($param, array(
        'js_on',
      )) && !empty($value)) {
        if (!is_integer($value)) {
          $request->{$param} = NULL;
        }
      }
      if ($param == 'sender_ip' && !empty($value)) {
        if (!is_string($value)) {
          $request->{$param} = NULL;
        }
      }
      if ($param == 'sender_email' && !empty($value)) {
        if (!is_string($value)) {
          $request->{$param} = NULL;
        }
      }
      if ($param == 'submit_time' && !empty($value)) {
        if (!is_int($value)) {
          $request->{$param} = NULL;
        }
      }
    }
  }

  /**
   * Compress data and encode to base64
   * @param type string
   * @return string
   */
  private function compressData($data = null) {
    if (strlen($data) > $this->dataMaxSise && function_exists('gzencode') && function_exists('base64_encode')) {
      $localData = gzencode($data, $this->compressRate, FORCE_GZIP);
      if ($localData === false) {
        return $data;
      }
      $localData = base64_encode($localData);
      if ($localData === false) {
        return $data;
      }
      return $localData;
    }
    return $data;
  }

  /**
   * Create msg for cleantalk server
   * @param type $method
   * @param CleantalkRequest $request
   * @return \xmlrpcmsg
   */
  private function createMsg($method, CleantalkRequest $request) {
    switch ($method) {
      case 'check_message':

        // Convert strings to UTF8
        $request->message = $this
          ->stringToUTF8($request->message, $this->data_codepage);
        $request->example = $this
          ->stringToUTF8($request->example, $this->data_codepage);
        $request->sender_email = $this
          ->stringToUTF8($request->sender_email, $this->data_codepage);
        $request->sender_nickname = $this
          ->stringToUTF8($request->sender_nickname, $this->data_codepage);
        $request->message = $this
          ->compressData($request->message);
        $request->example = $this
          ->compressData($request->example);
        break;
      case 'check_newuser':

        // Convert strings to UTF8
        $request->sender_email = $this
          ->stringToUTF8($request->sender_email, $this->data_codepage);
        $request->sender_nickname = $this
          ->stringToUTF8($request->sender_nickname, $this->data_codepage);
        break;
      case 'send_feedback':
        if (is_array($request->feedback)) {
          $request->feedback = implode(';', $request->feedback);
        }
        break;
    }
    $request->method_name = $method;

    //
    // Removing non UTF8 characters from request, because non UTF8 or malformed characters break json_encode().
    //
    foreach ($request as $param => $value) {
      if (!preg_match('//u', $value)) {
        $request->{$param} = 'Nulled. Not UTF8 encoded or malformed.';
      }
    }
    return $request;
  }

  /**
   * Send JSON request to servers
   * @param $msg
   * @return boolean|\CleantalkResponse
   */
  private function sendRequest($data = null, $url, $server_timeout = 3) {

    // Convert to array
    $data = drupal_json_decode(drupal_json_encode($data));

    // Convert to JSON
    $data = drupal_json_encode($data);
    if (isset($this->api_version)) {
      $url = $url . $this->api_version;
    }

    // Switching to secure connection
    if ($this->ssl_on && !preg_match("/^https:/", $url)) {
      $url = preg_replace("/^(http)/i", "\$1s", $url);
    }
    $result = false;
    $curl_error = null;
    if (function_exists('curl_init')) {
      $ch = curl_init();
      curl_setopt($ch, CURLOPT_URL, $url);
      curl_setopt($ch, CURLOPT_TIMEOUT, $server_timeout);
      curl_setopt($ch, CURLOPT_POST, 1);
      curl_setopt($ch, CURLOPT_POSTFIELDS, $data);

      // receive server response ...
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

      // resolve 'Expect: 100-continue' issue
      curl_setopt($ch, CURLOPT_HTTPHEADER, array(
        'Expect:',
      ));

      // see http://stackoverflow.com/a/23322368
      curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);

      // Disabling CA cert verivication
      // Disabling common name verification
      if ($this->ssl_on) {
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
      }
      $result = curl_exec($ch);
      if (!$result) {
        $curl_error = curl_error($ch);
      }
      curl_close($ch);
    }
    if (!$result) {
      $allow_url_fopen = ini_get('allow_url_fopen');
      if (function_exists('file_get_contents') && isset($allow_url_fopen) && $allow_url_fopen == '1') {
        $opts = array(
          'http' => array(
            'method' => 'POST',
            'header' => "Content-Type: text/html\r\n",
            'content' => $data,
            'timeout' => $server_timeout,
          ),
        );
        $context = stream_context_create($opts);
        $result = @file_get_contents($url, false, $context);
      }
    }
    if (!$result) {
      $response = null;
      $response['errno'] = 1;
      if ($curl_error) {
        $response['errstr'] = sprintf("CURL error: '%s'", $curl_error);
      }
      else {
        $response['errstr'] = 'No CURL support compiled in';
      }
      $response['errstr'] .= ' or disabled allow_url_fopen in php.ini.';
      $response = (object) drupal_json_decode(drupal_json_encode($response));
      return $response;
    }
    $errstr = null;
    $response = (object) drupal_json_decode($result);
    if ($result !== false && is_object($response)) {
      $response->errno = 0;
      $response->errstr = $errstr;
    }
    else {
      $errstr = 'Unknown response from ' . $url . '.' . ' ' . $result;
      $response = null;
      $response['errno'] = 1;
      $response['errstr'] = $errstr;
      $response = (object) drupal_json_decode(drupal_json_encode($response));
    }
    return $response;
  }

  /**
   * httpRequest
   * @param $msg
   * @return boolean|\CleantalkResponse
   */
  private function httpRequest($msg) {
    $result = false;
    $msg->all_headers = drupal_json_encode(apache_request_headers());

    //$msg->remote_addr=$_SERVER['REMOTE_ADDR'];

    //$msg->sender_info['remote_addr']=$_SERVER['REMOTE_ADDR'];
    $si = drupal_json_decode($msg->sender_info);
    $si['remote_addr'] = $_SERVER['REMOTE_ADDR'];
    $msg->sender_info = drupal_json_encode($si);
    if (isset($this->work_url) && $this->work_url !== '' && $this->server_changed + $this->server_ttl > time() || $this->stay_on_server == true) {
      $url = !empty($this->work_url) ? $this->work_url : $this->server_url;
      $result = $this
        ->sendRequest($msg, $url, $this->server_timeout);
    }
    if (($result === false || $result->errno != 0) && $this->stay_on_server == false) {

      // Split server url to parts
      preg_match("@^(https?://)([^/:]+)(.*)@i", $this->server_url, $matches);
      $url_prefix = '';
      if (isset($matches[1])) {
        $url_prefix = $matches[1];
      }
      $pool = null;
      if (isset($matches[2])) {
        $pool = $matches[2];
      }
      $url_suffix = '';
      if (isset($matches[3])) {
        $url_suffix = $matches[3];
      }
      if ($url_prefix === '') {
        $url_prefix = 'http://';
      }
      if (empty($pool)) {
        return false;
      }
      else {

        // Loop until find work server
        foreach ($this
          ->get_servers_ip($pool) as $server) {
          if ($server['host'] === 'localhost' || $server['ip'] === null) {
            $work_url = $server['host'];
          }
          else {
            $server_host = $server['ip'];
            $work_url = $server_host;
          }
          $work_url = $url_prefix . $work_url;
          if (isset($url_suffix)) {
            $work_url = $work_url . $url_suffix;
          }
          $this->work_url = $work_url;
          $this->server_ttl = $server['ttl'];
          $result = $this
            ->sendRequest($msg, $this->work_url, $this->server_timeout);
          if ($result !== false && $result->errno === 0) {
            $this->server_change = true;
            break;
          }
        }
      }
    }
    $response = new CleantalkResponse(null, $result);
    if (!empty($this->data_codepage) && $this->data_codepage !== 'UTF-8') {
      if (!empty($response->comment)) {
        $response->comment = $this
          ->stringFromUTF8($response->comment, $this->data_codepage);
      }
      if (!empty($response->errstr)) {
        $response->errstr = $this
          ->stringFromUTF8($response->errstr, $this->data_codepage);
      }
      if (!empty($response->sms_error_text)) {
        $response->sms_error_text = $this
          ->stringFromUTF8($response->sms_error_text, $this->data_codepage);
      }
    }
    return $response;
  }

  /**
   * Function DNS request
   * @param $host
   * @return array
   */
  public function get_servers_ip($host) {
    $response = null;
    if (!isset($host)) {
      return $response;
    }
    if (function_exists('dns_get_record')) {
      $records = dns_get_record($host, DNS_A);
      if ($records !== FALSE) {
        foreach ($records as $server) {
          $response[] = $server;
        }
      }
    }
    if (count($response) == 0 && function_exists('gethostbynamel')) {
      $records = gethostbynamel($host);
      if ($records !== FALSE) {
        foreach ($records as $server) {
          $response[] = array(
            "ip" => $server,
            "host" => $host,
            "ttl" => $this->server_ttl,
          );
        }
      }
    }
    if (count($response) == 0) {
      $response[] = array(
        "ip" => null,
        "host" => $host,
        "ttl" => $this->server_ttl,
      );
    }
    else {

      // $i - to resolve collisions with localhost
      $i = 0;
      $r_temp = null;
      $fast_server_found = false;
      foreach ($response as $server) {

        // Do not test servers because fast work server found
        if ($fast_server_found) {
          $ping = $this->min_server_timeout;
        }
        else {
          $ping = $this
            ->httpPing($server['ip']);
          $ping = $ping * 1000;
        }

        // -1 server is down, skips not reachable server
        if ($ping != -1) {
          $r_temp[$ping + $i] = $server;
        }
        $i++;
        if ($ping < $this->min_server_timeout) {
          $fast_server_found = true;
        }
      }
      if (count($r_temp)) {
        ksort($r_temp);
        $response = $r_temp;
      }
    }
    return $response;
  }

  /**
   * Function to get the message hash from Cleantalk.ru comment
   * @param $message
   * @return null
   */
  public function getCleantalkCommentHash($message) {
    $matches = array();
    if (preg_match('/\\n\\n\\*\\*\\*.+([a-z0-9]{32}).+\\*\\*\\*$/', $message, $matches)) {
      return $matches[1];
    }
    else {
      if (preg_match('/\\<br.*\\>[\\n]{0,1}\\<br.*\\>[\\n]{0,1}\\*\\*\\*.+([a-z0-9]{32}).+\\*\\*\\*$/', $message, $matches)) {
        return $matches[1];
      }
    }
    return NULL;
  }

  /**
   * Function adds to the post comment Cleantalk.ru
   * @param $message
   * @param $comment
   * @return string
   */
  public function addCleantalkComment($message, $comment) {
    $comment = preg_match('/\\*\\*\\*(.+)\\*\\*\\*/', $comment, $matches) ? $comment : '*** ' . $comment . ' ***';
    return $message . "\n\n" . $comment;
  }

  /**
   * Function deletes the comment Cleantalk.ru
   * @param $message
   * @return mixed
   */
  public function delCleantalkComment($message) {
    $message = preg_replace('/\\n\\n\\*\\*\\*.+\\*\\*\\*$/', '', $message);

    // DLE sign cut
    $message = preg_replace('/<br\\s?\\/><br\\s?\\/>\\*\\*\\*.+\\*\\*\\*$/', '', $message);
    $message = preg_replace('/\\<br.*\\>[\\n]{0,1}\\<br.*\\>[\\n]{0,1}\\*\\*\\*.+\\*\\*\\*$/', '', $message);
    return $message;
  }

  /**
   *   Get user IP behind proxy server
   */
  public function ct_session_ip($data_ip) {
    if (!$data_ip || !preg_match("/^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\$/", $data_ip)) {
      return $data_ip;
    }

    /*if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {

                $forwarded_ip = explode(",", $_SERVER['HTTP_X_FORWARDED_FOR']);

                // Looking for first value in the list, it should be sender real IP address
                if (!preg_match("/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/", $forwarded_ip[0])) {
                    return $data_ip;
                }

                $private_src_ip = false;
                $private_nets = array(
                    '10.0.0.0/8',
                    '127.0.0.0/8',
                    '176.16.0.0/12',
                    '192.168.0.0/16',
                );

                foreach ($private_nets as $v) {

                    // Private IP found
                    if ($private_src_ip) {
                        continue;
                    }

                    if ($this->net_match($v, $data_ip)) {
                        $private_src_ip = true;
                    }
                }
                if ($private_src_ip) {
                    // Taking first IP from the list HTTP_X_FORWARDED_FOR
                    $data_ip = $forwarded_ip[0];
                }
            }

            return $data_ip;*/
    return cleantalk_get_real_ip();
  }

  /**
   * From http://php.net/manual/en/function.ip2long.php#82397
   */
  public function net_match($CIDR, $IP) {
    list($net, $mask) = explode('/', $CIDR);
    return (ip2long($IP) & ~((1 << 32 - $mask) - 1)) == ip2long($net);
  }

  /**
   * Function to check response time
   * param string
   * @return int
   */
  function httpPing($host) {

    // Skip localhost ping cause it raise error at fsockopen.
    // And return minimun value
    if ($host == 'localhost') {
      return 0.001;
    }
    $starttime = microtime(true);
    $file = @fsockopen($host, 80, $errno, $errstr, $this->server_timeout);
    $stoptime = microtime(true);
    $status = 0;
    if (!$file) {
      $status = -1;

      // Site is down
    }
    else {
      fclose($file);
      $status = $stoptime - $starttime;
      $status = round($status, 4);
    }
    return $status;
  }

  /**
   * Function convert string to UTF8 and removes non UTF8 characters
   * param string
   * param string
   * @return string
   */
  function stringToUTF8($str, $data_codepage = null) {
    if (!preg_match('//u', $str) && function_exists('mb_detect_encoding') && function_exists('mb_convert_encoding')) {
      if ($data_codepage !== null) {
        return mb_convert_encoding($str, 'UTF-8', $data_codepage);
      }
      $encoding = mb_detect_encoding($str);
      if ($encoding) {
        return mb_convert_encoding($str, 'UTF-8', $encoding);
      }
    }
    return $str;
  }

  /**
   * Function convert string from UTF8
   * param string
   * param string
   * @return string
   */
  function stringFromUTF8($str, $data_codepage = null) {
    if (preg_match('//u', $str) && function_exists('mb_convert_encoding') && $data_codepage !== null) {
      return mb_convert_encoding($str, $data_codepage, 'UTF-8');
    }
    return $str;
  }

}

/**
 * Function gets access key automatically
 *
 * @param string website admin email
 * @param string website host
 * @param string website platform
 * @return type
 */
function getAutoKey($email, $host, $platform) {
  $request = array();
  $request['method_name'] = 'get_api_key';
  $request['email'] = $email;
  $request['website'] = $host;
  $request['platform'] = $platform;
  $url = 'https://api.cleantalk.org';
  $result = sendRawRequest($url, $request);
  return $result;
}

/**
 * Function gets information about renew notice
 *
 * @param string api_key
 * @return type
 */
function noticePaidTill($api_key) {
  $request = array();
  $request['method_name'] = 'notice_paid_till';
  $request['auth_key'] = $api_key;
  $url = 'https://api.cleantalk.org';
  $result = sendRawRequest($url, $request);
  return $result;
}

/**
 * Function sends raw request to API server
 *
 * @param string url of API server
 * @param array data to send
 * @param boolean is data have to be JSON encoded or not
 * @param integer connect timeout
 * @return type
 */
function sendRawRequest($url, $data, $isJSON = false, $timeout = 3) {
  $result = null;
  if (!$isJSON) {
    $data = http_build_query($data);
  }
  else {
    $data = json_encode($data);
  }
  $curl_exec = false;
  if (function_exists('curl_init') && function_exists('json_decode')) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);

    // receive server response ...
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

    // resolve 'Expect: 100-continue' issue
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
      'Expect:',
    ));
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
    $result = @curl_exec($ch);
    if ($result !== false) {
      $curl_exec = true;
    }
    @curl_close($ch);
  }
  if (!$curl_exec) {
    $opts = array(
      'http' => array(
        'method' => "POST",
        'content' => $data,
      ),
    );
    $context = stream_context_create($opts);
    $result = @file_get_contents($url, 0, $context);
  }
  return $result;
}
if (!function_exists('apache_request_headers')) {
  function apache_request_headers() {
    $arh = array();
    $rx_http = '/\\AHTTP_/';
    foreach ($_SERVER as $key => $val) {
      if (preg_match($rx_http, $key)) {
        $arh_key = preg_replace($rx_http, '', $key);
        $rx_matches = array();
        $rx_matches = explode('_', $arh_key);
        if (count($rx_matches) > 0 and strlen($arh_key) > 2) {
          foreach ($rx_matches as $ak_key => $ak_val) {
            $rx_matches[$ak_key] = ucfirst($ak_val);
          }
          $arh_key = implode('-', $rx_matches);
        }
        $arh[$arh_key] = $val;
      }
    }
    return $arh;
  }
}
function cleantalk_get_real_ip() {
  if (function_exists('apache_request_headers')) {
    $headers = apache_request_headers();
  }
  else {
    $headers = $_SERVER;
  }
  if (array_key_exists('X-Forwarded-For', $headers) && filter_var($headers['X-Forwarded-For'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
    $the_ip = $headers['X-Forwarded-For'];
  }
  elseif (array_key_exists('HTTP_X_FORWARDED_FOR', $headers) && filter_var($headers['HTTP_X_FORWARDED_FOR'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
    $the_ip = $headers['HTTP_X_FORWARDED_FOR'];
  }
  else {
    $the_ip = filter_var($_SERVER['REMOTE_ADDR'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4);
  }
  return $the_ip;
}

/*
*
*
*   END OF CLEANTALK BASE CLASS
*
*/
function cleantalk_page_build(&$page) {
  drupal_session_initialize();
  drupal_save_session(true);
  if ($_SERVER['REQUEST_METHOD'] == 'GET') {
    $_SESSION['ct_submit_comment_time'] = REQUEST_TIME;
    $_SESSION['ct_submit_register_time'] = REQUEST_TIME;
  }
  $ct_check_def = '0';
  $ct_check_value = _cleantalk_get_checkjs_value();
  $js_template = 'function ctSetCookie(c_name, value, def_value) {
  document.cookie = c_name + "=" + escape(value.replace(/^def_value$/, value)) + "; path=/";
}
setTimeout("ctSetCookie(\\"%s\\", \\"%s\\", \\"%s\\");",1000);';
  $js_addon_body = sprintf($js_template, 'ct_checkjs', $ct_check_value, $ct_check_def);
  drupal_add_js($js_addon_body, array(
    'type' => 'inline',
    'scope' => 'footer',
    'weight' => 5,
    'cache' => FALSE,
    'every_page' => TRUE,
  ));
}

/**
 * Implements hook_form_FORM_ID_alter().
 */
function cleantalk_form_user_register_form_alter(&$form, &$form_state, $form_id) {
  _cleantalk_form_alter($form, $form_state, $form_id);
}

/**
 * Implements hook_form_BASE_FORM_ID_alter().
 */
function cleantalk_form_comment_form_alter(&$form, &$form_state, $form_id) {
  _cleantalk_form_alter($form, $form_state, $form_id);
}

/**
 * Implements hook_form_BASE_FORM_ID_alter().
 */
function cleantalk_form_node_form_alter(&$form, &$form_state, $form_id) {
  _cleantalk_form_alter($form, $form_state, $form_id);
}

/**
 * Implements hook_form_BASE_FORM_ID_alter().
 */

//function cleantalk_form_alter(&$form, &$form_state, $form_id) {

//  _cleantalk_form_alter($form, $form_state, $form_id);

//}

/**
 * Implements hook_form_BASE_FORM_ID_alter()
 */
function cleantalk_form_comment_node_webform_form_alter(&$form, &$form_state, $form_id) {
  _cleantalk_form_alter($form, $form_state, $form_id);
}

/**
 * Implements hook_form_BASE_FORM_ID_alter()
 */
function cleantalk_form_mailchimp_signup_subscribe_form_alter(&$form, &$form_state, $form_id) {
  drupal_session_start();
  $_SESSION['ct_submit_comment_time'] = REQUEST_TIME;
  $field_name = 'ct_checkjs';
  $ct_check_def = '0';
  if (!isset($_COOKIE[$field_name])) {
    setcookie($field_name, $ct_check_def, 0, '/');
  }

  // We cannot place JS in separate file.
  // Because it is not static - we have to use generated values.

  /*  $ct_check_value = _cleantalk_get_checkjs_value();
    $js_template = 'function ctSetCookie(c_name, value, def_value) {
    document.cookie = c_name + "=" + escape(value.replace(/^def_value$/, value)) + "; path=/";
  }
  setTimeout("ctSetCookie(\"%s\", \"%s\", \"%s\");",1000);';
    $js_addon_body = sprintf($js_template, $field_name, $ct_check_value, $ct_check_def);

    drupal_add_js($js_addon_body,
      array(
        'type' => 'inline',
        'scope' => 'footer',
        'weight' => 5,
        'cache' => FALSE,
        'every_page' => FALSE,
      )
    );*/
}

/**
 * Implements hook_form_FORM_ID_alter().
 */
function cleantalk_form_contact_site_form_alter(&$form, &$form_state, $form_id) {
  _cleantalk_form_alter($form, $form_state, $form_id);
}

/**
 * Implements hook_form_FORM_ID_alter().
 */
function cleantalk_form_contact_personal_form_alter(&$form, &$form_state, $form_id) {
  _cleantalk_form_alter($form, $form_state, $form_id);
}

/**
 * Implements hook_user_presave().
 */
function cleantalk_user_presave(&$edit, $account, $category) {
  $ct_result = _cleantalk_ct_result();
  if ($account->is_new && @empty($ct_result['ct_request_id'])) {
    $spam_check = array();
    $spam_check['type'] = 'register';
    $spam_check['sender_email'] = !empty($_POST['mail']) ? $_POST['mail'] : '';
    $spam_check['sender_nickname'] = !empty($_POST['name']) ? $_POST['name'] : '';
    $spam_result = _cleantalk_check_spam($spam_check);
    if (isset($spam_result) && is_array($spam_result) && $spam_result['errno'] == 0 && $spam_result['allow'] != 1) {
      _cleantalk_die($spam_result['ct_result_comment']);
    }
  }
}

/**
 * Cleantalk registration validation function.
 */
function cleantalk_validate_register(&$form, &$form_state) {
  $spam_check = array();
  $spam_check['type'] = 'register';
  $spam_check['sender_email'] = !empty($form_state['values']['mail']) ? $form_state['values']['mail'] : '';
  $spam_check['sender_nickname'] = !empty($form_state['values']['name']) ? $form_state['values']['name'] : '';
  $spam_check['timezone'] = !empty($form_state['values']['timezone']) ? $form_state['values']['timezone'] : '';
  $spam_result = _cleantalk_check_spam($spam_check);
  if (isset($spam_result) && is_array($spam_result) && $spam_result['errno'] == 0 && $spam_result['allow'] != 1) {

    // Value of ct_result_comment is sanitized already (before storing).
    form_set_error('mail', $spam_result['ct_result_comment']);
  }
}

/**
 * Cleantalk comment validation function.
 */
function cleantalk_validate_comment(&$form, &$form_state) {
  global $user;

  // Don't check reged user with >= 'cleantalk_comments' approved msgs.
  if ($user->uid > 0) {

    # Don't check admin activity
    if (isset($user->roles) && is_array($user->roles)) {
      if (in_array('administrator', $user->roles)) {
        return;
      }
    }
  }
  $spam_check = array();
  if (isset($form_state['values']) && is_array($form_state['values'])) {
    $base_form_id = $form_state['build_info']['base_form_id'];
    if ($base_form_id == 'comment_form') {

      // Fill parameters array for usual comment
      $spam_check['type'] = 'comment';
      $comment_lang = array_key_exists('language', $form_state['values']) ? $form_state['values']['language'] : LANGUAGE_NONE;
      if (isset($form_state['values']['comment_body']) && is_array($form_state['values']['comment_body']) && isset($form_state['values']['comment_body'][$comment_lang]) && is_array($form_state['values']['comment_body'][$comment_lang]) && isset($form_state['values']['comment_body'][$comment_lang][0])) {
        $comment_body = $form_state['values']['comment_body'][$comment_lang][0];
      }

      // Values below can be empty, we'll check as comment because of $base_form_id
      $spam_check['sender_email'] = !empty($form_state['values']['mail']) ? $form_state['values']['mail'] : '';
      $spam_check['sender_nickname'] = !empty($form_state['values']['name']) ? $form_state['values']['name'] : '';
      $spam_check['message_title'] = !empty($form_state['values']['subject']) ? $form_state['values']['subject'] : '';
      $spam_check['message_body'] = is_array($comment_body) && isset($comment_body['value']) ? $comment_body['value'] : '';
    }
    else {
      if ($base_form_id == 'node_form') {

        // Fill paramaters array for something looking like a comment
        $comment_lang = array_key_exists('language', $form_state['values']) ? $form_state['values']['language'] : LANGUAGE_NONE;
        if (isset($form_state['values']['body']) && is_array($form_state['values']['body']) && isset($form_state['values']['body'][$comment_lang]) && is_array($form_state['values']['body'][$comment_lang]) && isset($form_state['values']['body'][$comment_lang][0])) {
          $comment_body = $form_state['values']['body'][$comment_lang][0];

          // Values below cannot be empty, we won't check as comment because of $base_form_id
          if (!empty($form_state['values']['mail'])) {
            $spam_check['sender_email'] = $form_state['values']['mail'];
          }
          if (!empty($form_state['values']['name'])) {
            $spam_check['sender_nickname'] = $form_state['values']['name'];
          }
          if (!empty($form_state['values']['title'])) {
            $spam_check['message_title'] = $form_state['values']['title'];
          }
          if (is_array($comment_body) && isset($comment_body['value'])) {
            $spam_check['message_body'] = $comment_body['value'];
          }
          if (!empty($spam_check)) {
            $spam_check['type'] = 'node';
          }
        }
      }
    }
  }
  if (empty($spam_check)) {
    return;
  }
  else {
    if ($user->uid > 0) {
      $result = db_query('SELECT count(*) AS count FROM {comment} WHERE uid=:uid AND status=1', array(
        ':uid' => $user->uid,
      ));
      $count = intval($result
        ->fetchObject()->count);
      $ct_comments = variable_get('cleantalk_comments', 3);
      if ($count >= $ct_comments) {
        return;
      }
    }
  }
  $spam_result = _cleantalk_check_spam($spam_check);
  if (isset($spam_result) && is_array($spam_result) && $spam_result['errno'] == 0 && $spam_result['allow'] != 1 && $spam_result['stop_queue'] == 1) {

    // Value of ct_result_comment is sanitized already (before storing).
    form_set_error('comment_body', $spam_result['ct_result_comment']);
  }
}

/**
 * Cleantalk contact message validation function.
 */
function cleantalk_validate_contact_message(&$form, &$form_state) {
  global $user;

  // Don't check reged user with >= 'cleantalk_comments' approved msgs.
  if ($user->uid > 0) {

    # Don't check admin activity
    if (isset($user->roles) && is_array($user->roles)) {
      if (in_array('administrator', $user->roles)) {
        return;
      }
    }
    $result = db_query('SELECT count(*) AS count FROM {comment} WHERE uid=:uid AND status=1', array(
      ':uid' => $user->uid,
    ));
    $count = intval($result
      ->fetchObject()->count);
    $ct_comments = variable_get('cleantalk_comments', 3);
    if ($count >= $ct_comments) {
      return;
    }
  }
  $spam_check = array();
  $spam_check['type'] = 'contact';
  $spam_check['sender_email'] = !empty($form_state['values']['mail']) ? $form_state['values']['mail'] : '';
  $spam_check['sender_nickname'] = !empty($form_state['values']['name']) ? $form_state['values']['name'] : '';
  $spam_check['message_title'] = !empty($form_state['values']['subject']) ? $form_state['values']['subject'] : '';
  $spam_check['message_body'] = !empty($form_state['values']['message']) ? $form_state['values']['message'] : '';
  $spam_result = _cleantalk_check_spam($spam_check);
  if (isset($spam_result) && is_array($spam_result) && $spam_result['errno'] == 0 && $spam_result['allow'] != 1 && $spam_result['stop_queue'] == 1) {

    // Value of ct_result_comment is sanitized already (before storing).
    form_set_error('comment_body', $spam_result['ct_result_comment']);
  }
}

/**
 * Implements hook_comment_presave().
 */
function cleantalk_comment_presave($comment) {
  $ct_result = _cleantalk_ct_result();
  if (!empty($ct_result['ct_request_id'])) {
    $ct_automod = variable_get('cleantalk_automod', 1);
    if ($ct_automod == 1) {

      // Automoderation enabled - change comment status.
      // Not empty 'ct_result_comment' means bad comment, set status = 0.
      // Empty 'ct_result_comment' means good comment, set status = 1.
      $comment->status = empty($ct_result['ct_result_comment']) ? COMMENT_PUBLISHED : COMMENT_NOT_PUBLISHED;
    }

    // Don't clear 'ct_request_id', use it in cleantalk_comment_insert().
  }
}
function cleantalk_node_presave($node) {
  $ct_result = _cleantalk_ct_result();
  if (!empty($ct_result['ct_request_id'])) {
    $ct_automod = variable_get('cleantalk_automod', 1);
    if ($ct_automod == 1) {

      // Automoderation enabled - change comment status.
      // Not empty 'ct_result_comment' means bad comment, set status = 0.
      // Empty 'ct_result_comment' means good comment, set status = 1.
      $node->status = empty($ct_result['ct_result_comment']) ? NODE_PUBLISHED : NODE_NOT_PUBLISHED;
    }

    // Don't clear 'ct_request_id', use it in cleantalk_comment_insert().
  }
}

/**
 * Implements hook_comment_insert().
 */
function cleantalk_comment_insert($comment) {
  $ct_result = _cleantalk_ct_result();
  if (!empty($ct_result['ct_request_id'])) {

    // Values of request_id and comment are stored in globals.
    // Store them in DB now.
    db_insert('cleantalk_cids')
      ->fields(array(
      'cid' => $comment->cid,
      'ct_request_id' => $ct_result['ct_request_id'],
      'ct_result_comment' => empty($ct_result['ct_result_comment']) ? '' : $ct_result['ct_result_comment'],
    ))
      ->execute();
    _cleantalk_ct_result('set');
  }
}

/**
 * Implements hook_user_insert().
 */
function cleantalk_user_insert(&$edit, $account, $category) {
  if ($category != 'account') {
    return;
  }
  $ct_result = _cleantalk_ct_result();
  if (!empty($ct_result['ct_request_id'])) {
    db_insert('cleantalk_uids')
      ->fields(array(
      'uid' => $account->uid,
      'ct_request_id' => $ct_result['ct_request_id'],
      'ct_result_comment' => empty($ct_result['ct_result_comment']) ? '' : $GLOBALS['ct_result_comment'],
    ))
      ->execute();
    _cleantalk_ct_result('set');
  }
}

/**
 * Implements hook_comment_publish().
 */
function cleantalk_comment_publish($comment) {
  if (isset($comment->form_id)) {

    // Not empty form_id means editing but not approving by link
    return;
  }
  $result = db_select('cleantalk_cids', 'c')
    ->fields('c', array(
    'ct_request_id',
    'ct_result_comment',
  ))
    ->condition('cid', $comment->cid, '=')
    ->range(0, 1)
    ->execute();
  if ($result
    ->rowCount() > 0) {
    $ct_result = $result
      ->fetchObject();

    // If ct_result_comment is not empty then comment is not approved by server.
    // But we publish it then comment is approved by admin.
    // We need to send positive feedback.
    _cleantalk_send_feedback($ct_result->ct_request_id, 1);
    db_delete('cleantalk_cids')
      ->condition('cid', $comment->cid, '=')
      ->execute();
  }
}

/**
 * Implements hook_comment_delete().
 */
function cleantalk_comment_delete($comment) {
  $result = db_select('cleantalk_cids', 'c')
    ->fields('c', array(
    'ct_request_id',
    'ct_result_comment',
  ))
    ->condition('cid', $comment->cid, '=')
    ->range(0, 1)
    ->execute();
  if ($result
    ->rowCount() > 0) {
    $ct_result = $result
      ->fetchObject();

    // If ct_result_comment is empty then comment is approved by server.
    // But we delete it then comment is not approved by admin.
    // We need to send negative feedback.
    _cleantalk_send_feedback($ct_result->ct_request_id, 0);
    db_delete('cleantalk_cids')
      ->condition('cid', $comment->cid, '=')
      ->execute();
  }
}

/**
 * Implements hook_user_delete().
 */
function cleantalk_user_delete($account) {
  $result = db_select('cleantalk_uids', 'c')
    ->fields('c', array(
    'ct_request_id',
    'ct_result_comment',
  ))
    ->condition('uid', $account->uid, '=')
    ->range(0, 1)
    ->execute();
  if ($result
    ->rowCount() > 0) {
    $ct_result = $result
      ->fetchObject();

    // If ct_result_comment is empty then user is approved by server.
    // But we delete it then user is not approved by admin.
    // We need to send negative feedback.
    _cleantalk_send_feedback($ct_result->ct_request_id, 0);
    db_delete('cleantalk_uids')
      ->condition('uid', $account->uid, '=')
      ->execute();
  }
}

/**
 * Implements hook_comment_view_alter().
 */
function cleantalk_comment_view_alter(&$build) {
  if (user_access('administer comments')) {
    $result = db_select('cleantalk_cids', 'c')
      ->fields('c', array(
      'ct_request_id',
      'ct_result_comment',
    ))
      ->condition('cid', $build['#comment']->cid, '=')
      ->range(0, 1)
      ->execute();
    if ($result
      ->rowCount() > 0) {
      $ct_result = $result
        ->fetchObject();
      if (!empty($ct_result->ct_result_comment)) {

        // Value of ct_result_comment is sanitized already (before storing).
        $build['comment_body'][0]['#markup'] .= '<hr>' . $ct_result->ct_result_comment;
      }
    }
  }
}

/**
 * Implements hook_menu().
 */
function cleantalk_menu() {
  $items['admin/config/cleantalk'] = array(
    'title' => 'Antispam by CleanTalk',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'cleantalk_settings_form',
    ),
    'access arguments' => array(
      'administer site configuration',
    ),
    'file' => 'cleantalk.admin.inc',
  );
  return $items;
}

/**
 * Implements hook_mail().
 */
function cleantalk_mail($key, &$message, $params) {
  if (isset($params['subject'])) {
    $message['subject'] = $params['subject'];
  }
  if (isset($params['body'])) {
    $message['body'][] = $params['body'];
  }
  if (isset($params['headers']) && is_array($params['headers'])) {
    $message['headers'] += $params['headers'];
  }
}

/**
 * Implements hook_libraries_info().
 *
 * For defining external CleanTalk librariy.
 */

/*function cleantalk_libraries_info() {
  // Expected to be extracted into 'sites/all/libraries/cleantalk'.
  $libraries['cleantalk'] = array(
    'name' => 'CleanTalk PHP-antispam classes',
    'vendor url' => 'http://cleantalk.org',
    'download url' => 'https://github.com/CleanTalk/php-antispam',
    'version arguments' => array(
      'file' => 'cleantalk.class.php',
      'pattern' => '/@version\s+([0-9a-zA-Z\.-]+)/',
      'lines' => 10,
    ),
    'files' => array(
      'php' => array('cleantalk.class.php'),
    ),
  );
  return $libraries;
}*/

/**
 * Cleantalk inner function - gets working server.
 */
function _cleantalk_get_ws() {
  return array(
    'work_url' => variable_get('cleantalk_work_url', 'http://moderate.cleantalk.ru'),
    'server_url' => variable_get('cleantalk_server_url', 'http://moderate.cleantalk.ru'),
    'server_ttl' => variable_get('cleantalk_server_ttl', 0),
    'server_changed' => variable_get('cleantalk_server_changed', 0),
  );
}

/**
 * Cleantalk inner function - sets working server.
 */
function _cleantalk_set_ws($work_url = 'http://moderate.cleantalk.ru', $server_url = 'http://moderate.cleantalk.ru', $server_ttl = 0, $server_changed = 0) {
  variable_set('cleantalk_work_url', $work_url);
  variable_set('cleantalk_server_url', $server_url);
  variable_set('cleantalk_server_ttl', $server_ttl);
  variable_set('cleantalk_server_changed', $server_changed);
}

/**
 * Cleantalk inner function - sends feedback to server.
 */
function _cleantalk_send_feedback($request_id, $feedback) {
  $ct_authkey = variable_get('cleantalk_authkey', '');
  $ct_ws = _cleantalk_get_ws();
  $ct = new Cleantalk();
  $ct->work_url = $ct_ws['work_url'];
  $ct->server_url = $ct_ws['server_url'];
  $ct->server_ttl = $ct_ws['server_ttl'];
  $ct->server_changed = $ct_ws['server_changed'];
  $ct_request = new CleantalkRequest();
  $ct_request->auth_key = $ct_authkey;
  $ct_request->agent = 'drupal-209';
  $ct_request->sender_ip = ip_address();
  $ct_request->feedback = $request_id . ':' . $feedback;
  $ct
    ->sendFeedback($ct_request);
}

/**
 * Cleantalk inner function - alters needed form.
 */
function _cleantalk_form_alter(&$form, &$form_state, $form_id) {
  static $js_cookie_added = FALSE;

  /*if ($js_cookie_added) {
      return;
    }*/
  $ct_link = variable_get('cleantalk_link', 0);
  if ($ct_link != 0) {
    $form['terms_of_use'] = array(
      '#type' => 'item',
      '#markup' => t("<a href='https://cleantalk.org/drupal-anti-spam-module-wo-captcha'>Drupal spam</a> blocked by CleanTalk."),
      '#required' => FALSE,
    );
  }
  $js_cookie_added = TRUE;
  if ($form_id == 'user_register_form') {
    $session_time_key = 'ct_submit_register_time';
    $form['#validate'][] = 'cleantalk_validate_register';
  }
  else {
    $session_time_key = 'ct_submit_comment_time';
    if ($form_id == 'contact_site_form' || $form_id == 'contact_personal_form') {
      $form['#validate'][] = 'cleantalk_validate_contact_message';
    }
    else {
      $form['#validate'][] = 'cleantalk_validate_comment';
    }
  }
  $field_name = 'ct_checkjs';
  $ct_check_def = '0';
  if (!isset($_COOKIE[$field_name])) {
    setcookie($field_name, $ct_check_def, 0, '/');
  }
}

/**
 * Cleantalk inner function - gets JavaScript checking value.
 */
function _cleantalk_get_checkjs_value() {
  return md5(variable_get('cleantalk_authkey', '') . '+' . variable_get('site_mail', ini_get('sendmail_from')));
}

/**
 * Cleantalk inner function - performs antispam checking.
 */
function _cleantalk_check_spam($spam_check) {
  if (defined('CLEANTALK_SKIP')) {
    return false;
  }
  $ct_authkey = variable_get('cleantalk_authkey', '');
  $ct_ws = _cleantalk_get_ws();
  $checkjs = 0;
  if (!isset($_COOKIE['ct_checkjs'])) {
    $checkjs = NULL;
  }
  elseif ($_COOKIE['ct_checkjs'] == _cleantalk_get_checkjs_value()) {
    $checkjs = 1;
  }
  else {
    $checkjs = 0;
  }
  $user_agent = $_SERVER['HTTP_USER_AGENT'];
  $refferrer = $_SERVER['HTTP_REFERER'];
  $ct = new Cleantalk();
  $ct->work_url = $ct_ws['work_url'];
  $ct->server_url = $ct_ws['server_url'];
  $ct->server_ttl = $ct_ws['server_ttl'];
  $ct->server_changed = $ct_ws['server_changed'];
  $ct_options = array(
    'access_key' => $ct_authkey,
    'cleantalk_comments' => variable_get('cleantalk_comments', 3),
    'cleantalk_automod' => variable_get('cleantalk_automod', ''),
    'cleantalk_ccf' => variable_get('cleantalk_ccf', ''),
    'cleantalk_link' => variable_get('cleantalk_link', ''),
    'cleantalk_sfw' => variable_get('cleantalk_sfw', ''),
    'cleantalk_wf_silent' => variable_get('cleantalk_wf_silent', ''),
    'cleantalk_wf_nomail' => variable_get('cleantalk_wf_nomail', ''),
  );
  $sender_info = drupal_json_encode(array(
    'cms_lang' => 'en',
    'REFFERRER' => $refferrer,
    'post_url' => $refferrer,
    'USER_AGENT' => $user_agent,
    'ct_options' => drupal_json_encode($ct_options),
  ));
  $ct_request = new CleantalkRequest();
  $ct_request->auth_key = $ct_authkey;
  $ct_request->agent = 'drupal-209';
  $ct_request->response_lang = 'en';
  $ct_request->js_on = $checkjs;
  $ct_request->sender_info = $sender_info;
  $ct_request->sender_email = $spam_check['sender_email'];
  $ct_request->sender_nickname = $spam_check['sender_nickname'];
  $ct_request->sender_ip = ip_address();
  $ct_submit_time = NULL;

  //drupal_session_start();
  switch ($spam_check['type']) {
    case 'comment':
    case 'contact':
    case 'node':
    case 'webform':
      if (isset($_SESSION['ct_submit_comment_time'])) {
        $ct_submit_time = REQUEST_TIME - $_SESSION['ct_submit_comment_time'];
      }
      $timelabels_key = 'mail_error_comment';
      $ct_request->submit_time = $ct_submit_time;
      $ct_request->message = $spam_check['message_title'] . " \n\n" . $spam_check['message_body'];

      // Additional info.
      $post_info = '';
      if ($spam_check['type'] == 'contact') {
        $a_post_info['comment_type'] = 'contact';
      }
      else {
        if ($spam_check['type'] == 'node') {
          $a_post_info['comment_type'] = 'node';
        }
        else {
          if ($spam_check['type'] == 'webform') {
            $a_post_info['comment_type'] = 'webform';
          }
          else {
            $a_post_info['comment_type'] = 'comment';
          }
        }
      }

      // JSON format.
      $post_info = drupal_json_encode($a_post_info);

      // Plain text format.
      if ($post_info === FALSE) {
        $post_info = '';
      }
      $ct_request->post_info = $post_info;

      // Example is obsolete now.
      $ct_request->example = '';
      $ct_result = $ct
        ->isAllowMessage($ct_request);
      break;
    case 'register':
      if (isset($_SESSION['ct_submit_register_time'])) {
        $ct_submit_time = REQUEST_TIME - $_SESSION['ct_submit_register_time'];
      }
      $timelabels_key = 'mail_error_reg';
      $ct_request->submit_time = $ct_submit_time;
      $ct_request->tz = $spam_check['timezone'];

      // Set JS test enabled if REST API request
      if (arg(0) != 'user') {
        $ct_request->js_on = 1;
      }
      $ct_result = $ct
        ->isAllowUser($ct_request);
      break;
  }
  $ret_val = array();
  $ret_val['ct_request_id'] = $ct_result->id;
  if ($ct->server_change) {
    _cleantalk_set_ws($ct->work_url, $ct->server_url, $ct->server_ttl, REQUEST_TIME);
  }

  // First check errstr flag.
  if (!empty($ct_result->errstr) || !empty($ct_result->inactive) && $ct_result->inactive == 1) {

    // Cleantalk error so we go default way (no action at all).
    $ret_val['errno'] = 1;
    if ($checkjs == 0) {
      $ret_val['allow'] = 0;
    }

    // Just inform admin.
    $err_title = $_SERVER['SERVER_NAME'] . ' - CleanTalk hook error';
    if (!empty($ct_result->errstr)) {
      $ret_val['errstr'] = _cleantalk_filter_response($ct_result->errstr);
    }
    else {
      $ret_val['errstr'] = _cleantalk_filter_response($ct_result->comment);
    }
    $send_flag = FALSE;
    $result = db_select('cleantalk_timelabels', 'c')
      ->fields('c', array(
      'ct_value',
    ))
      ->condition('ct_key', $timelabels_key, '=')
      ->execute();
    if ($result
      ->rowCount() == 0) {
      $send_flag = TRUE;
    }
    elseif (REQUEST_TIME - 900 > $result
      ->fetchObject()->ct_value) {

      // 15 minutes.
      $send_flag = TRUE;
    }
    if ($send_flag) {
      db_merge('cleantalk_timelabels')
        ->key(array(
        'ct_key' => $timelabels_key,
      ))
        ->fields(array(
        'ct_value' => REQUEST_TIME,
      ))
        ->execute();
      $to = variable_get('site_mail', ini_get('sendmail_from'));
      if (!empty($to)) {
        drupal_mail("cleantalk", $timelabels_key, $to, language_default(), array(
          'subject' => $err_title,
          'body' => $ret_val['errstr'],
          'headers' => array(),
        ), $to, TRUE);
      }
    }
    return $ret_val;
  }
  $ret_val['errno'] = 0;
  if ($ct_result->allow == 1) {

    // Not spammer.
    $ret_val['allow'] = 1;

    // Store request_id in globals to store it in DB later.
    _cleantalk_ct_result('set', $ct_result->id);

    // Don't store 'ct_result_comment', means good comment.
  }
  else {

    // Spammer.
    $ret_val['allow'] = 0;
    $ret_val['ct_result_comment'] = _cleantalk_filter_response($ct_result->comment);

    // Check stop_queue flag.
    if ($spam_check['type'] == 'comment' && $ct_result->stop_queue == 0) {

      // Spammer and stop_queue == 0 - to manual approvement.
      $ret_val['stop_queue'] = 0;

      // Store request_id and comment in static to store them in DB later.
      // Store 'ct_result_comment' - means bad comment.
      _cleantalk_ct_result('set', $ct_result->id, $ret_val['ct_result_comment']);
    }
    else {

      // New user or Spammer and stop_queue == 1 - display form error message.
      $ret_val['stop_queue'] = 1;
    }
  }
  return $ret_val;
}

/**
 * Cleantalk inner function - performs CleanTalk comment|errstr filtering.
 */
function _cleantalk_filter_response($ct_response) {
  if (preg_match('//u', $ct_response)) {
    $err_str = preg_replace('/\\*\\*\\*/iu', '', $ct_response);
  }
  else {
    $err_str = preg_replace('/\\*\\*\\*/i', '', $ct_response);
  }
  return filter_xss($err_str, array(
    'a',
  ));
}

/**
 * Cleantalk inner function - stores spam checking result.
 */
function _cleantalk_ct_result($cmd = 'get', $id = '', $comment = '') {
  static $request_id = '';
  static $result_comment = '';
  if ($cmd == 'set') {
    $request_id = $id;
    $result_comment = $comment;
  }
  else {
    return array(
      'ct_request_id' => $request_id,
      'ct_result_comment' => $result_comment,
    );
  }
}

/**
 * Cleantalk inner function - show error message and exit.
 */
function _cleantalk_die($message) {
  print '<!DOCTYPE html><!-- Ticket #11289, IE bug fix: always pad the error page with enough characters such that it is greater than 512 bytes, even after gzip compression abcdefghijklmnopqrstuvwxyz1234567890aabbccddeeffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz11223344556677889900abacbcbdcdcededfefegfgfhghgihihjijikjkjlklkmlmlnmnmononpopoqpqprqrqsrsrtstsubcbcdcdedefefgfabcadefbghicjkldmnoepqrfstugvwxhyz1i234j567k890laabmbccnddeoeffpgghqhiirjjksklltmmnunoovppqwqrrxsstytuuzvvw0wxx1yyz2z113223434455666777889890091abc2def3ghi4jkl5mno6pqr7stu8vwx9yz11aab2bcc3dd4ee5ff6gg7hh8ii9j0jk1kl2lmm3nnoo4p5pq6qrr7ss8tt9uuvv0wwx1x2yyzz13aba4cbcb5dcdc6dedfef8egf9gfh0ghg1ihi2hji3jik4jkj5lkl6kml7mln8mnm9ono--><html xmlns="http://www.w3.org/1999/xhtml" lang="en-US"><head>    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />    <title>Blacklisted</title>    <style type="text/css">        html {            background: #f1f1f1;        }        body {            background: #fff;            color: #444;            font-family: "Open Sans", sans-serif;            margin: 2em auto;            padding: 1em 2em;            max-width: 700px;            -webkit-box-shadow: 0 1px 3px rgba(0,0,0,0.13);            box-shadow: 0 1px 3px rgba(0,0,0,0.13);        }        h1 {            border-bottom: 1px solid #dadada;            clear: both;            color: #666;            font: 24px "Open Sans", sans-serif;            margin: 30px 0 0 0;            padding: 0;            padding-bottom: 7px;        }        #error-page {            margin-top: 50px;        }        #error-page p {            font-size: 14px;            line-height: 1.5;            margin: 25px 0 20px;        }        a {            color: #21759B;            text-decoration: none;        }        a:hover {            color: #D54E21;        }            </style></head><body id="error-page">    <p><center><b style="color: #49C73B;">Clean</b><b style="color: #349ebf;">Talk.</b> Spam protection</center><br><br>' . $message . '<script>setTimeout("history.back()", 5000);</script></p><p><a href="javascript:history.back()">&laquo; Back</a></p></body></html>';
  drupal_exit();
}

/**
 * Inner function - Finds and returns pattern in string
 * @return null|bool
 */
function cleantalk_get_data_from_submit($value = null, $field_name = null) {
  if (!$value || !$field_name || !is_string($value)) {
    return false;
  }
  if (preg_match("/[a-z0-9_\\-]*" . $field_name . "[a-z0-9_\\-]*\$/", $value)) {
    return true;
  }
}

/**
* gets data for checking recursively
*/
function cleantalk_get_fields_any(&$email, &$message, &$nickname, &$subject, $arr) {
  foreach ($arr as $key => $value) {
    if (!is_array($value) && !is_object($value)) {
      if ($email === '' && @preg_match("/^\\S+@\\S+\\.\\S+\$/", $value)) {
        $email = $value;
      }
      else {
        if ($nickname === '' && cleantalk_get_data_from_submit($value, 'name')) {
          $nickname = $value;
        }
        else {
          if ($subject === '' && cleantalk_get_data_from_submit($value, 'subject')) {
            $subject = $value;
          }
          else {
            @($message .= "{$value}\n");
          }
        }
      }
    }
    else {
      if (!is_object($value)) {
        cleantalk_get_fields_any($email, $message, $nickname, $subject, $value);
      }
    }
  }
}

/**
 * Implements hook_init()
 */
function cleantalk_init() {
  $ct_authkey = variable_get('cleantalk_authkey', '');
  if ($ct_authkey != '') {
    $ct_ccf = variable_get('cleantalk_ccf', 0);
    if (sizeof($_POST) > 0 && !isset($_POST['form_build_id']) && !isset($_POST['form_id']) && $ct_ccf == 1) {

      //Custom Contact forms
      $sender_email = '';
      $sender_nickname = '';
      $subject = '';
      $message = '';
      $contact_form = true;
      get_fields_any($sender_email, $message, $sender_nickname, $subject, $contact_form, $_POST);
      if ($sender_email != '') {
        if (!isset($_COOKIE['ct_checkjs'])) {
          $checkjs = NULL;
        }
        elseif ($_COOKIE['ct_checkjs'] == _cleantalk_get_checkjs_value()) {
          $checkjs = 1;
        }
        else {
          $checkjs = 0;
        }
        $data = array(
          'type' => 'comment',
          'auth_key' => $ct_authkey,
          'method_name' => 'check_message',
          'message' => $message,
          'example' => null,
          'agent' => 'drupal-209',
          'sender_ip' => $_SERVER['REMOTE_ADDR'],
          'sender_email' => $sender_email,
          'sender_nickname' => $sender_nickname,
          'message_title' => $subject,
          'message_body' => '',
          'example_title' => '',
          'example_body' => '',
          'example_comments' => '',
          'comment_body' => '',
          'js_on' => $checkjs,
        );
        if (!function_exists('drupal_json_encode')) {
          include_once DRUPAL_ROOT . '/includes/common.inc';
        }
        $result = _cleantalk_check_spam($data);
        if ($result['allow'] === 0) {
          drupal_set_message($result['ct_result_comment'], 'error');
        }
      }
    }
    if (isset($_POST['mergevars'])) {
      $sender_email = null;
      $message = '';
      foreach ($_POST['mergevars'] as $key => $value) {
        if ($sender_email === null && preg_match("/^\\S+@\\S+\\.\\S+\$/", $value)) {
          $sender_email = $value;
        }
        else {
          $message .= "{$value}\n";
        }
      }
      if ($sender_email != null) {
        $url = 'http://moderate.cleantalk.org/api2.0';
        $ct_authkey = variable_get('cleantalk_authkey', '');
        if (!isset($_COOKIE['ct_checkjs'])) {
          $checkjs = NULL;
        }
        elseif ($_COOKIE['ct_checkjs'] == _cleantalk_get_checkjs_value()) {
          $checkjs = 1;
        }
        else {
          $checkjs = 0;
        }
        $data = array(
          'type' => 'comment',
          'auth_key' => $ct_authkey,
          'method_name' => 'check_message',
          'message' => $message,
          'example' => null,
          'agent' => 'drupal-209',
          'sender_ip' => $_SERVER['REMOTE_ADDR'],
          'sender_email' => $sender_email,
          'sender_nickname' => '',
          'message_title' => '',
          'message_body' => '',
          'example_title' => '',
          'example_body' => '',
          'example_comments' => '',
          'comment_body' => '',
          'js_on' => $checkjs,
        );
        if (!function_exists('drupal_json_encode')) {
          include_once DRUPAL_ROOT . '/includes/common.inc';
        }
        $result = _cleantalk_check_spam($data);
        if ($result['allow'] === 0) {
          drupal_set_message($result['ct_result_comment'], 'error');
          $_POST['mergevars']['EMAIL'] = '';
        }
      }
    }
  }
  if (path_is_admin(current_path())) {
    if (isset($_POST['cleantalk_authkey'])) {
      $url = 'http://moderate.cleantalk.org/api2.0';
      $dt = array(
        'auth_key' => $_POST['cleantalk_authkey'],
        'method_name' => 'send_feedback',
        'feedback' => 0 . ':' . 'drupal-209',
      );
      sendRawRequest($url, $dt, true);
    }
    if (isset($_POST['cleantalk_authkey']) && isset($_POST['cleantalk_sfw']) && $_POST['cleantalk_sfw'] == 1) {
      CleanTalkSFW::sfw_update($_POST['cleantalk_authkey']);
      CleanTalkSFW::send_logs($_POST['cleantalk_authkey']);
    }
  }
}

/**
 * Implements hook_boot()
 */
function cleantalk_boot() {
  $is_sfw = variable_get('cleantalk_sfw', 0);
  if ($is_sfw == 1) {
    $ct_key = variable_get('cleantalk_authkey', '');
    if ($ct_key != '') {
      $ct_sfw_last_logs_sent = variable_get('ct_sfw_last_logs_sent', null);
      if ($ct_sfw_last_logs_sent && time() - $ct_sfw_last_logs_sent > 3600) {
        CleanTalkSFW::send_logs($ct_key);
      }
      $ct_sfw_last_updated = variable_get('ct_sfw_last_updated', null);
      if ($ct_sfw_last_updated && time() - $ct_sfw_last_updated > 86400) {
        CleanTalkSFW::sfw_update($ct_key);
      }
      $is_sfw_check = true;
      $ip = CleantalkGetIP();
      $ip = array_unique($ip);
      foreach ($ip as $key => $value) {
        if (isset($_COOKIE['ct_sfw_pass_key']) && $_COOKIE['ct_sfw_pass_key'] == md5($value . $ct_key)) {
          $is_sfw_check = false;
          if (isset($_COOKIE['ct_sfw_passed'])) {
            @setcookie('ct_sfw_passed');

            //Deleting cookie
            CleanTalkSFW::sfw_update_logs($value, 'passed');
          }
        }
      }
      unset($key, $value);
      if ($is_sfw_check) {
        $sfw = new CleanTalkSFW();
        $sfw
          ->cleantalk_get_real_ip();
        $sfw
          ->check_ip();
        if ($sfw->result) {
          CleanTalkSFW::sfw_update_logs($sfw->blocked_ip, 'blocked');
          $sfw
            ->sfw_die();
        }
      }
    }
  }
}

/**
 * Implements hook_webform_submission_presave()
 */
function cleantalk_webform_submission_presave(&$node, &$submission) {
  global $user;

  // Don't check reged user with >= 'cleantalk_comments' approved msgs.
  if ($user->uid > 0) {

    # Don't check admin activity
    if (isset($user->roles) && is_array($user->roles)) {
      if (in_array('administrator', $user->roles)) {
        return;
      }
    }
    $result = db_query('SELECT count(*) AS count FROM {comment} WHERE uid=:uid AND status=1', array(
      ':uid' => $user->uid,
    ));
    $count = intval($result
      ->fetchObject()->count);
    $ct_comments = variable_get('cleantalk_comments', 3);
    if ($count >= $ct_comments) {
      return;
    }
  }
  $sender_email = null;
  $message = '';
  $messagify = function ($array) use (&$messagify, &$sender_email, &$message) {
    foreach ($array as $key => $value) {
      if (is_array($value)) {
        $messagify($value);
      }
      else {
        if ($sender_email === null && preg_match("/^\\S+@\\S+\\.\\S+\$/", $value)) {
          $sender_email = $value;
        }
        else {
          $message .= "{$value}\n";
        }
      }
    }
  };
  $messagify($_POST['submitted']);
  $spam_check = array();
  $spam_check['type'] = 'webform';
  $spam_check['sender_email'] = !empty($sender_email) ? $sender_email : '';
  $spam_check['sender_nickname'] = '';
  $spam_check['message_title'] = '';
  $spam_check['message_body'] = $message;
  $spam_check['example_title'] = '';
  $spam_check['example_body'] = '';
  $spam_check['example_comments'] = '';
  $spam_result = _cleantalk_check_spam($spam_check);
  if (isset($spam_result) && is_array($spam_result) && $spam_result['errno'] == 0 && $spam_result['allow'] != 1) {
    $ct_automod = variable_get('cleantalk_automod', 1);
    if ($ct_automod == 1) {
      $submission->is_draft = 1;
      if (variable_get('cleantalk_wf_nomail', 1) == 1) {
        $node->webform['emails'] = array();
      }
      if (variable_get('cleantalk_wf_silent', 1) != 1) {
        drupal_set_message($spam_result['ct_result_comment'], 'error');
      }
    }
  }
}

/*
* implemments hook_uc_order - UberCart hook for order processing
*/
function cleantalk_uc_order($op, $order, $arg2) {
  global $cleantalk_executed;
  $email = '';
  $message = '';
  $nickname = '';
  $subject = '';
  cleantalk_get_fields_any($email, $message, $nickname, $subject, $_POST);
  if ($email != '' && !$cleantalk_executed && $op != 'total' && $op != 'presave' && $op != 'save') {
    $spam_check = array();
    $spam_check['type'] = 'comment';
    $spam_check['sender_email'] = $email;
    $spam_check['sender_nickname'] = $nickname;
    $spam_check['message_title'] = $subject;
    $spam_check['message_body'] = $message;
    $spam_check['example_title'] = '';
    $spam_check['example_body'] = '';
    $spam_check['example_comments'] = '';
    $spam_result = _cleantalk_check_spam($spam_check);
    $cleantalk_executed = true;
    if (isset($spam_result) && is_array($spam_result) && $spam_result['errno'] == 0 && $spam_result['allow'] != 1 && $spam_result['stop_queue'] == 1) {
      if (strpos($_SERVER['REQUEST_URI'], 'ajax') !== false) {
        print $spam_result['ct_result_comment'];
        drupal_exit();
      }
      else {
        _cleantalk_die($spam_result['ct_result_comment']);
      }
    }
  }
}

/**
 * Inner function - Finds and returns pattern in string
 * @return null|bool
 */
function get_data_from_submit($value = null, $field_name = null) {
  if (!$value || !$field_name || !is_string($value)) {
    return false;
  }
  if (preg_match("/[a-z0-9_\\-]*" . $field_name . "[a-z0-9_\\-]*\$/", $value)) {
    return true;
  }
}

/*
* Get data from submit recursively
*/
function get_fields_any(&$email, &$message, &$nickname, &$subject, &$contact, $arr) {
  $skip_params = array(
    'ipn_track_id',
    // PayPal IPN #
    'txn_type',
    // PayPal transaction type
    'payment_status',
  );
  foreach ($arr as $key => $value) {
    if (!is_array($value) && !is_object($value)) {
      if (in_array($key, $skip_params) && $key != 0 && $key != '' || preg_match("/^ct_checkjs/", $key)) {
        $contact = false;
      }
      if ($email === '' && preg_match("/^\\S+@\\S+\\.\\S+\$/", $value)) {
        $email = $value;
      }
      else {
        if ($nickname === '' && get_data_from_submit($value, 'name')) {
          $nickname = $value;
        }
        else {
          if ($subject === '' && get_data_from_submit($value, 'subject')) {
            $subject = $value;
          }
          else {
            $message .= "{$value}\n";
          }
        }
      }
    }
    else {
      get_fields_any($email, $message, $nickname, $subject, $contact, $value);
    }
  }
}
function CleantalkGetIP() {
  $result = array();
  if (function_exists('apache_request_headers')) {
    $headers = apache_request_headers();
  }
  else {
    $headers = $_SERVER;
  }
  if (array_key_exists('X-Forwarded-For', $headers)) {
    $the_ip = explode(",", trim($headers['X-Forwarded-For']));
    $result[] = trim($the_ip[0]);
  }
  if (array_key_exists('HTTP_X_FORWARDED_FOR', $headers)) {
    $the_ip = explode(",", trim($headers['HTTP_X_FORWARDED_FOR']));
    $result[] = trim($the_ip[0]);
  }
  $result[] = filter_var($_SERVER['REMOTE_ADDR'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4);
  if (isset($_GET['sfw_test_ip'])) {
    $result[] = $_GET['sfw_test_ip'];
  }
  return $result;
}

/**
 * Implements hook_form_FORM_ID_alter().
 */
function cleantalk_form_user_filter_form_alter(&$form, &$form_state, $form_id) {
  $ct_authkey = variable_get('cleantalk_authkey', '');
  if (!empty($ct_authkey)) {
    $form['actions']['find_spammers'] = array(
      '#type' => 'submit',
      '#value' => t('Check for spammers'),
      '#submit' => array(
        'cleantalk_find_spammers',
      ),
    );
  }
}

/**
 * Process submit of 'Check for spammers' button on user_filter_form.
 */
function cleantalk_find_spammers(&$form, &$form_state) {
  $ct_authkey = variable_get('cleantalk_authkey', '');
  if (empty($ct_authkey)) {
    return;
  }
  $op = $form_state['values']['op'];
  switch ($op) {
    case t('Check for spammers'):

      // Load spammer role
      $spammer_role_name = 'spammer';
      $spammer_role = user_role_load_by_name($spammer_role_name);
      if ($spammer_role !== FALSE && is_object($spammer_role) && isset($spammer_role->rid)) {
        $is_spammer_defined = FALSE;
        if (isset($_SESSION['user_overview_filter']) && is_array($_SESSION['user_overview_filter'])) {
          foreach ($_SESSION['user_overview_filter'] as $filter) {
            if (is_array($filter) && isset($filter[0]) && $filter[0] == 'role' && isset($filter[1]) && $filter[1] == $spammer_role->rid) {
              $is_spammer_defined = TRUE;
            }
          }
        }
        if (!$is_spammer_defined) {
          $_SESSION['user_overview_filter'][] = array(
            'role',
            $spammer_role->rid,
          );
        }

        // Get all accounts
        $accounts = user_load_multiple(FALSE);

        // Fill data for spam check
        $data = array();
        foreach ($accounts as $account) {

          // Skip adding the role to the user if they already have it.
          if ($account !== FALSE && !isset($account->roles[$spammer_role->rid]) && isset($account->mail)) {
            array_push($data, $account->mail);
          }
        }
        $data = implode(',', $data);
        $request = array();
        $request['method_name'] = 'spam_check';
        $request['auth_key'] = $ct_authkey;
        $request['data'] = $data;
        $url = 'https://api.cleantalk.org';
        $result = sendRawRequest($url, $request);
        $result = json_decode($result);
        if (isset($result->error_message)) {
          drupal_set_message($result->error_message, 'error');
        }
        else {

          // Add roles for spam accounts
          foreach ($accounts as $account) {

            // Skip adding the role to the user if they already have it.
            if ($account !== FALSE && !isset($account->roles[$spammer_role->rid]) && isset($account->mail)) {
              $uim = $account->mail;
              if (isset($result->data->{$uim}) && $result->data->{$uim}->appears == 1) {
                $roles = $account->roles + array(
                  $spammer_role->rid => $spammer_role_name,
                );

                // For efficiency manually save the original account before applying
                // any changes.
                $account->original = clone $account;
                user_save($account, array(
                  'roles' => $roles,
                ));
              }
            }
          }
        }
      }
      break;
  }
}

Functions

Namesort descending Description
CleantalkGetIP
cleantalk_boot Implements hook_boot()
cleantalk_comment_delete Implements hook_comment_delete().
cleantalk_comment_insert Implements hook_comment_insert().
cleantalk_comment_presave Implements hook_comment_presave().
cleantalk_comment_publish Implements hook_comment_publish().
cleantalk_comment_view_alter Implements hook_comment_view_alter().
cleantalk_find_spammers Process submit of 'Check for spammers' button on user_filter_form.
cleantalk_form_comment_form_alter Implements hook_form_BASE_FORM_ID_alter().
cleantalk_form_comment_node_webform_form_alter Implements hook_form_BASE_FORM_ID_alter()
cleantalk_form_contact_personal_form_alter Implements hook_form_FORM_ID_alter().
cleantalk_form_contact_site_form_alter Implements hook_form_FORM_ID_alter().
cleantalk_form_mailchimp_signup_subscribe_form_alter Implements hook_form_BASE_FORM_ID_alter()
cleantalk_form_node_form_alter Implements hook_form_BASE_FORM_ID_alter().
cleantalk_form_user_filter_form_alter Implements hook_form_FORM_ID_alter().
cleantalk_form_user_register_form_alter Implements hook_form_FORM_ID_alter().
cleantalk_get_data_from_submit Inner function - Finds and returns pattern in string
cleantalk_get_fields_any gets data for checking recursively
cleantalk_get_real_ip
cleantalk_init Implements hook_init()
cleantalk_mail Implements hook_mail().
cleantalk_menu Implements hook_menu().
cleantalk_node_presave
cleantalk_page_build
cleantalk_uc_order
cleantalk_user_delete Implements hook_user_delete().
cleantalk_user_insert Implements hook_user_insert().
cleantalk_user_presave Implements hook_user_presave().
cleantalk_validate_comment Cleantalk comment validation function.
cleantalk_validate_contact_message Cleantalk contact message validation function.
cleantalk_validate_register Cleantalk registration validation function.
cleantalk_webform_submission_presave Implements hook_webform_submission_presave()
getAutoKey Function gets access key automatically
get_data_from_submit Inner function - Finds and returns pattern in string
get_fields_any
noticePaidTill Function gets information about renew notice
sendRawRequest Function sends raw request to API server
_cleantalk_check_spam Cleantalk inner function - performs antispam checking.
_cleantalk_ct_result Cleantalk inner function - stores spam checking result.
_cleantalk_die Cleantalk inner function - show error message and exit.
_cleantalk_filter_response Cleantalk inner function - performs CleanTalk comment|errstr filtering.
_cleantalk_form_alter Cleantalk inner function - alters needed form.
_cleantalk_get_checkjs_value Cleantalk inner function - gets JavaScript checking value.
_cleantalk_get_ws Cleantalk inner function - gets working server.
_cleantalk_send_feedback Cleantalk inner function - sends feedback to server.
_cleantalk_set_ws Cleantalk inner function - sets working server.

Classes

Namesort descending Description
Cleantalk Cleantalk class create request
CleantalkRequest Request class
CleantalkResponse Response class
CleanTalkSFW Cleantalk Spam FireWall class