<?php

  // $Id: advuser.module,v 1.12.4.2 2007/06/02 22:45:47 earnie Exp $
define('ADVUSER_MODULE_VERSION', '$Id: advuser.module,v 1.12.4.2 2007/06/02 22:45:47 earnie Exp $' );

define('ADVUSER_DEFAULT_NEW_MAIL', "User email: %user_email\n\nIf you want to check and edit the account go to %uri.\n\nInvestigate User:\nYahoo search  %user_email: %yahoo_user \nGoogle search %user_email: %google_user\n\n--\n%site");
define('ADVUSER_DEFAULT_MODIFY_MAIL', ADVUSER_DEFAULT_NEW_MAIL); // "User email: %user_email\n\nIf you want to check and edit the account go to %uri.\n\nYahoo search %user_email: %yahoo_user \nGoogle search %user_email: %google_user\n\n--\n%site");
define('ADVUSER_DEFAULT_NEW_ROLES', NULL);
define('ADVUSER_DEFAULT_NEW_SUBJECT', 'A new user (%username) has just registered on %site.');
define('ADVUSER_DEFAULT_MODIFY_SUBJECT', 'A user (%username) has just modified their account on %site.');
define('ADVUSER_DEFAULT_NEW_NOTIFY', 1);
define('ADVUSER_DEFAULT_MODIFY_NOTIFY', 1);
define('ADVUSER_DEFAULT_LISTNO', 200);
define('ADVUSER_DEFAULT_PROFILE_FIELDS', NULL);

//define('ADVUSER_MAIL_MESSAGE_TEMPLATE', "From: $from\nReply-to: $from\nX-Mailer: Drupal\nReturn-path: $from\nErrors-to: $from");

/**
 * hook_perm() implementation
 *
 * @return array of permissions
 */
/**
 * Implementation of hook_menu().
 */
function advuser_menu($may_cache) {
  // code which should run exactly once per page view
  if (!$may_cache) {
    drupal_add_css(drupal_get_path('module', 'advuser') .'/advuser.css');
  }
  $items = array();
  if ($may_cache) {
    $items[] = array(
      'path' => 'admin/settings/advuser',
      'title' => t('Advanced User'),
      'description' => t('Advanced User Settings'),
      'callback' => 'drupal_get_form',
      'callback arguments' => array('advuser_settings'),
      'access' => user_access('administer site configuration'),
      'type' => MENU_NORMAL_ITEM,
    );

    $items[] = array(
            'path' => 'admin/user/advuser', 
            'title' => t('Advanced management'),
            'callback' => 'advuser_admin_users',
            'type' => MENU_NORMAL_ITEM,
//            'weight' => 7,
            'access' => user_access('administer users'),
            );
  }

  return $items;
}

/** 
 * hook_help implementation  
 */
function advuser_help($section) {  
  
  switch ($section) {
    case 'admin/modules#description':
      return t('Advanced user management module. Filter users and mass actions based on their filters.');
  }
}

/*
** Filters
*/
function advuser_admin_filters() {
  
  $filters = array();
  
  // Regular filters
  $filters['email'] = array(
      'title' => t('E-mail'),
      'where' => "u.mail = '%s'",
    );
  
   $filters['uid'] = array(
      'title' => t('User Id'),
      'where' => "u.uid = '%s'",
    );

    $filters['access'] = array(
      'title' => t('Last Access'),
      'where' => "u.access = '%s'",
    );
    $filters['status'] = array(
      'title' => t('Status'),
      'type'  => t('selection'),
      'options' => array(0 => t('Blocked'), 1 => ('Active')),
      'where' => 'u.status = %s',
    );
		
  $fields = variable_get('advuser_profile_fields', ADVUSER_DEFAULT_PROFILE_FIELDS);
  if ( is_array($fields) ) {
    foreach ( $fields as $fid => $value) {
      if ( $value ) {
        $field = db_fetch_object(db_query('SELECT * FROM {profile_fields} WHERE fid = %d', $fid));
        $options = array();
        if ( $field->type == 'selection' ) {
          $result_v = db_query('SELECT DISTINCT * FROM {profile_values} WHERE fid = %d', $field->fid);
          while ( $value = db_fetch_object($result_v)) {
            $options[$value->value] = $value->value;
          }
        }
        
        // Regular filters
        $filters[$field->fid] = array(
            'title' => $field->title,
            'type' => $field->type,
            'options' => $options,
            'field_where' => 'pf.fid = '. $field->fid .' AND pv.value = '."'%s'",
          );
      }
    }
  }
  
  advuser_module_invoke('filter', $filters);
  return $filters;
}

