Skip to content
buddylist.module 32.9 KiB
Newer Older
/**
 * returns an array of common translation placeholders
 */
function buddylist_translation() {
	return array('%buddy' => t('buddy'),
	  '%Buddy' => t('Buddy'),
	  '%buddylist' => t('buddylist'),
	  '%buddies' => t('buddies'),
	  '%Buddies' => t('Buddies'),
	  '%buddiesof' => t('buddies of'),
	  '%Buddylist' => t('Buddylist'),
	);
}

/**
 * Implementation of hook_help
 */
function buddylist_help($section) {
  switch ($section) {
    case 'admin/modules#description':
      return t('Enable %buddy list functionality.', array('%buddy' => t('buddy')));
	  case 'admin/help#buddylist':
      $output = t("
<p>%Buddy list enables users to keep a list of %buddies from their social network in their user account.  Users can also track what their %buddies are posting to the site.  Furthermore, they can track their <i>%buddies'</i> %buddies and thereby explore their social network.</p>
<p>If the administrator has enabled the profile module, users can add %buddies via their %buddies' user profiles.   On the \"View\" tab of each user's profile, there is a \"%Buddy list\" section.  Select the 'add %buddy' action to add the user to your %buddy list.  If a user is already in your %buddy list, the 'delete' action will remove the %buddy. Administrators can also enable the %buddylist block.  This block allows you to see a list of your %buddies. If the Friends Of A Friend (FOAF) module is enabled, it will be possible to share %buddy lists with other FOAF-aware social networking applications.</p>
<li>add a %buddy by looking at their profile: <a href = \"%Userprofiles\" title = \"View user profiles\">view user profiles</a></li>
<li>allow users to view profiles in <a href = \"%setaccesspermissions\" title = \"set access permissions\"> administer &raquo; access control</a></li>
<li>enable the %buddy list block at <a href = \"%blockadministration\" title = \"block administration\">administer &raquo; block</a></li>
<li>administer the %buddy list block at <a href = \"%buddylistsettings\" title = \"%buddylist settings\">administer &raquo; settings &raquo; %buddylist</a></li>
<p>For more information, read the configuration and customization handbook <a href=\"http://drupal.org/handbook/modules/Buddylist\" title=\"Buddylist page\">Buddylist page</a></p>",
array('%Userprofiles' => url('profile'),
      '%setaccesspermissions' => url('admin/access/permission'),
      '%blockadministration' => url('admin/block'),
      '%buddylistsettings' => url('admin/settings/buddylist')
      return $output;
  }
}


/**
 * Implementation of hook_perm
 */
function buddylist_perm() {
  return array('maintain buddy list', 'view buddy lists');
}

/**
 * Implementation of hook_menu
 */
function buddylist_menu($may_cache) {
  global $user;

  $links = array();
  $id = is_numeric(arg(1)) ? arg(1) : $user->uid;
  if ($may_cache) {
    $links[] = array('path' => 'buddylist', 'title' => t('my %buddylist', buddylist_translation()), 'access' => (user_access('view buddy lists') && $user->uid), 'callback' => 'buddylist_buddylisting_page');
  }
  elseif ($id == $user->uid || user_access('administer users')) {
    //tabs
      $links[] = array('path' => 'buddylist/'. $id .'/buddies', 'title' => t('%buddies', buddylist_translation()), 'access' => user_access('view buddy lists'), 'callback' => 'buddylist_buddylisting_page', 'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -1, 'callback arguments' => array($id));
      $links[] = array('path' => 'buddylist/'. $id .'/buddiesof', 'title' => t('%buddiesof', buddylist_translation()), 'access' => user_access('view buddy lists'), 'callback' => 'buddylist_buddylisting_page','type' => MENU_LOCAL_TASK, 'weight' => 1, 'callback arguments' => array($id, 'buddiesof'));
    // subtabs
      $links[] = array('path' => 'buddylist/'. $id .'/buddies/list', 'title' => t('list'), 'access' => user_access('view buddy lists'), 'callback' => 'buddylist_buddylisting_page', 'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -1, 'callback arguments' => array($id));
      $links[] = array('path' => 'buddylist/'. $id .'/buddies/recent', 'title' => t('recent posts'), 'access' => (user_access('view buddy lists') && module_exist('tracker')), 'callback' => 'buddylist_buddiesrecent_page', 'type' => MENU_LOCAL_TASK, 'weight' => 1, 'callback arguments' => array($id));
      $links[] = array('path' => 'buddylist/'. $id .'/buddies/groups/view', 'title' => t('view groups'), 'access' => user_access('view buddy lists'), 'callback' => 'buddylist_buddiesgroups_page', 'type' => MENU_LOCAL_TASK, 'weight' => 2, 'callback arguments' => array($id));
      $links[] = array('path' => 'buddylist/'. $id .'/buddies/groups/edit', 'title' => t('edit groups'), 'access' => user_access('maintain buddy list'), 'callback' => 'buddylist_buddiesgroups_form', 'type' => MENU_LOCAL_TASK, 'weight' => 3, 'callback arguments' => array($id));
    // RSS feeds
      $links[] = array('path' => 'buddylist/'. $id .'/buddies/recent/feed', 'title' => t('xml feed'), 'access' => user_access('view buddy lists'), 'callback' => 'buddylist_buddyfeed', 'type' => MENU_CALLBACK, 'callback arguments' => array($id));
    // other callbacks
      $links[] = array('path' => 'buddy/add', 'title' => t('add to buddylist'), 'access' => user_access(t('maintain %buddy list', buddylist_translation())), 'callback' => 'buddylist_addbuddy', 'callback arguments' => arg(2), 'type' => MENU_CALLBACK);
      $links[] = array('path' => 'buddy/delete', 'title' => t('delete from %buddylist', buddylist_translation()), 'access' => user_access('maintain buddy list'), 'callback' => 'buddylist_deletebuddy', 'callback arguments' => arg(2), 'type' => MENU_CALLBACK);
  return $links;
}

/**
 * Implementation of hook_settings
 */
function buddylist_settings() {
  // TODO: move these to block settings
  $form['block_settings'] = array(
    '#type' => 'fieldset',
    '#title' => t('%Buddylist block options', buddylist_translation()),
  );
  $form['block_settings']['buddylist_blocklisting_size'] = array(
    '#type' => 'select',
    '#title' => t("Number of %buddies to list in the user's %buddy block", buddylist_translation()),
    '#default_value' => variable_get('buddylist_blocklisting_size', 5),
    '#options' => drupal_map_assoc(array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20, 25, 30)),
    '#description' => t('This setting controls the maximum number of %buddies displayed in a user\'s "%buddylist block" given that the "%buddylist block" is enabled in the %link.', array('%link' => l(t('block settings'), 'admin/block')) + buddylist_translation()),
  );
  $form['block_settings']['buddylist_posts_block'] = array(
    '#type' => 'select',
    '#title' => t("Number of posts to list in the %buddies' recent posts block", buddylist_translation()),
    '#default_value' => variable_get('buddylist_posts_block', 7),
    '#options' => drupal_map_assoc(array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20, 25, 30)),
    '#description' => t('This setting controls the maximum number of posts to display in a user\'s "%buddy recent posts" block given that the "%buddies\' recent posts" block is enabled in the %link.', array('%link' => l(t('block settings'), 'admin/block')) + buddylist_translation()),
  );
  $form['block_settings']['buddylist_list_block_title'] = array(
    '#type' => 'textfield',
    '#title' => t('"My %buddies list" block title', buddylist_translation()),
    '#default_value' => variable_get('buddylist_list_block_title', t('My buddy list')),
    '#size' => 70,
    '#maxlength' => 128,
    '#description' => t('This will be the title for the "My %buddy list" block. If none is specified, "My %buddy list" will be used.', buddylist_translation()),
  );
  $form['block_settings']['buddylist_block_title'] = array(
    '#type' => 'textfield',
    '#title' => t('"My %buddies\' recent posts" block title', buddylist_translation()),
    '#default_value' => variable_get('buddylist_block_title', t("My %buddies' recent posts", buddylist_translation())),
    '#description' => t('This will be the title for the recent %buddies post block. If none is specified, "My %buddies\' recent posts" will be used.', buddylist_translation()),
  // User profile page settings
  $form['profile_settings'] = array(
    '#type' => 'fieldset',
    '#title' => t('Profile page options'),
  );
  $form['profile_settings']['buddylist_prof_buddies'] = array(
    '#type' => 'select',
    '#title' => t('Number of %buddies and users who\'ve added me', buddylist_translation()),
    '#default_value' => variable_get('buddylist_prof_buddies', 5),
    '#options' => drupal_map_assoc(range(0, 10)),
    '#description' => t('The default maximum number of %buddies and users who\'ve added me as a %buddy to display on a user\'s profile page.', buddylist_translation()),
  );

  return $form;
}


/**
 * Implementation of hook_user
 */
function buddylist_user($type, &$edit, &$thisuser, $category = NULL) {
  global $user;

  $output = array();
  // show any buddylist notifications upon login and upon viewing own profile
  if (user_access('view buddy lists') && (($type == 'login') || ($type == 'view') && ($thisuser->uid == $user->uid))) {
    buddylist_setmsg_received($thisuser);
  }

  if ($type == 'view' && user_access('view buddy lists')) {
    // if thisuser has friends, show friends
    $cnt = variable_get('buddylist_prof_buddies', 5);
    $i = 0;
    if ($buddies = buddylist_get_buddies($thisuser->uid)) {
      foreach(array_keys($buddies) as $buddy) {
        $account = user_load(array('uid' => $buddy));
				$listbuddies[] = $account;
        $i++;
        if ($i > $cnt) {
          break;
        }
      }
      $output[] = array('title' => t('%Buddies', buddylist_translation()), 'value' => theme('user_list', $listbuddies), 'class' => 'buddylist',);
    }

    // This portion of code is used to see if this $thisuser is a buddy of others and, if s/he is, returns a list
    // of people s/he is a buddy of.
    // Note the distinction between having a buddy and being someone else's buddy (i.e., 'buddyof')
    $sql = 'SELECT b.uid, u.name FROM {buddylist} b INNER JOIN {users} u ON b.uid = u.uid WHERE b.buddy = %d ORDER BY u.access DESC';
    $result = db_query_range($sql, $thisuser->uid, 0, $cnt);
    while ($row = db_fetch_object($result)) {
      $listbuddiesof[$row->uid] = $row;
    }
    if ($listbuddiesof) {
      $output[] = array('title' => t('%Buddy of', buddylist_translation()), 'value' => theme('user_list', $listbuddiesof));
    }

    // Check to see whether or not $thisuser is in global $user's buddy list
    // If $thisuser is already in $user's buddy list, a link offering to delete $thisuser from $user's buddy list is generated
    // If $thisuser is not on $user's buddy list, and $thisuser != $user, then a link offering to add $thisuser to $user's buddy list
    // is generated.
    if (@in_array($thisuser->uid, array_keys(buddylist_get_buddies($user->uid))) && user_access('maintain buddy list')) {
      $actions[] = theme('remove_from_buddylist_link', $thisuser);
    }
    else {
      if ($user->uid != $thisuser->uid && user_access('maintain buddy list')) {
        $actions[] = theme('add_to_buddylist_link', $thisuser);
      }
    }
    if ($actions) {
      $output[] = array('title' => t('%Buddy actions', buddylist_translation()), 'value' => theme('item_list', $actions), 'class' => 'buddylist');
      return array(t('%Buddy List', buddylist_translation()) => $output);
  }
}


/**
 * Implementation for hook_block
 */
function buddylist_block($op = 'list', $delta = 0) {
  global $user;

  if ($op == 'list') {
    $block[0]['info'] = variable_get('buddylist_list_block_title', t('My %buddy list', buddylist_translation()));
    $block[1]['info'] = variable_get('buddylist_block_title', t('My %buddies\' recent posts', buddylist_translation()));
    return $block;
  }
  else if ($op == 'view' && user_access('access content') && $user->uid > 0) {
    switch ($delta) {
      case 0 : // Shows buddylist block
        if ($buddies = buddylist_get_buddies()) {
        	$i = 0;
          foreach (array_keys($buddies) as $buddy) {
            $users[] = user_load(array('uid' => $buddy));
            $i++;
            if ($i == variable_get('buddylist_blocklisting_size', 5)) {
              break;
            }
          }

          $block['content'] = theme('user_list', $users);
          $block['subject'] = variable_get('buddylist_list_block_title', t('My %buddy list', buddylist_translation()));
          // check if a "more" link should generated by seeing if there are more buddies than the specified $upperlimit
          if (count($buddies) > variable_get('buddylist_blocklisting_size', 5)) {
            $block['content'] .=  '<div class="more-link">' . l(t('more'), 'buddylist', array('title' => t('View more.'))) . '</div>';
          }
          return $block;
        }
        break;

      case 1: // Shows my buddies recent posts block
        $buddies = buddylist_get_buddies();
        $keys = array_keys($buddies);
        if (count($keys) > 0) {
          $str_buddies = implode(',', $keys);
          $result = db_query_range(db_rewrite_sql("SELECT n.nid, n.status, n.type, u.uid, u.name, n.created, n.title FROM {node} n INNER JOIN {users} u ON n.uid = u.uid WHERE n.status = 1 AND n.uid IN ($str_buddies) ORDER BY n.nid DESC"), 0, variable_get('buddylist_posts_block', 7));

          if (db_num_rows($result)) {
            $block['subject'] = variable_get('buddylist_block_title', t('My %buddies\' recent posts', buddylist_translation()));
            $block['content'] = node_title_list($result);

            // check if a "more" link should generated by seeing if there are more buddies than the specified $upperlimit
            $result = db_query(db_rewrite_sql('SELECT COUNT(n.nid) AS node_count FROM {buddylist} b LEFT JOIN {node} n ON n.uid=b.buddy LEFT JOIN {users} u ON n.uid = u.uid WHERE n.status = 1 AND b.uid=%d'), $user->uid);
            $countresult = db_fetch_object($result);

            if (variable_get('buddylist_posts_block', 7) < $countresult->node_count) {
              $block['content'] .= '<div class="more-link">'. l(t('more'), 'buddylist/'. $user->uid .'/buddies/recent', array('title' => t('View more.'))) .'</div>';
            }
            return $block;
          }
        }
        break;
    }
  }
}


/**
 *  Implements a simple single select box suitable for use in a block
 *  or in theme, or in another module, for example.
 */
function buddylist_select() {
  global $user;

  if ($buddies = buddylist_get_buddies()) {
    foreach (array_keys($buddies) as $uid) {
      $account = user_load(array('uid' => $uid));
			$options[$account->uid] = $account->name;
    }
    $form['buddy'] = array(
      '#type' => 'select',
      '#default_value' => $edit['buddy'] ? $edit['buddy'] : '',
      '#options' => $options,
    );
    return $form;
  }
}

/**
 *  Implements a simple single select box suitable for use in a block
 *  or in theme, or in another module, for example.
 */
function buddylist_groups_select($uid, $desc, $edit = array()) {
  if ($buddies = buddylist_get_buddies($uid, 'label')) {
    $labels = array_keys($buddies);
		$options = drupal_map_assoc($labels);
		unset($options['all']);
    if ($options) {
      $form['buddylist_groups'] = array(
        '#type' => 'select',
        '#title' => t('%Buddy groups', buddylist_translation()),
        '#default_value' => $edit['buddylist_groups'],
        '#options' => $options,
        '#description' => $desc,
        '#multiple' => TRUE,
      );
			return $form;
    }
  }
}

/**
 * Public API for retrieving buddies. Feel free to use this from other
 * modules.
 * $key can be 'uid' or 'label'.
*/
function buddylist_get_buddies($uid = NULL, $key = 'uid') {
  static $buddies;

  if (!$uid) {
    global $user;
    $uid = $user->uid;
  }
  if (!isset($buddies[$key][$uid])) {
    $buddies[$key][$uid] = array();
    $sql = 'SELECT b.buddy, u.name, u.mail FROM {buddylist} b
            INNER JOIN {users} u ON b.buddy = u.uid
            WHERE b.uid = %d';
    $result = db_query($sql, $uid);
    while ($row = db_fetch_object($result)) {
			$buddies[$key][$uid][$row->buddy]['name'] = $row->name;
			$buddies[$key][$uid][$row->buddy]['mail'] = $row->mail;
			$buddies[$key][$uid][$row->buddy]['groups'] = buddylist_get_buddy_groups($uid, $row->buddy);
    }
  }

  return $buddies[$key][$uid];
}

function buddylist_get_buddy_groups($uid, $buddy) {
	$result = db_query("SELECT bg.label_id, bg.label, bg.visible FROM {buddylist_groups} bg INNER JOIN {buddylist_buddy_group} bbg ON bbg.uid = bg.uid WHERE bbg.uid = %d AND bbg.buddy = %d AND bg.label_id = bbg.label_id", $uid, $buddy);
  $buddy_groups = array();
  while ($row = db_fetch_array($result)) {
  	$buddy_groups[] = $row;
  }
  return $buddy_groups;
}



function buddylist_setmsg_received($thisuser) {
  global $user;

  $check_received = db_query('SELECT received, b.uid as uid, u.name FROM {buddylist} b LEFT JOIN {users} u ON u.uid = b.uid WHERE buddy = %d AND received = 1', $thisuser->uid);
  while ($rec = db_fetch_object($check_received)) {
    if (($rec->received) and ($thisuser->uid == $user->uid)) {
      // TODO: This is where integration with Privatemsg could happen. If enabled, send a private message instead.
      drupal_set_message(t('%linktouser has added you to his/her %buddylist.', array('%linktouser' => l($rec->name, 'user/'. $rec->uid)) + buddylist_translation()));
      db_query('UPDATE {buddylist} SET received = 0 WHERE buddy = %d', $user->uid);
    }
  }
}

/**
 * expose add and remove links to theming.
 */
function theme_remove_from_buddylist_link($buddyuser) {
  return l(t('Remove %name from my %buddy list', array('%name' => theme('placeholder', $buddyuser->name)) + buddylist_translation()), 'buddy/delete/' . $buddyuser->uid, NULL, drupal_get_destination(), NULL, FALSE, TRUE);
}

function theme_add_to_buddylist_link($buddyuser) {
	return l(t('Add %name to my %buddy list', array('%name' => theme('placeholder', $buddyuser->name)) + buddylist_translation()), 'buddy/add/' . $buddyuser->uid, NULL, drupal_get_destination(), NULL, FALSE, TRUE);
}


/**
 * Displays a list of a given user's buddies.
 */
function buddylist_buddylisting_page($uid = NULL, $mode = 'buddies') {
  global $user;

  if (!module_exist('profile')) {
    drupal_set_message(t('The %buddylist module requires the profile module to be enabled in order to use this functionality', buddylist_translation()), 'error');
  }
  if (empty($uid)) {
    $uid = $user->uid;
  }
	elseif ($uid != $user->uid && !user_access('administer users')) {
    // a normal user can only view own buddylist
    drupal_access_denied();
    exit();
  }

  $thisuser = user_load(array('uid' => $uid));
  drupal_set_title(t('%username\'s %buddylist', array('%username' => $thisuser->name) + buddylist_translation()));

  $output = '<div class="members">';

  $buddies_per_page = 20;

  // Compile a list of fields to show
  $fields = array();
  $result = db_query('SELECT name, title, type FROM {profile_fields} WHERE visibility = %d', PROFILE_PUBLIC_LISTINGS);
  while ($record = db_fetch_object($result)) {
    $fields[] = $record;
  }

  //TODO: use the get_buddies function instead
  if ($mode == 'buddies') {
    $sql = "SELECT DISTINCT(buddy) FROM {buddylist} b INNER JOIN {users} u ON b.buddy = u.uid WHERE b.uid = %d ORDER BY u.access DESC";
  }
  else {
    $sql = "SELECT DISTINCT(u.uid) as buddy FROM {buddylist} b INNER JOIN {users} u ON b.uid = u.uid WHERE b.buddy = %d ORDER BY u.access DESC";
  }
  $result = pager_query($sql, $buddies_per_page, 0 , NULL, $uid);

  $output .= '<div id="profile">';

  if (db_num_rows($result)) {
    while ($account = db_fetch_object($result)) {
      $output .= theme('profile_listing', user_load(array('uid' => $account->buddy)), $fields);
    }
  }
  else {
    $output .= t('none');
  }
  $output .= '</div>';
  $output .= theme('pager', NULL, $buddies_per_page);

  $output .= '</div>';
  return $output;
}

function buddylist_buddiesrecent_page($uid) {
  global $user;

  $thisuser = user_load(array('uid' => $uid));
  drupal_set_title(t('%username\'s %buddylist', array('%username' => $thisuser->name) + buddylist_translation()));

  $buddies = buddylist_get_buddies($uid);
  foreach ($buddies as $user_id => $buddy) {
  	$form[] = array('#type' => 'fieldset',
  	  '#title' => $buddy['name'],
  	  '#collapsible' => 'true',
  	  '#value' => tracker_page($user_id),
  	);
  }

  $output .= drupal_get_form('buddies_recent', $form);
  $output .= theme('xml_icon', url('buddylist/'. $uid .'/buddies/recent/feed'));
  drupal_set_html_head('<link rel="alternate" type="application/rss+xml" title="'. t('RSS - %buddies posts', buddylist_translation()). '" href="'. url('buddylist/'. $user->uid .'/buddies/recent/feed') .'" />');
  return $output;
}

function buddylist_buddiesgroups_page($uid) {
  $thisuser = user_load(array('uid' => $uid));
  drupal_set_title(t('%username\'s %buddy groups', array('%username' => $thisuser->name) + buddylist_translation()));
  $headers = array(t('%buddy', buddylist_translation()), t('# of %buddies', buddylist_translation()), t("%buddy's posts", buddylist_translation()));
  $result = db_query('SELECT DISTINCT(label), label_id FROM {buddylist_groups} WHERE uid = %d ORDER BY label ASC', $thisuser->uid);
  $groups = array();
  while ($row = db_fetch_object($result)) {
  	$groups[$row->label_id] = $row->label;
  }
  	drupal_set_message(t("You don't have any groups defined. To organize your %buddies into groups, visit the %edit_groups page", array('%edit_groups' => l(t('edit_groups'), "buddylist/$uid/buddies/groups/edit")) + buddylist_translation()));
  $buddies = buddylist_get_buddies($thisuser->uid);

  foreach ($groups as $label_id => $label) {
  	$result = pager_query('SELECT buddy FROM {buddylist_buddy_group} WHERE uid = %d and label_id = %d', 10, 0, NULL, $thisuser->uid, $label_id);
  	$rows = array();
  	while ($row = db_fetch_object($result)) {
  		$rows[] = array(
  		  l($buddies[$row->buddy]['name'], 'user/'.$row->buddy),
  		  buddylist_count_buddies($row->buddy),
  		  l(t('view posts'), 'user/'. $row->buddy. '/track')
  		);
  	}
  	if (count($rows) > 0) {
  		$form[] = array('#type' => 'fieldset',
  		  '#collapsible' => 'true',
  		  '#title' => $label,
  		  '#value' => theme('table', $headers, $rows),
  		);
  	}
  }
	return drupal_get_form('groups_tables', $form);
}

function buddylist_count_buddies($uid) {
	$result = db_query("SELECT count(DISTINCT buddy) AS buddies FROM {buddylist} WHERE uid = %d", $uid);
	return db_result($result);
}

function buddylist_buddiesgroups_form($uid) {
  $thisuser = user_load(array('uid' => $uid));
  drupal_set_title(t('%username\'s %buddy groups', array('%username' => $thisuser->name) + buddylist_translation()));
  if ($buddies = buddylist_get_buddies($thisuser->uid)) {

    // Add group form
    $form['add'] = array('#type' => 'fieldset',
      '#title' => t('Add a group'),
      '#collapsible' => true,
    );
    $form['add']['add_group'] = array(
      '#type' => 'textfield',
      '#title' => t('Add new group'),
    );
    $form['add']['submit'] = array(
      '#type' => 'submit',
      '#value' => t('Add'),
    );
    $output['add'] = drupal_get_form('buddylist_edit_groups_add', $form['add']);

    // Get all groups
    $result = db_query("SELECT label_id, label FROM {buddylist_groups} WHERE uid = %d ORDER BY label ASC", $uid);
    $all_groups = array();
    while ($row = db_fetch_object($result)) {
    	if ($row->label != '') {
    	  $all_groups[$row->label_id] = $row->label;
    	}
    }
    if (count($all_groups) > 0) {
      // Make a form to remove groups
      $form['remove'] = array('#type' => 'fieldset',
        '#title' => t('Remove groups'),
        '#collapsible' => true,
      );
      $form['remove']['groups'] = array(
        '#type' => 'checkboxes',
        '#return_value' => 1,
        '#title' => '',
        '#default_value' => null,
        '#options' => $all_groups,
      );
      $form['remove']['submit'] = array(
        '#type' => 'submit',
        '#value' => t('Remove'),
      );
    $output['remove'] = drupal_get_form('buddylist_edit_groups_remove', $form['remove']);
    }
    // Build the table with buddies and their groups
    foreach ($buddies as $uid => $buddy) {
      $items = array();
      foreach ($buddy['groups'] as $group) {
        $items[] = $group['label_id'];
      if (count($all_groups) > 0) {
        $form['table']['groups'][$uid] = array(
          '#type' => 'checkboxes',
          '#title' => '',
          '#return_value' => '1',
          '#default_value' => $items,
          '#options' => $all_groups,
        );
      }
    }

    $form['table']['user'] = array(
      '#type' => 'value',
      '#value' => $thisuser->uid,
    );
    if (count($form['table']['groups']) == 0) {
  	  drupal_set_message(t("You don't have any groups defined."));
    }
    else {
      $form['table']['submit'] = array(
        '#type' => 'submit',
        '#value' => t('Submit'),
      );
      $output['table'] = drupal_get_form('buddylist_edit_groups_table', $form['table']);
    }
    return theme('buddylist_edit_groups_form', $output);
  }
  else {
    return theme('placeholder',t('Unable to edit %buddy groups. No %buddies found.', buddylist_translation()));
  }
}

function theme_buddylist_edit_groups_form($forms) {
	$output = '<table><tr><td>'.
	            $forms['add'].
            '</td><td>'.
              $forms['remove'].
            '</td></tr></table>'.
              $forms['table'];
  return $output;
}


function theme_buddylist_edit_groups_table($form) {
  $rows = array();

  foreach ($form['groups'] as $key => $value) {
    if(is_numeric($key)) {
      $rows[] = array(theme('username', user_load(array('uid' => $key))), form_render($form['groups'][$key]));
    }
  }

  $headers = array(t('buddy'), t('%buddy groups', buddylist_translation()));
  $output .= theme('table', $headers, $rows);
  $output .= form_render($form);

  return $output;
}

function buddylist_edit_groups_add_submit($form_id, $form_values) {
  global $user;
  $label_id = buddylist_buddygroup_new($user->uid, $form_values['add_group']);
}

function buddylist_edit_groups_remove_submit($form_id, $form_values) {
  global $user;
  foreach ($form_values['groups'] as $label_id => $remove) {
    if ($remove > 0) {
      buddylist_buddygroup_remove($user->uid, $label_id);
    }
  }
}

function buddylist_edit_groups_table_submit($form_id, $form_values) {
  $userid = $form_values['user'];
  unset($form_values['user']);

  foreach ($form_values as $buddy => $groups) {
    foreach ($groups as $label_id => $checked) {
    	if ($checked == 0) {
    		buddylist_buddygroup_remove_buddy($userid, $buddy, $label_id);
    	}
    	else {
    		buddylist_buddygroup_add_buddy($userid, $buddy, $label_id);
    	}
    }
  }

  drupal_set_message(t('%buddy groups saved.', buddylist_translation()));
}

/**
 * Creates a new buddy group for a user
 *
 * @param $uid user id of the user to whom the group will belong.
 * @param $group string; name of the group
 * @param $visible determines whether the user's buddies can see which groups they've been put in.
 * @return $label_id the existing or newly created id for the name of this group.
 */
function buddylist_buddygroup_new($uid, $group, $visible = FALSE) {
  $label_id = db_result(db_query("SELECT label_id FROM {buddylist_groups} WHERE uid = %d AND label = '%s'", $uid, $group));
  if (is_null($label_id)) {
  	$new_label_id = db_next_id('buddygroup');
  	db_query("INSERT INTO {buddylist_groups} VALUES (%d, %d, '%s', %d)", $uid, $new_label_id, $group, $visible);
    return $new_label_id;
  }
  else {
  	return $label_id;
  }
}

/**
 * Removes a buddy group for a user
 *
 * @param $uid user id of the user to whom the group belongs.
 * @param $label_id id of the group
 */
function buddylist_buddygroup_remove($uid, $label_id) {
  db_query("DELETE FROM {buddylist_groups} WHERE uid = %d AND label_id = %d", $uid, $label_id);
  db_query("DELETE FROM {buddylist_buddy_group} WHERE uid = %d AND label_id = %d", $uid, $label_id);
}

function buddylist_buddygroup_remove_buddy($uid, $buddy, $label_id) {
	db_query("DELETE FROM {buddylist_buddy_group} WHERE uid = %d AND buddy = %d AND label_id = %d", $uid, $buddy, $label_id);
}

function buddylist_buddygroup_add_buddy($uid, $buddy, $label_id) {
  db_lock_table('buddylist_buddy_group');
  buddylist_buddygroup_remove_buddy($uid, $buddy, $label_id);
  db_query('INSERT INTO {buddylist_buddy_group} VALUES (%d, %d, %d)', $uid, $buddy, $label_id);
  db_unlock_tables();
}

/**
 * Feed for buddies recent posts
 */
function buddylist_buddyfeed($uid) {
	$buddy_ids = array_keys(buddylist_get_buddies($uid));
	// false query to be used if no posts from buddies are available (as in this user has no buddies).
  $result = db_query('SELECT nid FROM {node} WHERE 0');
	if (count($buddy_ids > 0)) {
		$buddy_ids_str = '('. implode(',', $buddy_ids). ')';
	  $result = db_query(db_rewrite_sql('SELECT nid FROM {node} WHERE status = 1 AND uid IN %s ORDER BY nid DESC'), $buddy_ids_str);
	}
  $channel['title'] = t('%Buddies recent posts on %site', array('%site' => variable_get('site_name', 'drupal')) + buddylist_translation());
  $channel['link'] = url('buddylist/'. $uid .'/buddies/recent', NULL, NULL, TRUE);

  node_feed($result, $channel);
}


function buddylist_addbuddy($uid) {
  $buddy = user_load(array('uid' => $uid));
  if (empty($buddy->name)) {
    return t('This user does not exist');
  }
  elseif (in_array($uid, array_keys(buddylist_get_buddies($user->uid)))) {
    return t('This user is already on your %buddy list', buddylist_translation());
    return t('Cannot add yourself to %buddy list', buddylist_translation());
  }

  $form['uid'] = array('#type' => 'hidden', '#value' => $uid);
  $form['name'] = array('#type' => 'hidden', '#value' => $buddy->name);
  return confirm_form('buddylist_addbuddy_confirm',
    t('Add user %name to your %buddy list?', array('%name' => theme('placeholder', $buddy->name)) + buddylist_translation()),
    $_GET['destination'],
    ' ',
    t('Add'), t('Cancel'));
}

/**
 * Confirm and add a buddy.
 */
function buddylist_addbuddy_confirm_submit($form_id, $form_values) {
	buddylist_add($form_values['uid']);
	drupal_set_message(t('%name will be be notified the next time s/he logs in.', array('%name' => theme('placeholder', $form_values['name']))));
  return 'user';
};

Robert Douglass's avatar
Robert Douglass committed
/**
 * Removes the user $uid from the global user's account.
 * TODO: generalize this so that two uids can be given
 */
function buddylist_deletebuddy($uid) {
  global $user;
Robert Douglass's avatar
Robert Douglass committed
  $uid = (int)$uid;
  $buddy = user_load(array('uid' => $uid));

  if (empty($buddy->name)) {
    return t('This user does not exist');
  }
  else if (!in_array($uid, array_keys(buddylist_get_buddies($user->uid)))) {
    return t('This user is not on your %buddy list', buddylist_translation());
  }

  $form['uid'] = array('#type' => 'hidden', '#value' => $uid);
  $form['name'] = array('#type' => 'hidden', '#value' => $buddy->name);
  return confirm_form('buddylist_deletebuddy_confirm',
    t('Remove user %name from your %buddy list?', array('%name' => theme('placeholder', $buddy->name)) + buddylist_translation()),
    $_GET['destination'],
    ' ',
    t('Remove'), t('Cancel'));
}


/**
 * Confirm and add a buddy.
 */
function buddylist_deletebuddy_confirm_submit($form_id, $form_values) {
	buddylist_remove($form_values['uid']);
	drupal_set_message(t('%name will be be notified of being removed.', array('%name' => theme('placeholder', $form_values['name']))));
  return 'user';
};


function buddylist_add($id) {
  global $user;
  $user_to_add = user_load(array('uid' => $id));

  if (!in_array($id, array_keys(buddylist_get_buddies($user->uid)))) {
    db_query('INSERT INTO {buddylist} (received, uid, buddy, timestamp) VALUES (1, %d, %d, %d)' , $user->uid , $id , time());
    // DB value buddylist.received set to 1, meaning buddy has a message waiting
    // letting them know you added them as a buddy
    // buddylist.received set back to 0 when user logs in along with being informed of new buddy

    drupal_set_message(t('%username has been added to your %buddy list', array('%username' => theme('placeholder', $user_to_add->name)) + buddylist_translation()));
    drupal_set_message(t('%username is already on your %buddylist', array('%username' => theme('placeholder', $user_to_add->name)) + buddylist_translation()));
  }
}

function buddylist_remove($id) {
  global $user;
  db_query('DELETE FROM {buddylist} WHERE uid = %d AND buddy = %d' , $user->uid , $id);
  $thisuser = user_load(array('uid' => $id));
  drupal_set_message(t('%username has been removed from your %buddylist', array('%username' => theme('placeholder', $thisuser->name )) + buddylist_translation()));
}

function buddylist_cancel_add($id) {
  $thisuser = user_load(array('uid' => $id));
  drupal_set_message(t('User %name was NOT added to your %buddylist.', array('%name' => theme('placeholder', $thisuser->name)) + buddylist_translation()));
}

function buddylist_cancel_remove($id) {
  $thisuser = user_load(array('uid' => $id));
  drupal_set_message(t('User %name was NOT removed from your %buddylist.', array('%name' => theme('placeholder', $thisuser->name)) + buddylist_translation()));