<?php
// $Id: false_account.module,v 1.11.4.2 2009/01/07 14:52:33 nunoveloso18 Exp $

/**
 * @file
 * Use this module to detect false accounts on your site
 */

define('FALSE_ACCOUNT_DEFAULT', 0);
define('FALSE_ACCOUNT_WHITELISTED', 1);
define('FALSE_ACCOUNT_BLOCKED', 2);


/**
 * Implementation of hook_user().
 */
function false_account_user($op, &$edit, &$account, $category = NULL) {
  switch ($op) {
    case 'insert':
      if (isset($_COOKIE['fad'])) {
        $cdata = explode(',', $_COOKIE['fad']);
        $cid = $cdata[0];
        $count = db_result(db_query("
          SELECT COUNT(cid) 
          FROM {false_accounts} 
          WHERE cid = '%s' and status = '%d'", 
          $cid, FALSE_ACCOUNT_BLOCKED
        ));
        if ($count) {
          watchdog('false account', 'Blocked: %cid',  array('%cid' => $cid), WATCHDOG_NOTICE);
          drupal_goto(variable_get('false_account_redirect', '<front>'));
        }
      }
      break;
    case 'login':
      if (!isset($_COOKIE['fad'])) {
        $uniqueid = md5('gsmi789'. uniqid(rand(), TRUE));
        setcookie('fad', $uniqueid .','. $account->uid, time() + 31536000, "/");
      } 
      else{
        $cdata = explode(',', $_COOKIE['fad']);
        $cid = $cdata[0];
        if (in_array($account->uid, $cdata)) {
          break;
        }
        else{
          $new_cdata = $_COOKIE['fad'] .','. $account->uid;
          setcookie('fad', $new_cdata, time() + 31536000, "/" );
          if (sizeof($cdata) >= 2) {
            db_query("
              DELETE FROM {false_accounts}
              WHERE cid = '%s'", 
              $cid
            );

            $i = 1;
            $time = time();
            while ($i < sizeof($cdata)) {
              db_query("
                INSERT INTO {false_accounts} (cid, uid, created, status) 
                VALUES ('%s', %d, %d, %d)", 
                $cid, $cdata[$i++] , $time, FALSE_ACCOUNT_DEFAULT
              );
            }
            db_query("
              INSERT INTO {false_accounts} (cid, uid, created, status) 
              VALUES ('%s', %d, %d, %d)", 
              $cid, $account->uid , $time, FALSE_ACCOUNT_DEFAULT
            );
          }
        }
      }
      break;
    case 'view':
      if (user_access('manage false account detector')) {
        $res = db_query('
          SELECT cid 
          FROM {false_accounts} 
          WHERE uid = %d', 
          $account->uid
        );

        $num_rows = db_result(db_query('
          SELECT COUNT(cid) 
          FROM {false_accounts} 
          WHERE uid = %d', 
          $account->uid
        ));
        
        if ($num_rows > 0) {
          while ($res_cid = db_fetch_object($res)) {
            $ors[] = "cid = '". $res_cid->cid ."'";
          }
          $or = implode(' OR ', $ors);
          $sql = "SELECT * FROM {false_accounts} WHERE " . $or;
    
          $header = array(
            array('data' => t('User Accounts')),
            array('data' => t('Created'), 'field' => 'created', 'sort' => 'desc'),
          );
          $result= pager_query($sql . tablesort_sql($header), 50, 0, NULL);
          $rows = array();
          
          $cookies = array();
        
          while ($cookie = db_fetch_object($result)) {
            if (array_key_exists($cookie->cid, $cookies)) {
              array_push($cookies[$cookie->cid]['users'], $cookie->uid);
            }
            else {
              $cookies[$cookie->cid] = array();
              $cookies[$cookie->cid]['users'] = array();
              array_push($cookies[$cookie->cid]['users'], $cookie->uid);
              $cookies[$cookie->cid]['created'] = $cookie->created;
            }
          }
        
          $account->content['fad'] = array(
            '#type' => 'user_profile_category',
            '#title' => t('False Account'),
            'table' => array(
              '#type' => 'user_profile_item',
              '#value' => _false_account_build_user_table($header, $cookies, $account->uid)),
            '#weight' => -10
          );
        }
        else {
          $account->content['fad'] = array(
            '#type' => 'user_profile_category',
            '#title' => t('False Account'),
            'table' => array(
              '#type' => 'user_profile_item',
              '#title' => t('No false accounts detected.')),
            '#weight' => -10
          );
        }
      }
      break;
  }
}


/**
 * Implementation of hook_menu().
 */
