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 buddies' buddies and thereby explore their social network.

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.

You can

For more information, read the configuration and customization handbook Buddylist page

", array('%Userprofiles' => url('/profile'), '%setaccesspermissions' => url('admin/access/permission'), '%blockadministration' => url('admin/block'), '%buddylistsettings' => url('admin/settings/buddylist') )); return $output; } } /** * 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[$uid][$key])) { $buddies[$uid][$key] = array(); $sql = "SELECT b.buddy as uid, b.label, u.name, u.mail FROM {buddylist} b INNER JOIN {users} u ON b.buddy = u.uid WHERE b.uid = %d ORDER BY b.timestamp, b.label DESC"; $result = db_query($sql, $uid); while ($row = db_fetch_object($result)) { $nonkey = $key == 'uid' ? 'label' : 'uid'; $buddies[$uid][$key][$row->$key][$row->$nonkey] = (object) array('uid' => $row->uid, 'name' => $row->name, 'mail' => $row->mail, 'label' => $row->label); } } return $buddies[$uid][$key]; } /** * 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'), '#default_value' => $edit['buddylist_groups'], '#options' => $options, '#description' => $desc, '#multiple' => TRUE, ); return $form; } } } /** * Implementation of hook_settings */ function buddylist_settings() { // TODO: move these to block settings $form['block_settings'] = array( '#type' => 'fieldset', '#title' => t('Buddylist block options'), ); $form['block_settings']['buddylist_blocklisting_size'] = array( '#type' => 'select', '#title' => t("Number of buddies to list in the user's buddy block"), '#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')) ), ); $form['block_settings']['buddylist_posts_block'] = array( '#type' => 'select', '#title' => t("Number of posts to list in the buddies' recent posts block"), '#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')) ), ); $form['block_settings']['buddylist_list_block_title'] = array( '#type' => 'textfield', '#title' => t('"My buddies list" block title'), '#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.'), ); $form['block_settings']['buddylist_block_title'] = array( '#type' => 'textfield', '#title' => t('"My buddies\' recent posts" block title'), '#default_value' => variable_get('buddylist_block_title', t("My buddies' recent posts")), '#size' => 70, '#maxlength' => 128, '#description' => t('This will be the title for the recent buddies post block. If none is specified, "My buddies\' recent posts" will be used.'), ); // 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'), '#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.'), ); return $form; } 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)) { drupal_set_message(l($rec->name, 'user/'. $rec->uid) .' has added you to his/her buddylist.'); drupal_set_message(t('%linktouser has added you to his/her buddylist.', array('%linktouser' => theme('placeholder', l($rec->name, 'user/'. $rec->uid))))); db_query('UPDATE {buddylist} SET received = 0 WHERE buddy = %d', $user->uid); } } } /** * Implementation of hook_user */ function buddylist_user($type, &$edit, &$thisuser, $category = NULL) { global $user; // 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'), '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] = theme('username', $row); } if ($listbuddiesof) { $output[] = array('title' => t('Buddy of'), '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'), 'value' => theme('user_list', $actions), 'class' => 'buddylist'); } return array(t('Buddy List') => $output); } } /** * 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))), '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))), 'buddy/add/' . $buddyuser->uid, NULL, drupal_get_destination(), NULL, FALSE, TRUE); } /** * 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')); $block[1]['info'] = variable_get('buddylist_block_title', t('My buddies\' recent posts')); 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')); // 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'] .= ''; } 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')); $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'] .= ''; } return $block; } } break; } } } /** * 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'), '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'), '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('buddies of'), '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'), '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('maintain buddy list'), 'callback' => 'buddylist_addbuddy', 'callback arguments' => arg(2), 'type' => MENU_CALLBACK); $links[] = array('path' => 'buddy/delete', 'title' => t('delete from buddylist'), 'access' => user_access('maintain buddy list'), 'callback' => 'buddylist_deletebuddy', 'callback arguments' => arg(2), 'type' => MENU_CALLBACK); } return $links; } /** * 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'), '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))); $output = '
'; $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 .= '
'; 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 .= '
'; $output .= theme('pager', NULL, $buddies_per_page); $output .= '
'; 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))); $output = ''; $result = pager_query(db_rewrite_sql('SELECT n.nid, n.type, n.status FROM {node} n LEFT JOIN {buddylist} b ON n.uid = b.buddy WHERE n.status = 1 AND b.uid = %d and b.label = \'all\' ORDER BY n.nid DESC'), variable_get('default_nodes_main', 10), 0, NULL, $uid); while ($node = db_fetch_object($result)) { $output .= node_view(node_load($node->nid), TRUE); } $output .= theme('pager', NULL, variable_get('default_nodes_main', 10)); $output .= theme('xml_icon', url('buddylist/'. $uid .'/buddies/recent/feed')); drupal_set_html_head(''); return $output; } function buddylist_buddiesgroups_page($uid) { global $user; $thisuser = user_load(array('uid' => $uid)); drupal_set_title(t('%username\'s buddy groups', array('%username' => $thisuser->name))); $buddies = buddylist_get_buddies($uid, 'label'); if (count($buddies)) { foreach ($buddies as $label => $users) { $output .= theme('user_list', $users, $label); } } else { $output .= t('No groups'); } return $output; } function buddylist_buddiesgroups_form($uid) { $thisuser = user_load(array('uid' => $uid)); drupal_set_title(t('%username\'s buddy groups', array('%username' => $thisuser->name))); if ($buddies = buddylist_get_buddies($thisuser->uid)) { $form['buddylist_labels'] = array( '#tree' => TRUE, ); foreach ($buddies as $uid => $accounts) { $items = array(); foreach ($accounts as $account) { if ($account->label != 'all') { $items[] = $account->label; } } $val = implode(',', $items); $form['buddylist_labels'][$account->uid] = array( '#type' => 'textfield', '#default_value' => $val, '#size' => 70, '#maxlength' => 255, ); } $form['user'] = array( '#type' => 'hidden', '#value' => $thisuser->uid, ); $form['submit'] = array( '#type' => 'submit', '#value' => t('Submit'), ); $output .= drupal_get_form('buddiesgroups',$form); return $output; } else { return theme('placeholder',t('Unable to edit buddy groups. No buddies found.')); } } function theme_buddiesgroups($form) { $rows = array(); foreach ($form['buddylist_labels'] as $key => $value) { if(is_numeric($key)) { $rows[] = array(theme('username', user_load(array('uid' => $key))), form_render($form['buddylist_labels'][$key])); } } $headers = array(t('buddy'), t('buddy groups')); $output .= theme('table', $headers, $rows); $output .= form_render($form); return $output; } function buddiesgroups_submit($form_id, $form_values) { $userid = $form_values['user']; $sql = "DELETE FROM {buddylist} WHERE uid=%d AND label != 'all'"; $result = db_query($sql, $userid); foreach($form_values['buddylist_labels'] as $buddy => $str_labels) { $labels = explode(',', $str_labels); foreach ($labels as $label) { $sql = "INSERT INTO buddylist (uid, buddy, label, timestamp, received) VALUES (%d, %d, '%s', %d, 0)"; db_query($sql, $userid, $buddy, trim($label), time()); } } drupal_set_message(t('buddy groups saved.')); } /** * Feed for buddies recent posts */ function buddylist_buddyfeed($uid) { global $user; $result = db_query(db_rewrite_sql('SELECT n.nid, n.title, n.teaser, n.created, u.name, u.uid FROM {node} n INNER JOIN {users} u ON n.uid = u.uid LEFT JOIN {buddylist} b ON b.buddy = u.uid WHERE n.status = 1 AND b.uid = %d ORDER BY n.nid DESC'), $uid); $channel['title'] = t('Buddies recent posts on %site', array('%site' => variable_get('site_name', 'drupal'))); $channel['link'] = url('buddylist/'. $uid .'/buddies/recent', NULL, NULL, TRUE); $channel['description'] = $term->description; node_feed($result, $channel); } function buddylist_addbuddy($uid) { global $user; $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'); } elseif ($user->uid == $uid) { return t('Cannot add yourself to buddy list'); } $form['uid'] = array('#type' => 'hidden', '#value' => $uid); $form['name'] = array('#type' => 'hidden', '#value' => $buddy->name); return confirm_form('buddylist_addbuddy_confirm', $form, t('Add user %name to your buddy list?', array('%name' => theme('placeholder', $buddy->name))), $_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'; }; function buddylist_deletebuddy($uid) { global $user; $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'); } $form['uid'] = array('#type' => 'hidden', '#value' => $uid); $form['name'] = array('#type' => 'hidden', '#value' => $buddy->name); return confirm_form('buddylist_deletebuddy_confirm', $form, t('Remove user %name from your buddy list?', array('%name' => theme('placeholder', $buddy->name))), $_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)))); } else { drupal_set_message(t('%username is already on your buddylist', array('%username' => theme('placeholder', $user_to_add->name)))); } } 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 )) )); } 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)))); } 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)))); }