function advuser_admin_filter_form_validate($form_id, $form) {
  $op = $form_values['op'];
  if ( $op == 'Filter' || $op == 'Refine' ) {
    if ( ! isset($form[$form['filter']]) || $form[$form['filter']] == '' ) {
      form_set_error($form['filter'], t('Please fill some value to correctely set up the filter'));
    }
  }
}


function advuser_admin_filter_form_submit() {
  global $form_values;
  $op = $form_values['op'];
  $filters = advuser_admin_filters();
  switch ($op) {
    case t('Filter'): case t('Refine'):
      if (isset($form_values['filter'])) {
        $filter = $form_values['filter'];
        if ( $filters[$filter]['type']  == 'selection' ) {
          if (isset($filters[$filter]['options'][$form_values[$filter]])) {
            $_SESSION['advuser_user_filter'][] = array($filter, $form_values[$filter]);
          }
        }
         else {
          $_SESSION['advuser_user_filter'][] = array($filter, $form_values[$filter]);
        }
      }
      break;
    case t('Undo'):
      array_pop($_SESSION['advuser_user_filter']);
      break;
    case t('Reset'):
      $_SESSION['advuser_user_filter'] = array();
      break;
    case t('Update'):
      return;
  }
  if ($op != '') {
    drupal_goto('admin/user/advuser');
  }
}


function advuser_admin_filter_form() {
  //print_r($_SESSION['advuser_user_filter']);
  
  $sess = &$_SESSION['advuser_user_filter'];
  $sess = is_array($sess) ? $sess : array();
  $session = $sess;
  asort($session);
  $filters = advuser_admin_filters();

  $i = 0;
  $form['filters'] = array('#type' => 'fieldset', '#title' => t('Show only items where'), '#theme' => 'advuser_filters');
  
  $types_used = array();
  foreach ($session as $filter) {
    list($type, $value) = $filter;
    $original = $filters[$type];
    $em = 'and';
    if ( array_search($type, $types_used) !== FALSE ) {
      $em = 'or';
    }
    $string = ($i++ ? '<em>'. $em .'</em> where <strong>%a</strong> is <strong>%b</strong>' : '<strong>%a</strong> is <strong>%b</strong>');
    $txt_value = $value;
    if ($original['type'] == 'selection') {
      $txt_value = $original['options'][$value];
    }
    $form['filters']['current'][] = array('#value' => t($string, array('%a' => $filters[$type]['title'] , '%b' => $txt_value)));
    $types_used[] = $type;
  }

  foreach ($filters as $key => $filter) {
    $names[$key] = $filter['title'];
    if ( $filter['type'] == 'selection' ) {
      $form['filters']['status'][$key] = array('#type' => 'select', '#options' => $filter['options']);
    }
     else {
      $form['filters']['status'][$key] = array('#type' => 'textfield');
    }
  }

  $names_keys = array_keys($names);
  $form['filters']['filter'] = array('#type' => 'radios', '#options' => $names , '#default_value' => $names_keys[0] );
  $form['filters']['buttons']['submit'] = array('#type' => 'submit', '#value' => (count($session) ? t('Refine') : t('Filter')));
  if (count($session)) {
    $form['filters']['buttons']['undo'] = array('#type' => 'submit', '#value' => t('Undo'));
    $form['filters']['buttons']['reset'] = array('#type' => 'submit', '#value' => t('Reset'));
  }

//  return drupal_get_form('advuser_admin_filter_form', $form);
  return $form;
}


/*
** AdvUser operations
*/
function advuser_admin_users_operations() {
  $external = array();
  $operations = array(
    'email' => array(t('Email users'), 'advuser_multiple_email_confirm_page', 'confirm'),
    'delete' =>    array(t('Delete users'), 'advuser_multiple_delete_confirm' , 'confirm')
  );
  
  advuser_module_invoke('actions', $external);
  
  foreach ($external as $k => $v ) {
    $operations['external_'. $k] = $v;
  }
  
  return $operations;
}

