<?php
// \$Id\$

/**
 * @file
 * Cave module.
 * Hide users posts from everyone but themselves.
 *
 */

/**
 * Implementation of hook_perm().
 */
function cave_perm() {
  return array(
    'administer cave',
  );
}

/**
 * Implementation of hook_menu().
 */
/*

This is commented out because the page 'cave_admin_form' is not yet in use.

function cave_menu() {
  $items = array();
  $items['admin/user/cave'] = array(
    'title' => 'Cave your trolls',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('cave_admin_form'),
    'access arguments' => array('administer cave'),
    'type' => MENU_NORMAL_ITEM,
    'description' => t('Configure how cave works.'),
  );
  return $items;
}
*/

/**
 * Implementation of hook_user().
 */
function cave_user($op, &$edit, &$account, $category = NULL) {
  if (user_access('administer cave') && $category == 'account') {
    if ($op == 'form') {
      $form['cave'] = array(
        '#type' => 'fieldset',
        '#title' => t('Cave'),
      );
      $form['cave']['cave'] = array(
        '#type' => 'checkbox',
        '#title' => t('Cave'),
        '#default_value' => $edit['cave'],
        '#description' => t('Cave this user.'),
      );
      return $form;
    }
    elseif ($op == 'update' || $op == 'insert') {
      if ($edit['cave']) {
        cave_caved_users($account->uid, 'add');
      }
      else {
        cave_caved_users($account->uid, 'remove');
      }
    }
  }
}

/**
 * Form builder function for cave admin form.
 */
function cave_admin_form($form_state) {
  $form = array();
  drupal_set_message("No config options enabled yet");
  return system_settings_form($form);
}

/**
 * Implementation of hook_form_FORM-ID_alter().
 */
function cave_form_troll_blacklist_punishment_form_alter(&$form, $form_state) {
  $form['cave'] = array(
    '#type' => 'checkbox',
    '#title' => t('Cave'),
    '#default_value' => variable_get('cave_troll_blacklist', 0),
    '#description' => t('Blacklisted users will have their posts caved, and therefore be visible to only themselves.'),
  );
  $form['#submit'] = is_array($form['#submit']) ? $form['#submit'] : array();
  array_unshift($form['#submit'], 'cave_troll_blacklist_punishment_form_submit');
}

/**
 * Submit function for admin finder add form.
 */
function cave_troll_blacklist_punishment_form_submit($form, &$form_state) {
  variable_set('cave_troll_blacklist', $form_state['values']['cave']);
}

/**
 * Implementation of hook_db_rewrite_sql().
 */
function cave_db_rewrite_sql($query, $primary_table, $primary_field, $args) {

  switch ($primary_field) {
    case 'nid':
      $type = isset($type) ? $type : 'node';
      // follow through

    case 'cid':
      $type = $type ? $type : 'comment';

      if (variable_get('cave_troll_blacklist', 0)) {
        $ip = ip2long(ip_address());
        $return['join'] = "
          LEFT JOIN {cave_tracker} cave_tracker 
          ON cave_tracker.id = ". $primary_table .".". $primary_field ." 
          AND cave_tracker.type = '". $type ."'";
        $whitelist = "
          SELECT 1 FROM {troll_whitelist} troll_w 
          WHERE troll_w.net <= cave_tracker.ip 
          AND troll_w.bcast >= cave_tracker.ip";
        $blacklist = "
          SELECT 1 FROM {troll_blacklist} troll_b 
          WHERE troll_b.net <= cave_tracker.ip 
          AND troll_b.bcast >= cave_tracker.ip
          AND NOT (troll_b.net <= ". $ip ." 
          AND troll_b.bcast >= ". $ip .")";
        $return['where'] = "( EXISTS (". $whitelist .") OR NOT EXISTS (". $blacklist .") )";
      }

      $caved = cave_caved_users();
      if (!empty($caved)) {
        global $user;
        if (cave_user_caved()) {
          unset($caved[$user->uid]);
        }
        if (!empty($caved)) {
          if (!isset($return['where'])) {
            $return['where'] = '';
          }
          else {
            $return['where'] .= ' AND ';
          }
          $return['where'] .= $primary_table .'.uid NOT IN ('. implode(', ', $caved) .')';
        }
      }

      if ($return) {
        return $return;
      }
  }

}

/**
 * Implementation of hook_nodeapi().
 */
function cave_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
  if ($op == 'insert') {
    cave_tracker_insert('node', $node->nid);
  }
}

/**
 * Implementation of hook_comment().
 */
function cave_comment(&$a1, $op) {
  if ($op == 'insert') {
    cave_tracker_insert('comment', $a1['cid']);
  }
}

/**
 * Insert a record into the cave_tracker table.
 */
function cave_tracker_insert($type, $id) {
  $sql = "INSERT INTO {cave_tracker} (type, id, ip) VALUES ('%s', %d, %d)";
  $args = array($type, $id, ip2long(ip_address()));
  db_query($sql, $args);
}

/**
 * Check whether current user is caved.
 */
function cave_user_caved() {
  global $user;
  return $user->cave;
}

/**
 * Get/Set caved users.
 */
function cave_caved_users($uid = NULL, $action = 'add') {
  $data = variable_get('cave_caved_users', array());
  if (!is_null($uid)) {
    if ($action == 'add' && !isset($data[$uid])) {
      $data[$uid] = $uid;
    }
    elseif ($action == 'remove' && isset($data[$uid])) {
      unset($data[$uid]);
    }
    variable_set('cave_caved_users', $data);
  }
  return $data;
}

/**
 * Implementation of hook_user_operations().
 */
function cave_user_operations() {
  $operations = array(
    'cave_bulk_users_add' => array(
      'label' => t('Cave Your Trolls: Add the selected users to the cave'),
      'callback' => 'cave_bulk_users_add',
    ),
    'cave_bulk_users_remove' => array(
      'label' => t('Cave Your Trolls: Remove the selected users from the cave'),
      'callback' => 'cave_bulk_users_remove',
    ),
  );
  return $operations;
}

/**
 * Callback function for hook_user_operations().
 */
function cave_bulk_users_add($accounts) {
  foreach ($accounts as $uid) {
    $account = user_load(array('uid' => (int)$uid));
    if ($account !== FALSE) {
      cave_caved_users($account->uid, 'add');
    }
  }
}

/**
 * Callback function for hook_user_operations().
 */
function cave_bulk_users_remove($accounts) {
  foreach ($accounts as $uid) {
    $account = user_load(array('uid' => (int)$uid));
    if ($account !== FALSE) {
      cave_caved_users($account->uid, 'remove');
    }
  }
}