Skip to content
user_badges.module 44.1 KiB
Newer Older
Nuno Veloso's avatar
Nuno Veloso committed

/**
 * @file
 * @brief User Badges module file
 * This file contains all the hook implementations and commonly used functions
Nuno Veloso's avatar
Nuno Veloso committed
 *
 * @author Jeff Robbins (jjeff), http://drupal.org/user/17190
 * @author Chad Phillips (hunmonk), http://drupal.org/user/22079
 * @author Heine Deelstra (Heine), http://drupal.org/user/17943
 * @author Nuno Veloso (nunoveloso18), http://drupal.org/user/80656
 * @author Richard Skinner (Likeless), http://drupal.org/user/310635
 * @author Nancy Wichmann (NancyDru), http://drupal.org/user/101412
 * @author Shabana Navas (Shabana Blackborder), http://drupal.org/user/1311398
Nuno Veloso's avatar
Nuno Veloso committed
 */
 */
function user_badges_help($path, $arg) {
    case 'admin/modules#description':
      return t('User badges are iconic images which can be assigned to users. They can represent accomplishments, status, or anything you\'d like. These badges will show up in the user\'s profile, and could also be used by a theme to appear with user postings on forums, comments, or nodes. Badges can be assigned manually by an administrator by visiting a user\'s profile. They also can be assigned automatically by role or ecommerce purchase (if ecommerce modules are installed). The excellent !link module can also be used to set and unset badges on a wide variety of conditions.', array('!link' => l('Rules', 'http://drupal.org/project/rules', array('absolute' => TRUE))));
      return t("Select the badge that you'd like to associate with each role.");
    case 'admin/user/user_badges/images':
      return t("This is the user badges image library. Note that this area is not functional if you have private download active. Here you can upload images to display as a user badge, but you can also enter image URLs directly in the badge form, so this area is optional. The images can be anything you like, but it is recommended that you maintain a uniform icon size for all of your badges. Keep in mind that a user may have many badges displayed so you'll probably want to keep them as small as possible (like 16x16 pixels or smaller).");
    case 'user/%/badges':
    case 'user/%/badges/list':
      $showone = variable_get('user_badges_showone', 0);
      if (variable_get('user_badges_userweight', 0) && ($user->uid == $arg[1] || user_access('change badge assignments')) ) {
        // Help messages for users who can reorder.
          return t("You can reorder badges here. Some badges may not appear on the list; these badges cannot be reordered. Only the top !number badges will be shown publicly.", array('!number' => $showone));
          return t("You can reorder your badges here. Some badges may not appear on the list; these badges cannot be reordered.");
        // Either we don't support reordering, or this user lacks the permission to do it.
//        return t("These are all the badges owned by this user.");
function user_badges_perm() {
  return array(
    'manage badges',
    'change badge assignments',
    'show badges in user profile'
  );
 */
function user_badges_menu() {
  $items = array();
  $access = array('manage badges');
  $items['admin/user/user_badges'] = array(
    'title' => 'Badges',
    'description' => t('Add, edit, and delete badges.  Associate badges with roles and configure site-wide settings for badges.'),
    'page callback' => 'drupal_get_form',
    'page arguments' => array('user_badges_badgelist_form'),
    'access arguments' => $access,
    'file' => 'user_badges.admin.inc',
  $items['admin/user/user_badges/list'] = array(
    'title' => 'List',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('user_badges_badgelist_form'),
    'access arguments' => $access,
    'type' => MENU_DEFAULT_LOCAL_TASK,
    'weight' => -10,
    'file' => 'user_badges.admin.inc',
  $items['admin/user/user_badges/add'] = array(
    'title' => 'Add',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('user_badges_edit_form'),
    'access arguments' => $access,
    'type' => MENU_LOCAL_TASK,
    'file' => 'user_badges.admin.inc',
  $items['admin/user/user_badges/images'] = array(
    'title' => 'Images',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('user_badges_images_form'),
    'access arguments' => $access,
    'type' => MENU_LOCAL_TASK,
    'file' => 'user_badges.admin.inc',
  $items['admin/user/user_badges/roles'] = array(
    'title' => 'Roles',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('user_badges_roles_form'),
    'access arguments' => $access,
    'type' => MENU_LOCAL_TASK,
    'file' => 'user_badges.admin.inc',
Nuno Veloso's avatar
Nuno Veloso committed
  $items['admin/user/user_badges/settings'] = array(
    'title' => 'Settings',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('user_badges_settings_form'),
    'access arguments' => $access,
    'type' => MENU_LOCAL_TASK,
    'file' => 'user_badges.admin.inc',
  $items['admin/user/user_badges/edit/%'] = array(
    'title' => 'Edit badge',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('user_badges_edit_form', 4),
    'access arguments' => $access,
    'type' => MENU_CALLBACK,
    'file' => 'user_badges.admin.inc',
  $items['admin/user/user_badges/delete/%'] = array(
    'title' => 'Delete badge',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('user_badges_delete_form', 4),
    'access arguments' => $access,
    'type' => MENU_CALLBACK,
    'file' => 'user_badges.admin.inc',
    'page callback' => 'user_badges_userweight_page',
    'page arguments' => array(1),
    'access arguments' => array('show badges in user profile'),
  $items['user/%/badges/list'] = array(
    'title' => 'List',
    'page callback' => 'user_badges_userweight_page',
    'page arguments' => array(1),
    'access arguments' => array('show badges in user profile'),
    'type' => MENU_DEFAULT_LOCAL_TASK,
    'weight' => -10,
  $items['user/%/badges/edit'] = array(
    'title' => 'Edit',
    'page callback' => 'user_badges_page',
    'page arguments' => array(1),
    'access arguments' => array('change badge assignments'),
    'type' => MENU_LOCAL_TASK,
    'weight' => 5,
  $items['user_badges/autocomplete'] = array(
    'title' => 'User Badges Badge Name Autocomplete',
    'page callback' => 'user_badges_badge_autocomplete',
    'access callback' => TRUE,
    'type' => MENU_CALLBACK,
 * This handles assignment of badges based on role.
 * When a role is assigned or removed, appropriate badges are added or removed.
function user_badges_user($op, &$edit, &$account, $category = 'account') {
      // Have we loaded this user before?
      if (isset($badges[$account->uid])) {
        $account->badges = $badges[$account->uid];
        // Get all user badges for this user, regardless of whether we filter the ones we show.
        $account->badges_all = user_badges_get_badges($account->uid, array('nolimit' => TRUE));
        // Now make the array of badges we will show.
        $account->badges = $account->badges_all;
        if ($limit = variable_get('user_badges_showone', 0)) {
//  dsm("Limit: $limit, account->badges: ".print_r($account->badges, true));
          // Loop through all potential badges and get the ones we can show.
//          if ($account->badges_all) {
            foreach ($account->badges_all as $bid => $badge) {
              $badge->class = 'badge ' . _user_badges_class($badge);
              // Display the badge if there's no limit or if the badge is unhideable or if we are within our limit.
              if ($limit > 0 || $badge->unhideable == 1) {
                $account->badges[$bid] = $badge;
                // Count down our limit, unless the badge doesn't count towards it.
                if (!$badge->doesnotcounttolimit) {
                  $limit--;
                }
//        else {
//          $account->badges = $account->badges_all;
//        }
      $badges[$account->uid] = $account->badges;
      if (is_array($account->roles)) {
        // Get the list of role badges.
Heine's avatar
Heine committed
        $roles = user_badges_get_roles();
        $badges = user_badges_get_badges('select');
Heine's avatar
Heine committed
        $message = user_access('manage badges');
        $rids = array_keys($account->roles);
        foreach ($rids as $rid) {
          if (array_key_exists($rid, $roles)) {
            if (!array_key_exists($roles[$rid], $account->badges)) {
              $success = user_badges_user_add_badge($account->uid, $roles[$rid], 'role');
              if ($success && $message) {
Heine's avatar
Heine committed
                drupal_set_message(t('User assigned %name badge.', array('%name' => $badges[$roles[$rid]])));
Heine's avatar
Heine committed
              }
            }
          }
Heine's avatar
Heine committed
    case 'update':
      if (is_array($edit['roles'])) {
Heine's avatar
Heine committed
        // Badges only get assigned or removed when a user's role assignments are changed.

        // Add authenticated users (code below only cares about array keys) to prevent badge deletion
Heine's avatar
Heine committed
        $new_roles[2] = 2;
        // Get the list of role badges.
        $roles = user_badges_get_roles();
        $badges = user_badges_get_badges('select');

        $message = user_access('manage badges');

Heine's avatar
Heine committed
        // What are the added roles?
        $added = array_diff(array_keys($new_roles), array_keys((array)$account->roles));
        foreach ($added as $rid) {
          if (array_key_exists($rid, $roles) && !array_key_exists($roles[$rid], $account->badges_all)) {
            $success = user_badges_user_add_badge($account->uid, $roles[$rid], 'role');
            if ($success && $message) {
Heine's avatar
Heine committed
              drupal_set_message(t('User assigned %name badge.', array('%name' => $badges[$roles[$rid]])));
Heine's avatar
Heine committed
        // What are the removed roles?
        $removed = array_diff(array_keys((array)$account->roles), array_keys($new_roles));
        foreach ($removed as $rid) {
Heine's avatar
Heine committed
          // If this role has a badge and user has this badge..
          if (array_key_exists($rid, $roles) && array_key_exists($roles[$rid], $account->badges_all)) {
            $success = user_badges_user_remove_badge($account->uid, $roles[$rid], 'role');
Heine's avatar
Heine committed
            drupal_set_message(t('%name badge removed from user.', array('%name' => $badges[$roles[$rid]])));
        //As we may have altered the badges, we need to refresh them in the $account object
        $account->badges = user_badges_get_badges($account->uid);
        $account->badges_all = user_badges_get_badges($account->uid, array('nolimit' => TRUE));
    case 'delete':
      db_query('DELETE FROM {user_badges_user} WHERE uid = %d', $account->uid);
    case 'view':
      if (is_array($account->badges) && count($account->badges)) {
        $badgeimgs = array();
        foreach ($account->badges as $badge) {
          $badgeimgs[] = theme('user_badge', $badge, $account);
        $account->content['user_badges'] = array(
          '#type' => 'user_profile_category',
          '#title' => t('Badges'),
          '#weight' => 10,
          '#attributes' => array('class' => 'user-badges'),
        );
        $account->content['user_badges']['badges'] = array(
          '#type' => 'user_profile_item',
          '#value' => theme('user_badge_group', $badgeimgs),
          '#attributes' => array('class' => 'badges'),
Heine's avatar
Heine committed
        );
/**
 * Helper function for building badge class names.
 * I was originally using form_clean_id, but it is not secure.
 *
 * @param $badge - the object describing the badge.
 * @return string containing the class name.
 */
function _user_badges_class($badge) {
  // Doing separate lines makes changing the algorithm easier.
  $class = $badge->name;
  $class = strip_tags($class, '');
  $class = drupal_strtolower($class);
  $class = str_replace(array('"', "'"), '', $class);
  $class = str_replace(array('_', ' '), '-', $class);

//  dsm("_user_badges_class: badge->name = $badge->name becomes $class.");
  return $class;
}

Heine's avatar
Heine committed
/**
Heine's avatar
Heine committed
 */
function user_badges_theme() {
  return array(
    'user_badge' => array(
      'arguments' => array('badge' => NULL, 'account' => NULL),
    'user_badge_group' => array(
      'arguments' => array('badgeimages' => array()),
    ),
    'user_badges_userweight_form' => array(
      'arguments' => array('form' => NULL),
    ),
    'user_badges_badgelist_form' => array(
      'arguments' => array('form' => NULL),
/**
 * form for users to weight their own badges
 */
function user_badges_userweight_form($form_state, $account) {
  $allbadges = $account->badges_all;
  $form['header'] = array('#type' => 'value', '#value' => array(
    array('data' => t('Name')),
    array('data' => t('Badge')),
    array('data' => t('Weight')),
  ));
  // We need to know what the weight delta will be, which depends on the number
  // of badges we will list.
  foreach ($allbadges as $badge) {
    if (!$badge->fixedweight) {
      $delta++;
    }
  }
  // Build a table listing the appropriate badges.
    $weight = $badge->weight;
    if (isset($badge->userweight)) {
      $weight = $badge->userweight;
    }
    $form['name'][$badge->bid] = array('#value' => check_plain($badge->name));
    $form['badge'][$badge->bid] = array('#value' => theme('user_badge', $badge, $account));
    $form['weight'][$badge->bid] = array(
      '#type' => 'weight',
      '#default_value' => $weight,
      '#delta' => $delta,
      '#attributes' => array('class' => 'user_badges_userweight_element'),
    );
  }
  $form['uid'] = array(
    '#type' => 'value',
    '#value' => $account->uid,
  );
  $form['submit'] = array('#type' => 'submit', '#value' => t('Submit'));
  return $form;
}

/**
 * Process user_badges_userweight_form form submissions.
 *
 * Update the badge userweights
 */
function user_badges_userweight_form_submit($form, &$form_state) {
  if (isset($form['weight']) && is_array($form['weight'])) {
    foreach (element_children($form['weight']) as $bid) {
      db_query("UPDATE {user_badges_user} SET userweight = %d WHERE bid = %d AND uid = %d",
      $form_state['values'][$bid],
      $bid,
      $form_state['values']['uid']
      );
    }
    drupal_set_message(t('Your badge order has been updated.'));
  }
}

/**
 * Form theming function
 */
function theme_user_badges_userweight_form($form) {
  //Loop through the array items in the name array to get all the bids for our listed badges
  if (isset($form['name']) && is_array($form['name'])) {
    foreach (element_children($form['name']) as $key) {
      //We only want bids as values of $key
      if (!is_numeric($key)) {
        continue;
      }
      //Create the rows array for the table theme
      $row = array();
      $row[] = drupal_render($form['name'][$key]);
      $row[] = drupal_render($form['badge'][$key]);
      $row[] = drupal_render($form['weight'][$key]);
      //Add the draggable class to this row
      $rows[] = array('data' => $row, 'class' => 'draggable', '#weight' => $form['weight'][$key]['#value']);
    }
    //Sort the rows by their weights
    usort($rows, 'element_sort');
    //Add the submit button
    $row = array();
    $row[] = '';
    $row[] = drupal_render($form['submit']);
    $row[] = '';
    $rows[] = $row;
  }
  else {
    $rows[] = array(array('data' => t('No badges available.'), 'colspan' => '3'));
  }
  //This makes the table draggable
  drupal_add_tabledrag('user_badges_userweight', 'order', 'sibling', 'user_badges_userweight_element');
  //Theme all that we have processed so far into a table
  $output .= theme('table', $form['header']['#value'], $rows, array('id' => 'user_badges_userweight'));
  //Render any remaining form elements
  $output .= drupal_render($form);
/**
 * Menu callback; Retrieve a JSON object containing autocomplete suggestions for badges
 */
function user_badges_badge_autocomplete($string = '') {
  $matches = array();
  if (preg_match('/^[^(]+/', $string, $searchstring)) {
    $result = db_query_range("SELECT * FROM {user_badges_badges} WHERE name LIKE '%%%s%%'", $trimstring, 0, 10);
    while ($badge = db_fetch_object($result)) {
      $matches[$badge->name . ' (' . t('Badge ID') . ' ' . $badge->bid .')'] = check_plain($badge->name) . ' ' . theme('user_badge', $badge);
/**
 * Validates submissions for textfields that use user_badges_badge_autocomplete strings
 * @return array($bid,$result)
 * $bid
 *   the bid detected in the string (integer)
 *   for an invalid string, this will be NULL
 * $result
 *   'valid' for a valid string with a real bid
 *   'string' for an incorrectly formatted string
 *   'nobid' for a correctly formatted string with an invalid badge ID
 */
function user_badges_badge_autocomplete_validation($value) {
  if (preg_match('/\('. t('Badge ID') .' (\d+)\)/', $value, $matches)) {
    //The format was correct, but we need to check the bid exists
    if (db_result(db_query('SELECT COUNT(*) FROM {user_badges_badges} b WHERE b.bid=%d', $matches[1]))) {
      return array($matches[1], 'valid');
      return array($matches[1], 'nobid');
    }
  }
  else {
      //Pattern does not match, return the error code
      return array(NULL, 'string');
 * Define the page on user/uid/badges/edit.
function user_badges_page($uid) {
  $account = user_load($uid);
Heine's avatar
Heine committed
  drupal_set_title(t('Edit badges for %user_name', array('%user_name' => $account->name)));
  return drupal_get_form('user_badges_change_form', $account);
}

/**
 * Define the page on user/uid/badges.
 */
function user_badges_userweight_page($uid) {
  $account = user_load($uid);
  drupal_set_title(t('Badges for %user_name', array('%user_name' => $account->name)));
  // Do we have the right to rearrange badges?
  if (variable_get('user_badges_userweight', 0) && ($account->uid == $user->uid || user_access('change badge assignments')) ) {
    // If the setting allows it and we are the badge owner or somebody with permission, yes.
    return drupal_get_form('user_badges_userweight_form', $account);
  }
  else {
    // Otherwise, just list the badges on the page.
    $user_badges = user_badges_get_badges($account->uid);
    foreach ((array)$user_badges as $badge) {
      $badges[] = theme('user_badge', $badge, $account);
    }
      $badges = array(theme('item_list', $badges));
      return theme('user_badge_group', $badges);
    }
    else {
      return t('This user is not currently assigned any badges.');
    }
Heine's avatar
Heine committed
 */
function user_badges_change_form(&$form_state, $account) {
Heine's avatar
Heine committed
  $form = array();

  $form['uid'] = array(
    '#type' => 'value',
    '#value' => $account->uid,
  );
  $form['add'] = array(
    '#type' => 'fieldset',
    '#title' => t('Add Badges'),
    '#weight' => 3,
    '#collapsible' => TRUE,
    '#collapsed' => FALSE,
  );
  for ($i = 1; $i <= 5; $i++) {
    $form['add']['add'. $i] = array(
      '#type' => 'textfield',
      '#title' => t('New Badge !number', array('!number' => $i)),
      '#size' => 40,
      '#maxlength' => 255,
      '#autocomplete_path' => 'user_badges/autocomplete',
Heine's avatar
Heine committed
    );
  }
  if (count($account->badges_all)) {
    $form['remove'] = array(
      '#type' => 'fieldset',
      '#title' => t('Remove Badges'),
      '#weight' => 5,
      '#collapsible' => TRUE,
      '#collapsed' => FALSE,
    );
    foreach ($account->badges_all as $badge) {
      $form['remove'][$badge->bid] = array(
        '#type' => 'checkbox',
        '#title' => theme('user_badge', $badge, $account),
        '#return_value' => 1,
        '#default_value' => 0,
        '#description' => check_plain($badge->name),
      );
    }
  }
Heine's avatar
Heine committed
    '#type' => 'submit',
    '#value' => t('Update Badges'),
    '#weight' => 10,
Heine's avatar
Heine committed
  );
Heine's avatar
Heine committed
  return $form;
Heine's avatar
Heine committed
}

/**
 * Validate user_badges_remove_form form submissions.
 */
function user_badges_change_form_validate($form, &$form_state) {
  for ($i = 1; $i <= 5; $i++) {
    if (!empty($form_state['values']['add'. $i])) {
      $validation = user_badges_badge_autocomplete_validation($form_state['values']['add'. $i]);
      switch ($validation[1]) {
          form_set_error('add'. $i, t('@value is not a valid badge ID. Try using the autocomplete function (requires javascript).', array('@value' => $validation[0])));
          break;
        case 'string':
          form_set_error('add'. $i, t('"@value" is not a valid badge. Try using the autocomplete function (requires javascript).', array('@value' => $form_state['values']['add'. $i])));
          break;
      }
    }
  }
}

/**
 * Process user_badges_remove_form form submissions.
 *
 * Add the named badge. Remove the checked badges.
 */
function user_badges_change_form_submit($form, &$form_state) {
  $uid = $form_state['values']['uid'];
  //Add badges for non-empty fields
  for ($i = 1; $i <= 5; $i++) {
    if (!empty($form_state['values']['add'. $i])) {
      $validation = user_badges_badge_autocomplete_validation($form_state['values']['add'. $i]);
      user_badges_user_add_badge($uid, $validation[0], 'user');
  //Remove any checked badges
  $badges_to_go = array();
  foreach ($form_state['values'] as $bid => $value) {
    if (is_numeric($bid) && $value == 1) {
      $badges_to_go[] = $bid;
    }
  }
  if (count($badges_to_go)) {
    foreach ($badges_to_go as $bid) {
      user_badges_user_remove_badge($uid, $bid);
    }
    drupal_set_message(t('!removalcount badge(s) removed.', array('!removalcount' => count($badges_to_go))));
  }
Nuno Veloso's avatar
Nuno Veloso committed
 * @param $edit is an array containing badges array
 * @param $uid is the user id
 * @param $quiet suppresses message display
function user_badges_user_save($edit, $uid, $quiet = TRUE) {
  $badges = user_badges_get_badges($uid);
Heine's avatar
Heine committed
  if (is_array($edit)) {
    // an array of just the checked boxes please
    foreach ($edit as $bid => $is_selected) {
      if ($is_selected) {
Heine's avatar
Heine committed
        $newbadges[] = $bid;
    $success = TRUE;

    // what are the added badges?
    $added = array_diff($newbadges, array_keys($badges));
      if (!array_key_exists($bid, $badges)) {
Heine's avatar
Heine committed
        $success = (boolean) user_badges_user_add_badge($uid, $bid);
      }
    }

    // what are the removed badges?
    $removed = array_diff(array_keys($badges), $newbadges);
      if (array_key_exists($bid, $badges)) {
        $success = $success && (boolean) user_badges_user_remove_badge($uid, $bid);
      }
    }
    if ($success && !$quiet) {
      drupal_set_message(t('Badges saved.'));
    }
    elseif (!$quiet) {
      drupal_set_message(t('There was a problem saving badges to the database.'), 'error');
Heine's avatar
Heine committed
/**
 * Add a badge to user.
 *
Nuno Veloso's avatar
Nuno Veloso committed
 * @param $uid User ID.
 * @param $bid Badge ID.
 * @param $type Whether set as part of the role, or individually assigned ('user', 'role').
Nuno Veloso's avatar
Nuno Veloso committed
 * @return bool with query success
Heine's avatar
Heine committed
 */
function user_badges_user_add_badge($uid, $bid, $type = NULL) {
  // Integrate rules events.
  if (module_exists('rules')) {
    $arguments = array('user' => user_load($uid), 'badge_id' => $bid);
    rules_invoke_event('user_badges_badge_given', $arguments);
  }
  
  user_badges_user_remove_badge($uid, $bid, $type);
  return db_query('INSERT INTO {user_badges_user} (uid, bid, type) VALUES (%d, %d, \'%s\')', $uid, $bid, $type);
Nuno Veloso's avatar
Nuno Veloso committed

/**
 * remove a badge from user.
 *
 * @param $uid User ID.
 * @param $bid Badge ID.
 * @param $type Whether set as part of the role, or individually assigned ('user', 'role').
 *
 * @return bool with query success
 */
function user_badges_user_remove_badge($uid, $bid, $type = NULL) {
  // Integrate rules events.
  if (module_exists('rules')) {
    $arguments = array('user' => user_load($uid), 'badge_id' => $bid);
    rules_invoke_event('user_badges_badge_removed', $arguments);
  }
  
    return db_query('DELETE FROM {user_badges_user} WHERE uid=%d AND bid=%d', $uid, $bid);
  }
  else {
    return db_query('DELETE FROM {user_badges_user} WHERE uid=%d AND bid=%d AND type=\'%s\'', $uid, $bid, $type);
Nuno Veloso's avatar
Nuno Veloso committed

 * Return array of user badges where keys are badge ids (bid)
 *   and values are object containing badge info.
 *   if $uid is a user id, returns badges for that user.
 *   if $uid is 'all', returns all badges.
 *   if $uid is 'select', returns badges for form_select options.
 * @param $options array of options.
 *   $options['nolimit'] : if TRUE, the limit clause will not be applied for a user
 *   returned values for 'select' are just badge names.
function user_badges_get_badges($uid, $options = array()) {
  static $badges = array(), $past_uid, $past_options;
  if (isset($badges[$uid])) {
    return $badges[$uid];
  }
  // Do this so we don't return NULL.
  $badges[$uid] = array();

  if (empty($past_uid) || $past_uid !== $uid || $past_options !== $options ) {
    $past_uid = $uid;
    if ($uid == 'all' || $uid == 'select') {
      $sql = db_query('SELECT b.bid, b.weight, b.name, b.image, b.href,
        b.unhideable, b.fixedweight, b.doesnotcounttolimit, b.tid
Nuno Veloso's avatar
Nuno Veloso committed
      $usr = db_result(db_query('SELECT COUNT(uid) FROM {users} WHERE uid = %d AND status = 0', $uid));
Nuno Veloso's avatar
Nuno Veloso committed
      if ($usr && variable_get('user_badges_showblocked', 0)) {
        $sql = db_query('SELECT DISTINCT b.bid, b.weight, b.name, b.image, b.href,
          b.unhideable, b.fixedweight, b.doesnotcounttolimit, u.userweight, b.tid,
          CASE WHEN b.fixedweight = 1 THEN b.weight ELSE COALESCE(u.userweight,b.weight) END coalescedweight
          FROM {user_badges_badges} b
            INNER JOIN {user_badges_user} u ON b.bid = u.bid
Nuno Veloso's avatar
Nuno Veloso committed
            INNER JOIN {user_badges_roles} r ON b.bid = r.bid
          WHERE u.uid = %d AND r.rid = 0
          ORDER BY coalescedweight, b.name',
Nuno Veloso's avatar
Nuno Veloso committed
      }
      else {
        $query = 'SELECT DISTINCT b.bid, b.weight, b.name, b.image, b.href,
          b.unhideable, b.fixedweight, b.doesnotcounttolimit, u.userweight, b.tid,
          CASE WHEN b.fixedweight = 1 THEN b.weight ELSE COALESCE(u.userweight,b.weight) END coalescedweight
          FROM {user_badges_badges} b
            INNER JOIN {user_badges_user} u ON b.bid = u.bid
          WHERE u.uid = %d
Nuno Veloso's avatar
Nuno Veloso committed
      }
    // Should we limit the badges returned?
    if (!$options['nolimit'] && variable_get('user_badges_showone', 0)) {
      $limit = variable_get('user_badges_showone', 1);
    }
    else {
    while ($badge = db_fetch_object($sql)) {
      // Display the badge if there's no limit or if the badge is unhideable or if we are within our limit.
      if ($limit != 0 || $badge->unhideable == 1) {
          $badges[$uid][$badge->bid] = $badge->name;
          $badges[$badge->bid]['#attributes'] = array('class' => 'badge ' . _user_badges_class($badge));
          $badges[$uid][$badge->bid] = $badge;
          $badges[$uid][$badge->bid]->class = 'badge ' . _user_badges_class($badge);
        }
        //Count down our limit, unless the badge doesn't count towards it
        if (!$badge->doesnotcounttolimit) {
          $limit--;
        }
Nuno Veloso's avatar
Nuno Veloso committed

Jeff Robbins's avatar
Jeff Robbins committed
/**
 * Return badge object for given badge id
 */
Jeff Robbins's avatar
Jeff Robbins committed
function user_badges_get_badge($bid) {
  return db_fetch_object(db_query('SELECT * FROM {user_badges_badges} WHERE bid = %d', $bid));
}

Nuno Veloso's avatar
Nuno Veloso committed


function user_badges_delete_form($form_state, $bid) {
Heine's avatar
Heine committed
  if ($badge = user_badges_get_badge($bid)) {
    $form = array();
    $form['badge'] = array('#value' => theme('user_badge_group', array(theme('user_badge', $badge))));
    $form['bid'] = array('#type' => 'value', '#value' => $bid);
    return confirm_form($form, t('Are you sure you want to delete the badge %name?', array('%name' => $badge->name)), 'admin/user/user_badges');
Heine's avatar
Heine committed
  form_set_error('', t('This badge does not exist.'));
}

function user_badges_delete_form_submit($form, &$form_state) {
  $bid = $form_state['values']['bid'];
  db_query("DELETE FROM {user_badges_badges} WHERE bid = %d", $bid);
  db_query("DELETE FROM {user_badges_user} WHERE bid = %d", $bid);
  db_query("DELETE FROM {user_badges_roles} WHERE bid = %d", $bid);
Heine's avatar
Heine committed
  drupal_set_message(t('Badge deleted.'));
  $form_state['redirect'] = 'admin/user/user_badges';
Nuno Veloso's avatar
Nuno Veloso committed

 * Returns an array where keys are role ids (rid) and values are the badge ids (bid) associated with that role
 * These values are assigned on admin/user/user_badges/roles
 *
 * @param $rid - if set, return only values for this role
 * @param $options - array of options
 * $options['returnbadges'] - if TRUE, return badge objects, not just bids
Nuno Veloso's avatar
Nuno Veloso committed
 * @return a list of roles
function user_badges_get_roles($rid = NULL, $options = array()) {
  $roles = array();
  $options = array_merge(array('returnbadges' => 'FALSE'), $options);

  if ($rid) {
    $sql = db_query('SELECT ubr.rid, ubr.bid, ubb.name, ubb.image, ubb.weight, ubb.href, ubb.tid FROM {user_badges_roles} ubr INNER JOIN {user_badges_badges} ubb ON ubb.bid=ubr.bid WHERE ubr.rid = %d', $rid);
    $sql = db_query('SELECT ubr.rid, ubr.bid, ubb.name, ubb.image, ubb.weight, ubb.href, ubb.tid FROM {user_badges_roles} ubr INNER JOIN {user_badges_badges} ubb ON ubb.bid=ubr.bid', $rid);
  }
  while ($row = db_fetch_object($sql)) {
      $roles[$row->rid] = $row;
    }
    else {
      $roles[$row->rid] = $row->bid;
    }
 * Save information about roles for user_badges (in settings)
 * @param $roles
 *   An array in the format rid => bid for each role/badge relationship.
Heine's avatar
Heine committed
function user_badges_save_roles($roles) {
Heine's avatar
Heine committed
  if (is_array($roles)) {
    $success = TRUE;
    db_query('DELETE FROM {user_badges_roles}');
    db_query("DELETE FROM {user_badges_user} WHERE type='role'");
    // Now we loop through the roles and their badges, and assign them to
    // each user accordingly.
Heine's avatar
Heine committed
    foreach ($roles as $rid => $bid) {
      if ($bid) {
        // First of all, insert all the role and badge relationship
        // into user_badges_roles.
Heine's avatar
Heine committed
        $success = $success && db_query('INSERT INTO {user_badges_roles} (rid, bid) VALUES (%d, %d)', $rid, $bid);
        // For all of these queries, we LEFT JOIN user_badges_user to check
        // whether there are existing entries for that badge for that user
        // of the "role" type. Otherwise, we get database errors when
        // multiple roles assign the same badge
        // The blocked user "role" (represented as rid 0) has no entry in
        // the users_role table, so it needs its own special query.
Nuno Veloso's avatar
Nuno Veloso committed
        if ($rid == 0) {
          $success = $success && db_query("
            INSERT INTO {user_badges_user} (uid, bid, type)
            SELECT u.uid, %d, 'role'
            FROM {users} u
            LEFT JOIN {user_badges_user} ubu
            ON ubu.uid=u.uid AND ubu.bid=%d AND ubu.type='role'
            WHERE status = 0 AND ubu.uid IS NULL
Nuno Veloso's avatar
Nuno Veloso committed
        }
        // The authenticated user role (represented as rid 2) has no entry
        // in the users_role table, so it needs its own special query.
Nuno Veloso's avatar
Nuno Veloso committed
          $success = $success && db_query("
            INSERT INTO {user_badges_user} (uid, bid, type)
            SELECT u.uid, %d, 'role'
            FROM {users} u
            LEFT JOIN {user_badges_user} ubu
            ON ubu.uid=u.uid AND ubu.bid=%d AND ubu.type='role'
            WHERE u.uid > 0 AND ubu.uid IS NULL
          ", $bid, $bid);
        // For all the normal roles, we want to run this query.
Heine's avatar
Heine committed
        else {
Nuno Veloso's avatar
Nuno Veloso committed
          $success = $success && db_query("
            INSERT INTO {user_badges_user} (uid, bid, type)
            SELECT ur.uid, %d, 'role'
            FROM {users_roles} ur
            LEFT JOIN {user_badges_user} ubu
            ON ubu.uid=ur.uid AND ubu.bid=%d AND ubu.type='role'
            WHERE ur.rid=%d AND ubu.uid IS NULL
          ", $bid, $bid, $rid);
Heine's avatar
Heine committed
        }
      }
    }
    if ($success) {
      drupal_set_message(t('Roles saved.'));
    }
    else {
      drupal_set_message(t('There was a problem saving roles to the database'));
    }
  }
}