function advuser_admin_user_build_filter_query() {
  $filters = advuser_admin_filters();

  // Build query
  $field_where = $where = $where_args = $having_args = array();
  $join = '';
  
  $cnt = 0;
  $session = $_SESSION['advuser_user_filter'];
  asort($session);
  foreach ($session as $filter) {
    list($key, $value) = $filter;
    
    // Check if process the filter an how
    $where_key = TRUE ;
    $where_keys = array_keys($where, $filters[$key]['where']);
    if ( count((array) $where_keys) > 0 ) {
      // check for same value to on arg array, should have the same key
      foreach ( $where_keys as $k => $v ) {
        if ( $where_args[$v] == $value ) {
          $where_key = FALSE;
        }
      }//foreach;
    }
    
    if ( isset($filters[$key]['where']) && $where_key )  {
      $where[] = $filters[$key]['where'];
      $where_args[] = $value;
    }
    
    // Check if process the filter an how
    $field_where_key = TRUE;
    $field_where_keys = array_keys($field_where, $filters[$key]['field_where']);
    if ( count((array) $field_where_keys) > 0 ) {
      // check for same value to on arg array, should have the same key
      foreach ( $field_where_keys as $k => $v ) {
        if ( $having_args[$v] == $value ) {
          $field_where_key = FALSE;
        }
      }//foreach;
    }
     else {
      if (  isset($filters[$key]['field_where']) ) {
        $cnt++;
      }
    }

    if ( isset($filters[$key]['field_where']) && $field_where_key )  {
      $field_where[] = $filters[$key]['field_where'];
      $having_args[] = $value;
    }
    
    // Proces join just once
    if ( ! strstr($join, $filters[$key]['join'] .' ') ) {
      $join .= $filters[$key]['join'] .' ';
    }
  }
  
  //print_r($field_where);
  
  // build query smartly
  $where_sql = 'WHERE u.uid > 1 AND ';
  foreach ( (array) $where as $w ) {
    if ( $lastwhere ) {
      if ( $lastwhere == $w ) {
        $where_sql .= ' OR '. $w ;
      }
       else {
        $where_sql .= ') AND ('. $w ;
      }
    } 
     else {
      $where_sql .= '('. $w ;
    }
    $lastwhere = $w;
  }
  if ( $lastwhere ) {
    $where_sql .= ') AND ';
  }
  $where_sql .= '1';
  
  $where = count($where) ? 'WHERE u.uid > 1 AND '. implode(' AND ', $where) : '';
  $field_where_cnt = count($field_where);
  $field_where = $field_where_cnt ? implode(' OR ', $field_where) : '0';
  $having[] = 'SUM(IF('. $field_where .',1,0)) = '. $cnt;
  $having = count($having) ? 'HAVING '. implode(' AND ', $having) : '';
  
  $args = array_merge($where_args, $having_args);

  return array( 'where' => $where_sql, 'join' => $join, 'args' => $args, 'having' => $having);
}

function advuser_multiple_email_confirm_page($all, $form) {
  return drupal_get_form('advuser_multiple_email_confirm', $all, $form);
}

function advuser_multiple_email_confirm($all, $form) {
  $form['mailsubject'] = array(
      '#type' => 'textfield', 
      '#title' => t('Subject'),
      '#required' => TRUE,
    );
  $form['mailbody'] = array(
      '#type' => 'textarea', 
      '#title' => t('Mail body'),
      '#required' => TRUE,
    );

  return confirm_form($form,
                      t('Are you sure you want to mail these users?'),
                      'admin/user/advuser', t('This action cannot be undone.'),
                      t('Mail all'), t('Cancel'));
}


function advuser_multiple_email_confirm_submit($form_id, $edit) {
  if ($edit['confirm']) {
    foreach ($edit['users'] as $uid => $value) {
      $account = user_load(array('uid' => $uid));
      if ( module_exists('lightcrm') ) {
        _lightcrm_comment_add($uid, $edit['mailsubject'], $edit['mailbody']);
      }
       else {
        $from = variable_get("site_mail", ini_get("sendmail_from")); // http://drupal.org/node/77689
        drupal_mail('advance-user-mail', $account->mail, $edit['mailsubject'], $edit['mailbody'], $from);
      }
    }
    drupal_set_message(t('The users have been mailed.'));
  }
  drupal_goto('admin/user/advuser');
}