function false_account_menu() {
  $access = array('manage false account detector');

  $items['false_account'] = array(
    'title' => 'False Account Detector',
    'title callback' => 't',
    'page callback' => 'false_account_page',
    'page arguments' => array('FALSE_ACCOUNT_DEFAULT'),
    'access arguments' => $access,
    'weight' => 0,
    'type' => MENU_CALLBACK
  );
  $items['admin/user/false_account'] = array(
    'title' => 'False Account Detector',
    'title callback' => 't',
    'page callback' => 'false_account_page',
    'page arguments' => array('FALSE_ACCOUNT_DEFAULT'),
    'access arguments' => $access,
    'weight' => 0
  );
  $items['admin/user/false_account/default'] = array(
    'title' => 'Default',
    'title callback' => 't',
    'page callback' => 'false_account_page',
    'page arguments' => array('FALSE_ACCOUNT_DEFAULT'),
    'access arguments' => $access,
    'type' => MENU_DEFAULT_LOCAL_TASK,
    'weight' => 0
  );
  $items['admin/user/false_account/whitelisted'] = array(
    'title' => 'Whitelisted',
    'title callback' => 't',
    'page callback' => 'false_account_page',
    'page arguments' => array('FALSE_ACCOUNT_WHITELISTED'),
    'access arguments' => $access,
    'type' => MENU_LOCAL_TASK,
    'weight' => 1
  );
  $items['admin/user/false_account/blocked'] = array(
    'title' => 'Blocked',
    'title callback' => 't',
    'page callback' => 'false_account_page',
    'page arguments' => array('FALSE_ACCOUNT_BLOCKED'),
    'access arguments' => $access,
    'type' => MENU_LOCAL_TASK,
    'weight' => 1
    );
  $items['admin/user/false_account/settings'] = array(
    'title' => 'Settings',
    'title callback' => 't',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('false_account_settings'),
    'access arguments' => $access,
    'type' => MENU_LOCAL_TASK,
    'weight' => 2
  );
    $items['admin/user/false_account/search'] = array(
    'title' => 'Search',
    'title callback' => 't',    
    'page callback' => 'false_account_searchfa',
    'access arguments' => $access,
    'type' => MENU_LOCAL_TASK,
    'weight' => 2
  );
  $items['admin/user/false_account/op'] = array(
    'page callback' => 'false_account_operations',
    'access arguments' => $access,
    'type' => MENU_CALLBACK
  );

  return $items;
}


/**
 * Implementation of hook_perm().
 */
function false_account_perm() {
  return array('manage false account detector');
}


/**
* Define the settings form.
*/
function false_account_settings() {  
  $form['false_account_redirect'] = array(
    '#type' => 'textfield',
    '#title' => t('Redirect blocked users'),
    '#default_value' =>  variable_get('false_account_redirect', '<front>'),
    '#description' => t('Indicate the Drupal internal URL to redirect to or insert an external URL.'),
  );

  return system_settings_form($form);
}



function false_account_page($op = 'FALSE_ACCOUNT_DEFAULT') {

  switch ($op) {
    case 'FALSE_ACCOUNT_DEFAULT':
      $op = 0;
      break;
    case 'FALSE_ACCOUNT_WHITELISTED':
      $op = 1;
      break;
    case 'FALSE_ACCOUNT_BLOCKED':
      $op = 2;
      break;
  }
  
  $content = t('<p>User accounts marked with an * are blocked</p>');
  $sql = 'SELECT * FROM {false_accounts} WHERE status = '. $op ;
  $header = array(
    array('data' => t('Cookie ID')),
    array('data' => t('User Accounts')),
    array('data' => t('Created'), 'field' => 'created', 'sort' => 'desc'),
    array('data' => t('Actions'))
  );
  $result = pager_query($sql . tablesort_sql($header), 50);
  $rows = array();

  $cookies = array();

  while ($cookie = db_fetch_object($result)) {
    if (array_key_exists($cookie->cid, $cookies)) {
      array_push($cookies[$cookie->cid]['users'], $cookie->uid);
    }
    else {
      $cookies[$cookie->cid] = array();
      $cookies[$cookie->cid]['users'] = array();
      array_push($cookies[$cookie->cid]['users'], $cookie->uid);
      $cookies[$cookie->cid]['status'] = $cookie->status;
      $cookies[$cookie->cid]['created'] = $cookie->created;
    }
  }
  
  $content .= _false_account_build_table($header, $cookies, $op);
  
 return $content;
}

function false_account_operations($op, $cid) {
  $sql = "UPDATE {false_accounts} SET status ='%d' WHERE cid = '%s'";
  db_query($sql, $op, $cid);
  drupal_goto('admin/user/false_account');  
}