function advuser_multiple_delete_confirm_submit($form_id, $edit) {
  if ($edit['confirm']) {
    foreach ($edit['users'] as $uid => $value) {
      $account = user_load(array('uid' => $uid));
      db_query('DELETE FROM {users} WHERE uid = %d', $account->uid);
      db_query('DELETE FROM {sessions} WHERE uid = %d', $account->uid);
      db_query('DELETE FROM {users_roles} WHERE uid = %d', $account->uid);
      db_query('DELETE FROM {authmap} WHERE uid = %d', $account->uid);
      watchdog('user', t('Deleted user: %name %email.', array('%name' => theme('placeholder', $account->name), '%email' => theme('placeholder', '<'. $account->mail .'>'))), WATCHDOG_NOTICE);
      drupal_set_message(t('The account has been deleted.'));
      module_invoke_all('user', 'delete', $edit, $account);
    }
    drupal_set_message(t('The items have been deleted.'));
  }
  drupal_goto('admin/user/advuser');
}

function advuser_multiple_confirm($all, $action, $user_func) {
  $edit = $_POST['edit'];

  $form = array();
  $form['users'] = array('#prefix' => '<ul>', '#suffix' => '</ul>', '#tree' => TRUE);
  // array filter returns only elements with true values
  if ( $all ) {
    $filter = advuser_admin_user_build_filter_query();
    $result = db_query('SELECT u.* FROM {users} u '. $filter['join'] .' LEFT JOIN {profile_values} pv ON u.uid = pv.uid LEFT JOIN {profile_fields} pf on pv.fid = pf.fid '. $filter['where'] .' GROUP BY u.uid '. $filter['having'] .' ORDER BY u.login DESC', $filter['args']);
    while ( $usr = db_fetch_object($result)) {
      $user_array[$usr->uid] = '';
    }
  }
   else {
    $user_array = array_filter($edit['users']);
  }
  
  foreach ($user_array as $uid => $value) {
    $name = db_result(db_query('SELECT name FROM {users} WHERE uid = %d', $uid));
    $form['users'][$uid] = array('#type' => 'hidden', '#value' => $uid, '#prefix' => '<li>', '#suffix' => check_plain($name) ."</li>\n");
  }
  $form['operation'] = array('#type' => 'hidden', '#value' => $action);
  
  if ( function_exists($user_func) ) {
    $user_func($all, $form);
  }

  $operations = advuser_admin_users_operations();
  return confirm_form($user_func, $form,
                      t('Are you sure you want to update these items?'),
                      'admin/user/advuser', t('This action cannot be undone.'),
                      $operations[$action][0], t('Cancel'));
}

function advuser_admin_users() {
  $output = drupal_get_form('advuser_admin_filter_form');

  // Call the form first, to allow for the form_values array to be populated.
//  $output .= drupal_get_form('user_admin_account');
  $output .= drupal_get_form('advuser_admin_users_form');
  
  return $output;
}

function advuser_admin_users_form() {
  global $form_values;

  $op = $form_values['op'];
  if ( $op == 'Update all' ) {
    $all = TRUE;
  }
  
  foreach (advuser_admin_users_operations() as $key => $value) {
    if ( $value[2] == 'confirm' ) {
      if ( 
          $_POST['edit']['options_all']['operation'] == $key && $all ||
          ( $_POST['edit']['options_sel']['operation'] == $key && (count($_POST['edit']['users']) > 0) ) ||
          $_POST['edit']['operation'] == $key
        ) {
  
        return advuser_multiple_confirm($all, $key, $value[1]);
        //return call_user_func($value[1], $all);
        //return advuser_multiple_delete_confirm($all);
      } 
    }
  }
  
  $filter = advuser_admin_user_build_filter_query();
  $listno = variable_get('advuser_listno', ADVUSER_DEFAULT_LISTNO);
  $result = pager_query('SELECT u.* FROM {users} u '. $filter['join'] .' LEFT JOIN {profile_values} pv ON u.uid = pv.uid LEFT JOIN {profile_fields} pf on pv.fid = pf.fid '. $filter['where'] .' GROUP BY u.uid '. $filter['having'] .' ORDER BY u.login DESC', $listno, 0, NULL, $filter['args']);
  //$result = 'SELECT u.* FROM {users} u '. $filter['join'] .' LEFT JOIN {profile_values} pv ON u.uid = pv.uid LEFT JOIN {profile_fields} pf on pv.fid = pf.fid '. $filter['where'] .' GROUP BY u.uid ' . $filter['having'] . ' ORDER BY u.login DESC', $listno, 0, $filter['args'];
  //$result .= tablesort_sql($header);

  $form['options_all'] = array(
    '#type' => 'fieldset', '#title' => t('Mass update on every record'),
    '#prefix' => "<div class=\"container-inline\">" , '#suffix' => "</div>",
    '#tree' => TRUE,
  );
  $options = array();
  foreach (advuser_admin_users_operations() as $key => $value) {
    $options[$key] = $value[0];
  }
  $form['options_all']['operation'] = array(
    '#type' => 'select',
    '#options' => $options,
  );
  $form['options_all']['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Update all')
  );
  
  $form['options_sel'] = array(
    '#type' => 'fieldset', '#title' => t('Update on selected records only'),
    '#prefix' => "<div class=\"container-inline\">" , '#suffix' => "</div>",
    '#tree' => TRUE,
  );
  $options = array();
  foreach (advuser_admin_users_operations() as $key => $value) {
    $options[$key] = $value[0];
  }
  $form['options_sel']['operation'] = array(
    '#type' => 'select',
    '#options' => $options,
   );
  $form['options_sel']['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Update')
   );

    $destination = drupal_get_destination();

    $status = array(t('blocked'), t('active'));

  while ($usr = db_fetch_object($result)) {
    $users[$usr->uid] = '';
    $form['name'][$usr->uid] = array('#value' => theme('username', $usr));

    $form['status'][$account->uid] =  array('#value' => $status[$account->status]);
    $form['access'][$usr->uid] = array('#value' => $usr->access ? t('%time ago', array('%time' => format_interval(time() - $usr->access))) : t('never'));
    //$form['access'][$usr->access] = array('#value' => ($usr->access ? format_interval(time() - $usr->access)));
    $form['operations'][$usr->uid] = array('#value' => l(t('edit'), 'user/'. $usr->uid .'/edit', array(), $destination));
    $form['refcode'][$usr->uid] = array('#value' => $usr->uid);
  }

  $form['users'] = array(
    '#type' => 'checkboxes',
    '#options' => $users
   );

  $form['pager'] = array('#value' => theme('pager', NULL, 50, 0));

  $form['#method'] = 'post';
  $form['#action'] =  url('admin/user/advuser/action');

  return $form;
}


function theme_advuser_admin_users_form($form) {
  // Overview table:
  $header = array(
    theme('table_select_header_cell'),
    array('data' => t('Username'), 'field' => 'u.name'),
    array('data' => t('Status'), 'field' => 'u.status'),
    array('data' => t('Last access'), 'field' => 'u.access'),
    array('data' => t('User ID'), 'field' => 'u.uid'),
    t('Operations')
  );


  $output .= drupal_render($form['options_all']);
  $output .= drupal_render($form['options_sel']);
  if (isset($form['name']) && is_array($form['name'])) {
    foreach (element_children($form['name']) as $key) {
      $rows[] = array(
      drupal_render($form['users'][$key]),
      drupal_render($form['name'][$key]),
      drupal_render($form['status'][$key]),
      drupal_render($form['access'][$key]),
      drupal_render($form['refcode'][$key]),
      drupal_render($form['operations'][$key]),
      );
    }

  }
  else  {
    $rows[] = array(array('data' => t('No posts available.'), 'colspan' => '4'));
  }

  $output .= theme('table', $header, $rows);
  if ($form['pager']['#value']) {
    $output .= drupal_render($form['pager']);
  }

  $output .= drupal_render($form);
  $output .= theme('pager', NULL, 50, 0);
  return $output;
}

function theme_advuser_admin_filter_form(&$form) {
  $output .= '<div id="advuser-admin-filter">';
  $output .= drupal_render($form['filters']);
  $output .= '</div>';
  $output .= drupal_render($form);
  return $output;
}

function advuser_admin_users_validate($form_id, $edit) {
  $op = $form_values['op'];
  if ( $op == 'Update' ) {
    $edit['users'] = array_diff($edit['users'], array(0));
    if (count($edit['users']) == 0) {
      form_set_error('', t('Please select some items to perform the update on.'));
    }
  }
}

/**
 * Perform actions on users
 */
function advuser_admin_users_submit($form_id, $edit) {
  $operations = advuser_admin_users_operations();
  if ($operations[$edit['operation']][1]) {
    // Execute sql
    $operation = $operations[$edit['operation']][1];
    foreach ($edit['users'] as $uid => $value) {
      if ($value) {
        db_query($operation, $uid);
      }
    }
    drupal_set_message(t('The update has been performed.'));
    drupal_goto('admin/user/advuser');
  }
}