function false_account_searchfa($account = NULL) {
  $content = t('<p>Search false accounts for one specific user.</p>');
  $content .= drupal_get_form('false_account_searchfa_form');
  if ($account) {
    $accountname = user_load(array('uid' => $account));
    $content .= '<p>'. t('<strong>User Name: </strong>') . $accountname->name .'<br/>';
    $content .= t('<strong>User ID: </strong>') . $accountname->uid .'</p>';
    $res = db_query('SELECT cid FROM {false_accounts} WHERE uid = %d', $accountname->uid);
    while ($res_cid = db_fetch_object($res)) {
      $ors[] = 'cid = "'. $res_cid->cid .'"';
    }
    $or = implode(' OR ', $ors);
    $sql = "SELECT * FROM {false_accounts} WHERE " . $or;
    $header = array(
      array('data' => t('Cookie ID')),
      array('data' => t('User Accounts')),
      array('data' => t('Created'), 'field' => 'created', 'sort' => 'desc'),
      array('data' => t('Actions'))
    );
    $result= pager_query($sql . tablesort_sql($header), 50, 0, NULL);
    $rows = array();
    
    $cookies = array();
  
    while ($cookie = db_fetch_object($result)) {
      if (array_key_exists($cookie->cid, $cookies)) {
        array_push($cookies[$cookie->cid]['users'], $cookie->uid);
      }
      else {
        $cookies[$cookie->cid] = array();
        $cookies[$cookie->cid]['users'] = array();
        array_push($cookies[$cookie->cid]['users'], $cookie->uid);
        $cookies[$cookie->cid]['status'] = $cookie->status;
        $cookies[$cookie->cid]['created'] = $cookie->created;
      }
    }

    $content .= _false_account_build_table($header, $cookies, $op);
  }
  return $content;
}


function false_account_searchfa_form() {
  $form['username'] = array(
    '#type' => 'textfield',
    '#description' => t('Enter username'),
    '#autocomplete_path' => 'user/autocomplete',
    '#maxlength' => USERNAME_MAX_LENGTH,
    '#size' => 16,
  );
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Search'),
  );
  return $form;

}

function false_account_searchfa_form_validate($form, &$form_state) {
  if (!$account = user_load(array('name' => $form_state['values']['username']))) {
    form_set_error('username', t('Username not found'));
  }
}

function false_account_searchfa_form_submit($form, &$form_state) {
  $account = user_load(array('name' => $form_state['values']['username']));
  $form_state['redirect'] = 'admin/user/false_account/search/'. $account->uid;
}


function _false_account_build_table($header, $cookies, $op) {

  foreach ($cookies as $cid => $cookie) {
    // user handling
    foreach ($cookie['users'] as $user) {
      $uid = trim($user);
      $status = db_result(db_query('SELECT status FROM {users} WHERE uid = %d', $uid));
      $account[] = l(($status->status == 0) ? $uid .'*' : $uid, 'user/'. $uid);
    }
    $accounts = implode(', ', $account);

    // actions handling
    switch ($op) {
      case FALSE_ACCOUNT_DEFAULT:
        $actions = l(t('whitelist'), 'admin/user/false_account/op/'. FALSE_ACCOUNT_WHITELISTED .'/'. $cid) .' | '. l(t('block'), 'admin/user/false_account/op/'. FALSE_ACCOUNT_BLOCKED .'/'. $cid);
        break;
      case FALSE_ACCOUNT_WHITELISTED:
        $actions = l(t('default'), 'admin/user/false_account/op/'. FALSE_ACCOUNT_DEFAULT .'/'. $cid) .' | '. l(t('block'), 'admin/user/false_account/op/'. FALSE_ACCOUNT_BLOCKED .'/'. $cid);
        break;
      case FALSE_ACCOUNT_BLOCKED:
        $actions = l(t('default'), 'admin/user/false_account/op/'. FALSE_ACCOUNT_DEFAULT .'/'. $cid) .' | '. l(t('whitelist'), 'admin/user/false_account/op/'. FALSE_ACCOUNT_WHITELISTED .'/'. $cid);
      break;
    }

    $rows[] = array(
      $cid,
      $accounts,
      date('d-m-Y', $cookie['created']),
      $actions
      );
    unset($account);
  }
  if ($rows) {
    $table .= theme('table', $header, $rows);
    $table .= theme('pager');
  }
  else{
    $table = t('No false accounts detected.');
  }

  return $table;
}


function _false_account_build_user_table($header, $cookies, $userid) {

  foreach ($cookies as $cid => $cookie) {
    // user handling
    foreach ($cookie['users'] as $user) {
      $uid = trim($user);
      $status = db_fetch_object(db_query('SELECT status, name FROM {users} WHERE uid = %d', $uid));
      if ($userid == $uid) {
        $account[] = ($status->status == 0) ? $status->name .'*' : $status->name;
      }
      else {
        $account[] = l(($status->status == 0) ? $status->name .'*' : $status->name, 'user/'. $uid);
      }
    }
    $accounts = implode(', ', $account);

    $rows[] = array(
      $accounts,
      date('d-m-Y', $cookie['created']),
      );
    unset($account);
  }
  if ($rows) {
    $table .= theme('table', $header, $rows);
    $table .= theme('pager');
  }
  else{
    $table = t('No false accounts detected.');
  }

  return $table;
}