/**
 * Invokes hook_advuser() in every module.
 *
 * We cannot use module_invoke() for this, because the arguments need to
 * be passed by reference.
 */
function advuser_module_invoke($type, &$array) {
  foreach (module_list() as $module) {
    $function = $module .'_advuser';
    if (function_exists($function)) {
      $function($type, $array);
    }
  }
}

function theme_advuser_filters(&$form) {
  $output .= '<ul>';
  if (sizeof($form['current'])) {
    foreach (element_children($form['current']) as $key) {
      $output .= '<li>'. drupal_render($form['current'][$key]) .'</li>';
    }
  }

  $output .= '<li><dl class="multiselect">'. (sizeof($form['current']) ? '<dt><em>'. t('and/or') .'</em> '. t('where') .'</dt>' : '') .'<dd class="a">';
  foreach (element_children($form['filter']) as $key) {
    $output .= drupal_render($form['filter'][$key]);
  }
  $output .= '</dd>';

  $output .= '<dt>'. t('is') .'</dt><dd class="b">';

  foreach (element_children($form['status']) as $key) {
    $output .= drupal_render($form['status'][$key]);
  }
  $output .= '</dd>';

  $output .= '</dl>';
  $output .= '<div class="container-inline" id="advuser-admin-buttons">'. drupal_render($form['buttons']) .'</div>';
  $output .= '</li></ul><br class="clear" />';

  return $output;
}

function advuser_settings() {
  $form['module_banner'] = array(
      '#type' => 'markup', 
      '#value' => '<div style="border: solid 1px #eee; margin: .5em; padding: .5em;" <strong>Module maintenance and development sponsored by <a href="http://exodusdev.com">Exodus Development</a></strong><br/>'
    );

  $form['module_id'] = array(
      '#type' => 'markup',
      '#value' =>  ADVUSER_MODULE_VERSION .'<br/></div>'
    );

  $form['advuser_mail'] = array(
      '#type' => 'fieldset',
      '#title' => t('Mail notifications on user account activity.'),
      '#collapsible' => FALSE,
      '#collapsed' => FALSE,
    );

  $result = db_query('SELECT DISTINCT name FROM {profile_fields}');
  while ($value = db_fetch_array($result)) {
      $vars[] = '%'.$value[name];
  }
  $form['advuser_mail']['variables'] = array(
      '#type' => 'markup', 
      '#value' => '<div class="advuser-inset-panel"><strong>Substitution variables</strong> available in subject and email body<br/><em> %username, %site, %uri, %user_email, %google_user (search google for user email), %yahoo_user (search yahoo for user email) '.implode(" ", $vars).'</em></div>'
    );

  //New User Notification
  $form['advuser_mail']['advuser_new_notify'] = array(
      '#type' => 'checkbox',
      '#title' => t('Send notifications on new user registration'),
      '#description' => t('Notify selected roles when new users register.'),
      '#default_value' => variable_get('advuser_new_notify', ADVUSER_DEFAULT_NEW_NOTIFY),
    );
  $form['advuser_mail']['advuser_new_subject'] = array(
      '#type' => 'textfield',
      '#title' => t('Mail subject'),
      '#description' => t('The subject of the mail that is going to be sent to the user.  You may insert substitution variables within this item.'),
      '#default_value' => variable_get('advuser_new_subject', ADVUSER_DEFAULT_NEW_SUBJECT),
    );
  $form['advuser_mail']['advuser_new_mail'] = array(
      '#type' => 'textarea',
      '#title' => t('Mail body'),
      '#description' => t('The mail that is going to be sent to the selected roles.  You may insert substitution variables within this item.'),
      '#default_value' => variable_get('advuser_new_mail', ADVUSER_DEFAULT_NEW_MAIL),
    );

   //User change notification
   $form['advuser_mail']['advuser_modify_notify'] = array(
      '#type' => 'checkbox',
      '#title' => t('Send notifications on user profile updates'),
      '#description' => t('Notify selected roles when users update their profiles.'),
      '#default_value' => variable_get('advuser_modify_notify', ADVUSER_DEFAULT_MODIFY_NOTIFY),
    );
  $form['advuser_mail']['advuser_modify_subject'] = array(
      '#type' => 'textfield',
      '#title' => t('Mail subject'),
      '#description' => t('The subject of the mail that is going to be sent when a user modifies their profiles.  You may insert substitution variables within this item.'),
      '#default_value' => variable_get('advuser_modify_subject', ADVUSER_DEFAULT_MODIFY_SUBJECT),
    );
  $form['advuser_mail']['advuser_modify_mail'] = array(
      '#type' => 'textarea',
      '#title' => t('Mail body'),
      '#description' => t('The mail that is going to be sent to the selected roles when a user modifies their account.  You may insert substitution variables within this item.'),
      '#default_value' => variable_get('advuser_modify_mail', ADVUSER_DEFAULT_MODIFY_MAIL),
    );
				
    //Maximum rows in dataset to display
    $form['advuser_mail']['advuser_listno'] = array(
      '#type' => 'select',
      '#options' => drupal_map_assoc(array(0, 10, 25, 50, 75, 100, 125, 150, 175, 200)),
      '#title' => t('Number of users in listing'),
      '#description' => t('Sets how many users to display in table view'),
      '#default_value' => variable_get('advuser_listno', ADVUSER_DEFAULT_LISTNO),
    );
    
  $roles = user_roles(1);
  /*$options = array();
  foreach ( $roles as $rid => $role) {
    $options["$rid"] = $role;
  }*/
  //print_r();
  $values = array();
  $options = variable_get('advuser_new_roles', ADVUSER_DEFAULT_NEW_ROLES);
  $sel_roles_count = 0;
  foreach ( (array)$options as $opt => $v ) {
    if ( $v > 0 ) {
      $values[] = $v;
      $sel_roles_count++;
    }
  }
  $form['advuser_mailonnew']['advuser_new_roles'] = array(
      '#type' => 'checkboxes',
      '#title' => t('Notification Roles'),
      '#description' => t('Roles that receive email notifications.'),
      '#options' => $roles,
      '#default_value' => $values /*variable_get('advuser_new_roles', ADVUSER_DEFAULT_NEW_ROLES)*/,
    );

  if ($sel_roles_count == 0) {
    $form['advuser_mailonnew']['no_roles_sel_warning']
      = array('#type' => 'markup', 
              '#value' => '<div class="advuser-settings-warning"><strong>WARNING: No roles selected!</strong> - no email notifications will be sent.</div>');
  }
    
  if ( module_exists('profile') ) {
    $form['advuser_profile'] = array(
        '#type' => 'fieldset',
        '#title' => t('Profile module special settings'),
        '#collapsible' => TRUE,
        '#collapsed' => TRUE,
      );

    $fields = array();
    $result = db_query('SELECT * FROM {profile_fields} WHERE visibility != %d ORDER BY category, weight', PROFILE_HIDDEN);
    while ( $row = db_fetch_object($result)) {
      $fields[$row->fid] = $row->title;
    }
    
    $values = array();
    $options = variable_get('advuser_profile_fields', ADVUSER_DEFAULT_PROFILE_FIELDS);
    foreach ( (array)$options as $opt => $v ) {
      if ( $v > 0 ) {
        $values[] = $v;
      }
    }
    
    $form['advuser_profile']['advuser_profile_fields'] = array(
        '#type' => 'checkboxes',
        '#description' => t('Profile fields to be used as filters for the users.'),
        '#title' => t('Profile fields'),
        '#options' => $fields,
        '#default_value' => $values,
      );    
      
  }
  return system_settings_form($form);
}

/**
 * Get a list of substitution variables for the user account
 * @param $user the user account
 * @return An associative array of substitution variables 
 */
function _advuser_get_variables(&$user) {
  $variables = 
    array(
          '%username' => $user->name,
          '%site' => variable_get("site_name", "drupal"), 
          '%uri' => url('user/'. $user->uid, NULL, NULL, TRUE), 
          '%user_email' => $user->mail,
          /* FUTURE: '%user_signature' => $user->signature, */
          '%google_user' => "http:/www.google.com/search?q=%22$user->mail%22",
          '%yahoo_user' => "http://search.yahoo.com/search/?p=%22$user->mail%22", 
          );
  $result = db_query('SELECT DISTINCT name FROM {profile_fields}');
  while ($value = db_fetch_array($result)) {
    $field = $value[name];
    $variables['%'.$field] = $user->$field;
  }
  return $variables;
}

/**
 * Construct a db query 'where' clause fragment so we can get a list of users to notify
 * TODO: this needs cleanup.  There should be a way to gather a list of users who are 
 * in roles.  
 */
function _advuser_get_roles_query_fragment($roles) {
  // TODO: this needs to be cleaned up.
  if (is_array($roles) ) {
    foreach ((array)$roles as $role_k => $role_v) {
      if ( $role_v > 0 ) {
        if ( $role_v == DRUPAL_AUTHENTICATED_RID ) {
          $role_where = ' OR 1';
        }
         else {
          $role_where = ' OR ur.rid = '. $role_v;
        }
      }
    }
  }
  return $role_where;
}

function _advuser_dbquery_users_to_notify($roles) {
  $role_where = _advuser_get_roles_query_fragment($roles);
  return db_query('SELECT u.mail, u.name FROM {users} u LEFT JOIN {users_roles} ur on u.uid = ur.uid WHERE 0 '. $role_where );
}


/**
 * Handle user insertion (new users)
 * TODO: DRY (don't repeat yourself!)
 */

function advuser_user_insert($edit, $user, $category) {
  // send mail
  if ( variable_get('advuser_new_notify', ADVUSER_DEFAULT_NEW_NOTIFY) ) {
    $from = variable_get("site_mail", ini_get("sendmail_from"));
    $body = variable_get('advuser_new_mail', ADVUSER_DEFAULT_NEW_MAIL);
    $subject = variable_get('advuser_new_subject', ADVUSER_DEFAULT_NEW_SUBJECT);

    // these are invariant for all sent emails
    $variables = _advuser_get_variables($user);
    $user_subject = strtr($subject, $variables);
    $user_body = strtr($body, $variables);

    watchdog('advuser', "Sending user account mail: subj='$user_subject' body='$user_body'");

    $roles = variable_get('advuser_new_roles', ADVUSER_DEFAULT_NEW_ROLES);
    $result = _advuser_dbquery_users_to_notify($roles);
    while ($row = db_fetch_object($result)) {
      drupal_mail('advanced-user-mail', $row->mail, $user_subject, $user_body, $from);
    }
  }
}

/**
 * TODO: Need 'send test email' -> sends test email for current user account, to current user account
 */

function advuser_user_update($edit, $user, $category) {
	global $old_subject;
	global $old_body;

  // create mail with original values
  if ( variable_get('advuser_modify_notify', ADVUSER_DEFAULT_MODIFY_NOTIFY) ) {
    $from = variable_get("site_mail", ini_get("sendmail_from"));
    $body = variable_get('advuser_modify_mail', ADVUSER_DEFAULT_MODIFY_MAIL);
    $subject = variable_get('advuser_modify_subject', ADVUSER_DEFAULT_MODIFY_SUBJECT);

    $variables = _advuser_get_variables($user);
    $old_subject = strtr($subject, $variables);
    $old_body = strtr($body, $variables);
  }
}

/**
 * Handle user edit
 * TODO: DRY (don't repeat yourself!)
 */
function advuser_user_after_update($edit, $user, $category) {
  global $old_subject;
  global $old_body;

  // prepare mail
  if ( variable_get('advuser_modify_notify', ADVUSER_DEFAULT_MODIFY_NOTIFY) ) {
    $from = variable_get("site_mail", ini_get("sendmail_from"));
    $body = variable_get('advuser_modify_mail', ADVUSER_DEFAULT_MODIFY_MAIL);
    $subject = variable_get('advuser_modify_subject', ADVUSER_DEFAULT_MODIFY_SUBJECT);

    $variables = _advuser_get_variables($user);
    $user_subject = strtr($subject, $variables);
    $user_body = strtr($body, $variables);
		// send mail if it changed
    if ($user_body != $old_body || $user_subject != $old_subject) {
			watchdog('advuser', "Sending user account mail: subj='$user_subject' body='$user_body'");

			$roles = variable_get('advuser_new_roles', ADVUSER_DEFAULT_NEW_ROLES);
			$result = _advuser_dbquery_users_to_notify($roles);
			while ($row = db_fetch_object($result)) {
				drupal_mail('advanced-user-mail', $row->mail, $user_subject, $user_body, $from);
			}
    }
  }
}


/** 
 * hook_user implementation  
 */
function advuser_user($type, &$edit, &$user, $category = NULL) {
  switch ($type) {
  case 'insert':
    return advuser_user_insert($edit, $user, $category);
  case 'update':
    return advuser_user_update($edit, $user, $category);
  case 'after_update':
    return advuser_user_after_update($edit, $user, $category);
  }
}

// vim:ft=php:et:sw=2:ts=2:sts=2:ai:sta
