/[drupal]/contributions/modules/buddylist/buddylist.module
ViewVC logotype

Contents of /contributions/modules/buddylist/buddylist.module

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.93 - (show annotations) (download) (as text)
Tue May 15 13:55:43 2007 UTC (2 years, 6 months ago) by robertDouglass
Branch: MAIN
CVS Tags: HEAD
Changes since 1.92: +62 -57 lines
File MIME type: text/x-php
sync DRUPAL-5 with HEAD
1 <?php
2 // $Id: buddylist.module,v 1.68.2.22 2007/05/15 13:28:41 robertDouglass Exp $
3
4 if (module_exists('views')) {
5 include_once(drupal_get_path('module', 'buddylist'). '/buddylist_views.inc');
6 }
7
8
9 define('BUDDYLIST_ADD_SUBJECT', variable_get('buddylist_add_subject', "[@site] You are @adder_name's newest @buddy"));
10 define('BUDDYLIST_REMOVE_SUBJECT', variable_get('buddylist_remove_subject', "[@site] You have been removed from @adder_name's @buddylist"));
11 define('BUDDYLIST_REQUEST_SUBJECT', variable_get('buddylist_request_subject', "[@site] @adder_name has requested to add you to his/her @buddylist"));
12 define('BUDDYLIST_APPROVAL_SUBJECT', variable_get('buddylist_approval_subject', "[@site] @addee_name has approved your @buddylist add request"));
13
14 /**
15 * returns an array of common translation placeholders
16 */
17 function buddylist_translation() {
18 $translations = array(
19 '@buddy' => t('buddy'),
20 '@Buddy' => t('Buddy'),
21
22 '@buddylist' => t('buddylist'),
23 '@Buddylist' => t('Buddylist'),
24
25 '@buddies' => t('buddies'),
26 '@Buddies' => t('Buddies'),
27
28 '@buddyof' => t('buddy of'),
29 '@Buddyof' => t('Buddy of'),
30 );
31 return variable_get('buddylist_translation', $translations);
32 }
33
34
35 /**
36 * Implementation of hook_help
37 */
38 function buddylist_help($section) {
39 switch ($section) {
40 case 'admin/help#buddylist':
41 $output = t("
42 <p>@Buddy list enables users to keep a list of @buddies from their social network in their user account.
43 Users can also track what their @buddies are posting to the site.
44 Furthermore, they can track their <i>@buddies'</i> @buddies and thereby explore their social network.</p>
45 <p>If the administrator has enabled the profile module, users can add @buddies via their @buddies' user profiles.
46 On the \"View\" tab of each user's profile, there is a \"@Buddylist\" section. Select the 'add @buddy' action to add the user to your @buddylist.
47 If a user is already in your @buddylist, the 'delete' action will remove the @buddy. Administrators can also enable the @buddylist block.
48 This block allows you to see a list of your @buddies. If the <a href=\"http://drupal.org/project/foaf\">Friends Of A Friend (FOAF)</a> module is enabled, it will be possible to share @buddylists with other FOAF-aware social networking applications.</p>
49 <p>You can:</p>
50 <ul>
51 <li>add a @buddy by looking at their profile: <a href=\"@userprofiles\" title=\"View user profiles\">view user profiles</a></li>
52 <li>allow users to view profiles in <a href=\"@setaccesspermissions\" title=\"set access permissions\">administer &raquo; access control</a></li>
53 <li>enable the @buddylist block at <a href=\"@blockadministration\" title=\"block administration\">administer &raquo; block</a></li>
54 <li>administer the @buddylist block at <a href=\"@buddylistsettings\" title=\"@buddylist settings\">administer &raquo; settings &raquo; @buddylist</a></li>
55 </ul>
56
57 <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>",
58 array('@userprofiles' => url('profile'),
59 '@setaccesspermissions' => url('admin/user/access'),
60 '@blockadministration' => url('admin/build/block'),
61 '@buddylistsettings' => url('admin/settings/buddylist')
62 ) + buddylist_translation());
63 return $output;
64 }
65 }
66
67
68 /**
69 * Implementation of hook_perm
70 */
71 function buddylist_perm() {
72 return array('maintain buddy list', 'view buddy lists');
73 }
74
75 /**
76 * Implementation of hook_menu
77 */
78 function buddylist_menu($may_cache) {
79 global $user;
80
81 $items = array();
82 $id = is_numeric(arg(1)) ? arg(1) : $user->uid;
83
84 if ($may_cache) {
85 // buddylist settings page
86 $items[] = array(
87 'path' => 'admin/settings/buddylist',
88 'title' => t('Buddylist'), // Note that this isn't translated on purpose since it is for the admin
89 'description' => t('Buddylist configuration options for blocks, email, etc.'),
90 'callback' => 'drupal_get_form',
91 'callback arguments' => 'buddylist_admin_settings',
92 'access' => user_access('administer site configuration'),
93 );
94 // my buddylist menu item
95 $items[] = array(
96 'path' => 'buddylist',
97 'title' => t('My @buddylist', buddylist_translation()),
98 'access' => (user_access('maintain buddy list') && $id),
99 'callback' => 'buddylist_buddylisting_page',
100 'callback arguments' => array($user->uid, 'buddies'),
101 );
102 }
103 else {
104 // 'edit access' only granted to user's own buddy list or to administrative users
105 $editAccess = (
106 ($id == $user->uid && user_access('maintain buddy list') && $user->uid)
107 || user_access('administer users'));
108
109 $approval_required = variable_get('buddylist_require_approval', 0);
110
111 $items[] = array(
112 'path' => 'buddy/add',
113 'title' => t('Add to @buddylist', buddylist_translation()),
114 'access' => $editAccess,
115 'callback' => 'drupal_get_form',
116 'callback arguments' => array('buddylist_addbuddy', arg(2)),
117 'type' => MENU_CALLBACK,
118 );
119 $items[] = array(
120 'path' => 'buddy/delete',
121 'title' => t('Delete from @buddylist', buddylist_translation()),
122 'access' => $editAccess,
123 'callback' => 'drupal_get_form',
124 'callback arguments' => array('buddylist_deletebuddy', arg(2)),
125 'type' => MENU_CALLBACK,
126 );
127
128 // 'view only' tabs
129 $viewAccess = (($id == $user->uid && user_access('maintain buddy list')) || user_access('view buddy lists'));
130
131 // If buddylist approval is required, then upon approval, both parties become buddies of each other.
132 // So, in effect, idea 'buddyof' becomes redundant.
133 if (!$approval_required) {
134 $items[] = array(
135 'path' => 'buddylist/'. $id .'/buddies',
136 'title' => t('@Buddies', buddylist_translation()),
137 'access' => $viewAccess,
138 'callback' => 'buddylist_buddylisting_page',
139 'type' => MENU_DEFAULT_LOCAL_TASK,
140 'weight' => -1,
141 'callback arguments' => array($id)
142 );
143 $items[] = array(
144 'path' => 'buddylist/'. $id .'/buddyof',
145 'title' => t('@Buddyof', buddylist_translation()),
146 'access' => $viewAccess,
147 'callback' => 'buddylist_buddylisting_page',
148 'type' => MENU_LOCAL_TASK,
149 'weight' => 1,
150 'callback arguments' => array($id, 'buddyof')
151 );
152 }
153
154 // subtabs
155 $items[] = array(
156 'path' => 'buddylist/'. $id .'/buddies/list',
157 'title' => t('@Buddylist', buddylist_translation()),
158 'access' => $viewAccess,
159 'callback' => 'buddylist_buddylisting_page',
160 'type' => MENU_DEFAULT_LOCAL_TASK,
161 'weight' => -1,
162 'callback arguments' => array($id),
163 );
164 $items[] = array(
165 'path' => 'buddylist/'. $id .'/buddies/recent',
166 'title' => t('Recent posts'),
167 'access' => ($viewAccess && module_exists('tracker')),
168 'callback' => 'buddylist_buddiesrecent_page',
169 'type' => MENU_LOCAL_TASK,
170 'weight' => 3,
171 'callback arguments' => array($id),
172 );
173 if (variable_get('buddylist_buddygroups', FALSE)) {
174 $items[] = array(
175 'path' => 'buddylist/'. $id .'/buddies/groups/view',
176 'title' => t('View groups'),
177 'access' => $viewAccess,
178 'callback' => 'buddylist_buddiesgroups_page',
179 'type' => MENU_LOCAL_TASK,
180 'weight' => 5,
181 'callback arguments' => array($id),
182 );
183 $items[] = array(
184 'path' => 'buddylist/'. $id .'/buddies/groups/edit',
185 'title' => t('Edit groups'),
186 'access' => $editAccess,
187 'callback' => 'buddylist_buddiesgroups_edit',
188 'type' => MENU_LOCAL_TASK,
189 'weight' => 6,
190 'callback arguments' => array($id),
191 );
192 }
193
194 // sub-subtabs
195 if ($approval_required && $editAccess) {
196 $items[] = array(
197 'path' => 'buddylist/'. $id .'/buddies/requests',
198 'title' => t('Pending requests'),
199 'access' => $editAccess,
200 'callback' => 'theme',
201 'type' => MENU_LOCAL_TASK,
202 'weight' => 0,
203 'callback arguments' => array('buddylist_pending_requests', $id)
204 );
205
206 $items[] = array(
207 'path' => 'buddylist/'. $id .'/buddies/requested/accept',
208 'title' => t('Accept Request'),
209 'access' => $editAccess,
210 'type' => MENU_CALLBACK,
211 'callback' => 'drupal_get_form',
212 'callback arguments' => array('buddylist_pending_requested_accept',$id),
213 );
214
215 $items[] = array(
216 'path' => 'buddylist/'. $id .'/buddies/requested/deny',
217 'title' => t('Deny Request'),
218 'access' => $editAccess,
219 'type' => MENU_CALLBACK,
220 'callback' => 'drupal_get_form',
221 'callback arguments' => array('buddylist_pending_requested_deny',$id),
222 );
223
224 $items[] = array(
225 'path' => 'buddylist/'. $id .'/buddies/request/cancel',
226 'title' => t('Cancel Request'),
227 'access' => $editAccess,
228 'type' => MENU_CALLBACK,
229 'callback' => 'drupal_get_form',
230 'callback arguments' => array('buddylist_cancel_request',$id),
231 );
232
233 }
234
235 // other callbacks
236 if ($id != $user->uid) {
237 // This callback can interfere with the 'my buddylist' menu item,
238 // so we only load it if the user is viewing another user's list.
239 $items[] = array(
240 'path' => 'buddylist/'. $id,
241 'title' => t('@Buddylist', buddylist_translation()),
242 'access' => (($viewAccess || $editAccess) && $id),
243 'callback' => 'buddylist_buddylisting_page',
244 'type' => MENU_CALLBACK,
245 'callback arguments' => array($id),
246 );
247 }
248 $items[] = array(
249 'path' => 'buddylist/'. $id .'/buddies/recent/feed',
250 'title' => t('Xml feed'),
251 'access' => $viewAccess,
252 'callback' => 'buddylist_buddyfeed',
253 'type' => MENU_CALLBACK,
254 'callback arguments' => array($id),
255 );
256 }
257
258 return $items;
259 }
260
261 /**
262 * Buddylist administration settings page
263 */
264 function buddylist_admin_settings() {
265 $form['general'] = array(
266 '#type' => 'fieldset',
267 '#title' => t('General settings'),
268 );
269
270 $form['general']['buddylist_require_approval'] = array(
271 '#type' => 'radios',
272 '#title' => t('Require approval'),
273 '#default_value' => variable_get('buddylist_require_approval', 0),
274 '#description' => t("Select 'Yes' if a user's request to be someone's @buddy should be approved by the other user first. Upon approval, both parties will be @buddies of each other.", buddylist_translation()),
275 '#options' => array(1 => t('Yes'), 0 => t('No'))
276 );
277 $form['general']['buddylist_buddygroups'] = array(
278 '#type' => 'checkbox',
279 '#title' => t('Enable @buddy groups', buddylist_translation()),
280 '#description' => t('Enables @buddylist @buddy groups. Users will be able to create @buddy groups to manage their @buddies.', buddylist_translation()),
281 '#default_value' => variable_get('buddylist_buddygroups', FALSE),
282 );
283
284 // User profile page settings
285 $form['profile_settings'] = array(
286 '#type' => 'fieldset',
287 '#title' => t('Profile page options'),
288 );
289 $form['profile_settings']['buddylist_prof_buddies'] = array(
290 '#type' => 'select',
291 '#title' => t('Number of @buddies and users who\'ve added me', buddylist_translation()),
292 '#default_value' => variable_get('buddylist_prof_buddies', 5),
293 '#options' => drupal_map_assoc(range(0, 10)),
294 '#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()),
295 );
296
297 // TODO: move these to block settings
298 $form['block_settings'] = array(
299 '#type' => 'fieldset',
300 '#title' => t('@Buddylist block options', buddylist_translation()),
301 );
302 $form['block_settings']['buddylist_blocklisting_size'] = array(
303 '#type' => 'select',
304 '#title' => t("Number of @buddies to list in the user's @buddy block", buddylist_translation()),
305 '#default_value' => variable_get('buddylist_blocklisting_size', 5),
306 '#options' => drupal_map_assoc(array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20, 25, 30)),
307 '#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/build/block')) + buddylist_translation()),
308 );
309 $form['block_settings']['buddylist_posts_block'] = array(
310 '#type' => 'select',
311 '#title' => t("Number of posts to list in the @buddies' recent posts block", buddylist_translation()),
312 '#default_value' => variable_get('buddylist_posts_block', 7),
313 '#options' => drupal_map_assoc(array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20, 25, 30)),
314 '#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/build/block')) + buddylist_translation()),
315 );
316 $form['block_settings']['buddylist_block_title'] = array(
317 '#type' => 'textfield',
318 '#title' => t('"My @buddies\' recent posts" block title', buddylist_translation()),
319 '#default_value' => variable_get('buddylist_block_title', t("My @buddies' recent posts", buddylist_translation())),
320 '#size' => 70,
321 '#maxlength' => 128,
322 '#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()),
323 );
324 $form['block_settings']['buddylist_status_block_title'] = array(
325 '#type' => 'textfield',
326 '#title' => t('"My @buddylist status" block title', buddylist_translation()),
327 '#default_value' => variable_get('buddylist_status_block_title', t("My @buddylist status", buddylist_translation())),
328 '#size' => 70,
329 '#maxlength' => 128,
330 '#description' => t('This will be the title for the @buddylist status block. If none is specified, "My @buddylist status" will be used.', buddylist_translation()),
331 );
332 $form['block_settings']['buddylist_list_block_title'] = array(
333 '#type' => 'textfield',
334 '#title' => t('"My @buddies list" block title', buddylist_translation()),
335 '#weight' => 1,
336 '#default_value' => variable_get('buddylist_list_block_title', t('My @buddylist', buddylist_translation())),
337 '#size' => 70,
338 '#maxlength' => 128,
339 '#description' => t('This will be the title for the "My @buddylist" block. If none is specified, "My @buddylist" will be used.', buddylist_translation()),
340 );
341 $form['block_settings']['buddylist_block_if_no_buddies'] = array(
342 '#type' => 'checkbox',
343 '#title' => t('Show "My @buddies list" block even if @buddylist is empty', buddylist_translation()),
344 '#weight' => 2,
345 '#default_value' => variable_get('buddylist_block_if_no_buddies', FALSE),
346 '#description' => t('If a user has no @buddies, the @buddy block can show a message.', buddylist_translation()),
347 );
348 $form['block_settings']['buddylist_empty_text'] = array(
349 '#type' => 'textarea',
350 '#title' => t('Show this text in "My @buddies list" if @buddylist is empty', buddylist_translation()),
351 '#weight' => 3,
352 '#default_value' => variable_get('buddylist_empty_text', t(buddylist_empty_text_default(), buddylist_translation())),
353 '#description' => t('If a user has no @buddies and the above checkbox is checked, this message is shown instead of a list.', buddylist_translation()),
354 );
355
356 $form['mail'] = array(
357 '#type' => 'fieldset',
358 '#title' => t('email'),
359 );
360
361 global $user;
362 $macros = implode(', ', array_keys(buddylist_mail_replacements($user, $user)));
363 $approval_macros = implode(', ', array_keys(buddylist_approval_mail_replacements($user, $user)));
364
365 $form['mail']['buddylist_user_mail'] = array(
366 '#type' => 'checkbox',
367 '#title' => t('Allow users to turn off buddylist messages'),
368 '#default_value' => variable_get('buddylist_user_mail', FALSE),
369 '#description' => t('If you check this, users will have a new setting on their account edit page.'),
370 );
371
372 $form['mail']['buddylist_send_add'] = array(
373 '#type' => 'checkbox',
374 '#title' => t('Send add messages'),
375 '#default_value' => variable_get('buddylist_send_add', FALSE),
376 );
377
378 $form['mail']['buddylist_add_subject'] = array(
379 '#type' => 'textfield',
380 '#title' => t('Added @buddy email subject', buddylist_translation()),
381 '#default_value' => BUDDYLIST_ADD_SUBJECT,
382 );
383
384 $form['mail']['buddylist_add_message'] = array(
385 '#type' => 'textarea',
386 '#title' => t('Added @buddy email message', buddylist_translation()),
387 '#default_value' => variable_get('buddylist_add_message', buddylist_mail_add_default()),
388 '#description' => t('Replacement strings are: %macros', array('%macros' => $macros)),
389 );
390
391 $form['mail']['buddylist_send_remove'] = array(
392 '#type' => 'checkbox',
393 '#title' => t('Send remove messages'),
394 '#default_value' => variable_get('buddylist_send_remove', FALSE),
395 );
396
397 $form['mail']['buddylist_remove_subject'] = array(
398 '#type' => 'textfield',
399 '#title' => t('Removed @buddy email subject', buddylist_translation()),
400 '#default_value' => BUDDYLIST_REMOVE_SUBJECT,
401 );
402
403 $form['mail']['buddylist_remove_message'] = array(
404 '#type' => 'textarea',
405 '#title' => t('Removed @buddy email message', buddylist_translation()),
406 '#default_value' => variable_get('buddylist_remove_message', buddylist_mail_remove_default()),
407 '#description' => t('Replacement strings are: %macros', array('%macros' => $macros)),
408 );
409
410 $form['mail']['buddylist_send_request'] = array(
411 '#type' => 'checkbox',
412 '#title' => t('Send request messages.'),
413 '#description' => t('Check this box if you want users to receive an email when someone requests to be their buddy. This setting only has effect if approval is required to be on someone\'s buddylist.'),
414 '#default_value' => variable_get('buddylist_send_request', FALSE)
415 );
416
417 $form['mail']['buddylist_request_subject'] = array(
418 '#type' => 'textfield',
419 '#title' => t('@buddy request email subject', buddylist_translation()),
420 '#default_value' => BUDDYLIST_REQUEST_SUBJECT,
421 );
422
423 $form['mail']['buddylist_request_message'] = array(
424 '#type' => 'textarea',
425 '#title' => t('@buddy request email message', buddylist_translation()),
426 '#default_value' => variable_get('buddylist_request_message', buddylist_mail_request_default()),
427 '#description' => t('Replacement strings are: %macros', array('%macros' => $macros)),
428 );
429
430 $form['mail']['buddylist_send_approval'] = array(
431 '#type' => 'checkbox',
432 '#title' => t('Send approval messages'),
433 '#default_value' => variable_get('buddylist_send_approval', FALSE),
434 '#description' => t('Check this box if you want users to receive an email to the requester when someone approves an add request. This setting only has effect if approval is required to be on someone\'s @buddylist.', buddylist_translation())
435 );
436
437 $form['mail']['buddylist_approval_subject'] = array(
438 '#type' => 'textfield',
439 '#title' => t('@buddy request email subject', buddylist_translation()),
440 '#default_value' => BUDDYLIST_APPROVAL_SUBJECT,
441 );
442
443 $form['mail']['buddylist_approval_message'] = array(
444 '#type' => 'textarea',
445 '#title' => t('@buddy approval email message', buddylist_translation()),
446 '#default_value' => variable_get('buddylist_approval_message', buddylist_mail_approval_default()),
447 '#description' => t('Replacement strings are: %macros', array('%macros' => $approval_macros)),
448 );
449
450 return system_settings_form($form);
451 }
452
453
454 /**
455 * Implementation of hook_user
456 */
457 function buddylist_user($type, &$edit, &$thisuser, $category = NULL) {
458 global $user;
459
460 $output = array();
461 // show any buddylist notifications upon login and upon viewing own profile
462 if (user_access('maintain buddy list') && (($type == 'login') || ($type == 'view') && ($thisuser->uid == $user->uid))) {
463 buddylist_setmsg_received($thisuser);
464 }
465 if ($type == 'view') {
466 if ($list = buddylist_get_buddylist($thisuser)) {
467 $output[] = array('title' => t('@Buddies', buddylist_translation()), 'value' => $list, 'class' => 'buddylist');
468 }
469 if ($list = buddylist_get_buddylist($thisuser, TRUE)) {
470 $output[] = array('title' => t('@buddy of', buddylist_translation()), 'value' => $list, 'class' => 'buddyoflist');
471 }
472 if ($actions = buddylist_get_buddy_actions($user, $thisuser)) {
473 $output[] = array('title' => t('@Buddy actions', buddylist_translation()), 'value' => theme('item_list', $actions), 'class' => 'buddylist_actions');
474 }
475 if(count($output) > 0) {
476 return array(t('@Buddy List', buddylist_translation()) => $output);
477 }
478 }
479 else if ($type == 'delete') {
480 db_query("DELETE FROM {buddylist} WHERE uid = %d OR buddy = %d", $thisuser->uid, $thisuser->uid);
481 db_query("DELETE FROM {buddylist_buddy_group} WHERE uid = %d OR buddy = %d", $thisuser->uid, $thisuser->uid);
482 db_query("DELETE FROM {buddylist_groups} WHERE uid = %d", $thisuser->uid);
483 db_query("DELETE FROM {buddylist_pending_requests} WHERE requester_uid = %d OR requestee_uid = %d", $thisuser->uid, $thisuser->uid);
484 }
485 else if ($type == 'load') {
486 $thisuser->buddies = buddylist_get_buddies($thisuser->uid);
487 }
488 else if ($type == 'form' && $category == 'account' && variable_get('buddylist_user_mail', FALSE) && user_access('maintain buddy list', $thisuser)) {
489 // when user tries to edit his own data
490 $form['buddylist_settings'] = array(
491 '#type' => 'fieldset',
492 '#title' => t('Buddylist settings'),
493 '#weight' => 5);
494 $form['buddylist_settings']['buddylist_mail'] = array(
495 '#type' => 'checkbox',
496 '#title' => t('Receive @buddylist notification mails', buddylist_translation()),
497 '#default_value' => isset($edit['buddylist_mail']) ? $edit['buddylist_mail'] : 1,
498 '#description' => t('If you check this, you will be notified about important actions regarding your @Buddylist.', buddylist_translation()));
499 return $form;
500 }
501 }
502
503 /*
504 * Return a formatted list of buddies for the given user
505 * @param $buddy_of If set to TRUE, a formatted list of users is returned, for whom this user is a buddy.
506 */
507 function buddylist_get_buddylist($user, $buddy_of = FALSE) {
508
509 if (user_access('view buddy lists') && !$buddy_of) {
510 $i = 0;
511 if ($buddies = buddylist_get_buddies($user->uid)) {
512 foreach(array_keys($buddies) as $buddy) {
513 $account = user_load(array('uid' => $buddy));
514 $listbuddies[] = $account;
515 $i++;
516 if ($i > variable_get('buddylist_prof_buddies', 5)) {
517 break;
518 }
519 }
520 return theme('user_list', $listbuddies);
521 }
522 }
523 else if (user_access('view buddy lists') && !variable_get('buddylist_require_approval', 0)) {
524 // This portion of code is used to see if this $thisuser is a buddy of others and, if s/he is, returns a list
525 // of people s/he is a buddy of.
526 // Note the distinction between having a buddy and being someone else's buddy (i.e., 'buddyof')
527 // Of course, this distinction doesn't exist if approval is required to add a buddy (in which case, buddy relationships are symmetric)
528 $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';
529 $result = db_query_range($sql, $user->uid, 0, variable_get('buddylist_prof_buddies', 5));
530 while ($row = db_fetch_object($result)) {
531 $listbuddyof[$row->uid] = $row;
532 }
533 if ($listbuddyof) {
534 return theme('user_list', $listbuddyof);
535 }
536 }
537 }
538
539
540 /*
541 * Returns an array of posible actions (html) for the viewing user,
542 * e.g. a link to make the viewed user a buddy
543 */
544 function buddylist_get_buddy_actions(&$viewing_user, &$viewed_user) {
545
546 $actions = array();
547 if (!user_access('maintain buddy list') || $viewing_user->uid == $viewed_user->uid) {
548 return $actions;
549 }
550
551 if (variable_get('buddylist_require_approval', FALSE) && in_array($viewed_user->uid, array_keys(buddylist_get_requestees($viewing_user->uid)))) {
552 $actions[] = t('You have requested to add this user to your @buddylist. (See !your_pending_requests)', array('!your_pending_requests' => l(t('your pending requests'), 'buddylist/'. $viewing_user->uid .'/buddies/requests')) + buddylist_translation());
553 }
554 else if (in_array($viewed_user->uid, array_keys(buddylist_get_buddies($viewing_user->uid)))) {
555 $actions[] = theme('remove_from_buddylist_link', $viewed_user);
556 }
557 else if (in_array($viewing_user->uid, array_keys(buddylist_get_requestees($viewed_user->uid)))) {
558 $actions[] = t('This user has requested to add you to your @buddylist.', buddylist_translation()) .
559 drupal_get_form('buddylist_approval_form', $viewing_user->uid, $viewed_user->uid);
560 }
561 else {
562 $actions[] = theme('add_to_buddylist_link', $viewed_user);
563 }
564
565 return $actions;
566 }
567
568
569 /**
570 * Implementation for hook_block
571 */
572 function buddylist_block($op = 'list', $delta = 0) {
573 global $user;
574
575 if ($op == 'list') {
576 $block[0]['info'] = variable_get('buddylist_list_block_title', t('My @buddylist', buddylist_translation()));
577 $block[1]['info'] = variable_get('buddylist_block_title', t('My @buddies\' recent posts', buddylist_translation()));
578 if (variable_get('buddylist_require_approval', 0)) {
579 $block[2]['info'] = variable_get('buddylist_status_block_title', t('My @buddy status', buddylist_translation()));
580 }
581 return $block;
582 }
583 else if ($op == 'view' && user_access('access content') && user_access('maintain buddy list') && $user->uid > 0) {
584 switch ($delta) {
585 case 0 : // Shows buddylist block
586 if ($buddies = buddylist_get_buddies()) {
587 // we have buddies defined and generate the list
588 $i = 0;
589 foreach (array_keys($buddies) as $buddy) {
590 $users[] = user_load(array('uid' => $buddy));
591 $i++;
592 if ($i == variable_get('buddylist_blocklisting_size', 5)) {
593 break;
594 }
595 }
596 $block['content'] = theme('user_list', $users);
597 } else {
598 // buddylist is empty
599 if(variable_get('buddylist_block_if_no_buddies', FALSE)) {
600 // Show a message that we have no buddies yet
601 $block['content'] = variable_get('buddylist_empty_text', t(buddylist_empty_text_default(), buddylist_translation()));
602 } else {
603 // If no buddies defined and no message available, end 'case' without returning block.
604 break;
605 }
606 }
607 // this is the same output whether buddylist or not
608 $block['subject'] = variable_get('buddylist_list_block_title', t('My @buddylist', buddylist_translation()));
609
610 // check if a "more" link should generated by seeing if there are more buddies than the specified $upperlimit
611 if (count($buddies) > variable_get('buddylist_blocklisting_size', 5)) {
612 $block['content'] .= '<div class="more-link">' . l(t('more'), 'buddylist', array('title' => t('View more.'))) . '</div>';
613 }
614 return $block;
615 break;
616
617 case 1: // Shows my buddies recent posts block
618 $buddies = buddylist_get_buddies();
619 $keys = array_keys($buddies);
620 if (count($keys) > 0) {
621 $str_buddies = implode(',', $keys);
622 $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));
623
624 if (db_num_rows($result)) {
625 $block['subject'] = variable_get('buddylist_block_title', t('My @buddies\' recent posts', buddylist_translation()));
626 $block['content'] = node_title_list($result);
627
628 // check if a "more" link should generated by seeing if there are more buddies than the specified $upperlimit
629 $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);
630 $countresult = db_fetch_object($result);
631
632 if (module_exists('tracker') && variable_get('buddylist_posts_block', 7) < $countresult->node_count) {
633 $block['content'] .= '<div class="more-link">'. l(t('more'), 'buddylist/'. $user->uid .'/buddies/recent', array('title' => t('View more.'))) .'</div>';
634 }
635 return $block;
636 }
637 }
638 break;
639
640 case 2: // Buddylist status
641 $block['subject'] = variable_get('buddylist_status_block_title', t('My @buddy status', buddylist_translation()));
642
643 $count = db_result(db_query("SELECT COUNT(uid) FROM {buddylist} WHERE uid = %d", $user->uid));
644 $sent = db_result(db_query("SELECT COUNT(requester_uid) FROM {buddylist_pending_requests} WHERE requester_uid = %d", $user->uid));
645 $received = db_result(db_query("SELECT COUNT(requestee_uid) FROM {buddylist_pending_requests} WHERE requestee_uid = %d", $user->uid));
646
647 $block['content'] = theme('buddylist_status_block', $count, $received, $sent);
648 return $block;
649 break;
650 }
651 }
652 }
653
654 /**
655 * Public API for retrieving buddies. Feel free to use this from other
656 * modules.
657 * $key can be 'uid' or 'label'.
658 */
659 function buddylist_get_buddies($uid = NULL, $key = 'uid') {
660 static $buddies;
661
662 if (!$uid) {
663 global $user;
664 $uid = $user->uid;
665 }
666 if (!isset($buddies[$key][$uid])) {
667 $buddies[$key][$uid] = array();
668 $sql = 'SELECT b.buddy, u.name, u.mail, u.uid FROM {buddylist} b
669 INNER JOIN {users} u ON b.buddy = u.uid
670 WHERE b.uid = %d';
671 $result = db_query($sql, $uid);
672 while ($row = db_fetch_object($result)) {
673 $buddies[$key][$uid][$row->buddy]['uid'] = $row->uid;
674 $buddies[$key][$uid][$row->buddy]['name'] = $row->name;
675 $buddies[$key][$uid][$row->buddy]['mail'] = $row->mail;
676 $buddies[$key][$uid][$row->buddy]['groups'] = buddylist_get_buddy_groups($uid, $row->buddy);
677 $buddies[$key][$uid][$row->buddy]['online'] = 0;
678 $selectlist .= $row->buddy.",";
679 }
680 // Add the online flag
681 if (db_num_rows($result)) {
682 $sql = 'SELECT uid FROM {sessions} WHERE uid IN (%s) AND timestamp > %d';
683 $result = db_query($sql, substr($selectlist,0,-1), time()-1800);
684 while ($row = db_fetch_object($result)) {
685 $buddies[$key][$uid][$row->uid]['online'] = 1;
686 }
687 }
688 }
689
690 return $buddies[$key][$uid];
691 }
692
693 /**
694 * Returns an array of uid => name of people that user with param $uid has made a buddy request to
695 */
696 function buddylist_get_requestees($uid) {
697 $buddies = array();
698
699 $result = db_query('SELECT bpr.requestee_uid, u.name FROM {buddylist_pending_requests} bpr INNER JOIN {users} u ON bpr.requestee_uid = u.uid WHERE requester_uid = %d', $uid);
700
701 while ($row = db_fetch_object($result)) {
702 $buddies[$row->requestee_uid] = $row->name;
703 }
704
705 return $buddies;
706 }
707
708 function buddylist_setmsg_received($thisuser) {
709 global $user;
710
711 if (variable_get('buddylist_require_approval', 0)) {
712 // Go through and find new buddylist add-requests, (i.e., the ones in {buddylist_pending_requests} w/ received column == 0
713 $result = db_query('SELECT bpr.requester_uid as uid, u.name FROM {buddylist_pending_requests} bpr INNER JOIN {users} u ON bpr.requester_uid = u.uid WHERE bpr.requestee_uid = %d AND bpr.received = 0', $user->uid);
714 $acknowledged_uids = array();
715 while ($row = db_fetch_object($result)) {
716 drupal_set_message(t('!linktouser has requested to add you to his/her @buddylist. Please view your !pending_buddy_requests to approve/deny.', array('!linktouser' => theme('username', $row), '!pending_buddy_requests' => l(t('pending buddy requests'), 'buddylist/'. $user->uid .'/buddies/requests')) + buddylist_translation()));
717 $acknowledged_uids[] = $row->uid;
718 }
719 if (count($acknowledged_uids)) {
720 db_query('UPDATE {buddylist_pending_requests} SET received = 1 WHERE requestee_uid = %d AND requester_uid IN (%s)', $user->uid, implode(',', $acknowledged_uids));
721 }
722 }
723 else {
724 $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);
725 while ($rec = db_fetch_object($check_received)) {
726 if (($rec->received) and ($thisuser->uid == $user->uid)) {
727 // TODO: This is where integration with Privatemsg could happen. If enabled, send a private message instead.
728 drupal_set_message(t('!linktouser has added you to his/her @buddylist.', array('!linktouser' => theme('username', $rec)) + buddylist_translation()));
729 db_query('UPDATE {buddylist} SET received = 0 WHERE buddy = %d', $user->uid);
730 }
731 }
732 }
733 }
734
735 /**
736 * expose add and remove links to theming.
737 */
738 function theme_remove_from_buddylist_link($buddyuser) {
739 return l(t('Remove %name from my @buddylist', array('%name' => $buddyuser->name) + buddylist_translation()), 'buddy/delete/' . $buddyuser->uid, NULL, drupal_get_destination(), NULL, FALSE, TRUE);
740 }
741
742 function theme_add_to_buddylist_link($buddyuser) {
743 return l(t('Add %name to my @buddylist', array('%name' => $buddyuser->name) + buddylist_translation()), 'buddy/add/' . $buddyuser->uid, NULL, drupal_get_destination(), NULL, FALSE, TRUE);
744 }
745
746 function theme_buddylist_accept_request_link($requestee_uid, $requester_uid) {
747 return l(t('Accept'), 'buddylist/' . $requestee_uid . '/buddies/requested/accept/' . $requester_uid, array('title' => 'Accept'), drupal_get_destination(), NULL, FALSE, TRUE);
748 }
749
750 function theme_buddylist_deny_request_link($requestee_uid, $requester_uid) {
751 return l(t('Deny'), 'buddylist/' . $requestee_uid . '/buddies/requested/deny/' . $requester_uid, array('title' => 'Deny'), drupal_get_destination(), NULL, FALSE, TRUE);
752 }
753
754 function theme_buddylist_sent_requests_cancel_link($requestee_uid, $requester_uid) {
755 return l(t('Cancel'), 'buddylist/' . $requestee_uid . '/buddies/request/cancel/' . $requester_uid, array('title' => 'Cancel'), drupal_get_destination(), NULL, FALSE, TRUE);
756 }
757
758 /**
759 * Displays a list of a given user's buddies.
760 */
761 function buddylist_buddylisting_page($uid = NULL, $mode = 'buddies') {
762 global $user;
763
764 if (empty($uid)) {
765 $uid = $user->uid;
766 }
767 // Check that the uid is valid, not the anonymous user, and the user exists
768 if (!(is_numeric($uid) && ($uid > 0) && $thisuser = user_load(array('uid' => $uid)))) {
769 drupal_not_found();
770 exit();
771 }
772
773 $viewing_own_account = ($user->uid == $uid);
774
775 if (user_access('maintain buddy list') && $viewing_own_account) {
776 buddylist_setmsg_received($thisuser);
777 }
778
779 drupal_set_title(t('%username\'s @buddylist', array('%username' => $thisuser->name) + buddylist_translation()));
780
781 $buddies_per_page = 20;
782
783 //TODO: use the get_buddies function instead
784 if ($mode == 'buddies') {
785 $sql = "SELECT DISTINCT(b.buddy), u.access FROM {buddylist} b INNER JOIN {users} u ON b.buddy = u.uid WHERE b.uid = %d ORDER BY u.access DESC";
786 }
787 else {
788 $sql = "SELECT DISTINCT(u.uid) as buddy, u.access FROM {buddylist} b INNER JOIN {users} u ON b.uid = u.uid WHERE b.buddy = %d ORDER BY u.access DESC";
789 }
790 $result = pager_query($sql, $buddies_per_page, 0 , NULL, $uid);
791
792 $header = array(t('@buddy', buddylist_translation()), t('online'));
793 $online_interval = time() - variable_get('user_block_seconds_online', 180);
794
795 if (db_num_rows($result)) {
796 while ($account = db_fetch_object($result)) {
797 $online = $account->access > $online_interval;
798 $rows[] = array(theme('username', user_load(array('uid' => $account->buddy))), theme('buddylist_online', $online));
799 }
800 $output .= theme('table', $header, $rows);
801 }
802 else {
803 $output .= variable_get('buddylist_empty_text', t(buddylist_empty_text_default(), buddylist_translation()));
804 }
805
806 $output .= theme('pager', NULL, $buddies_per_page);
807
808 return $output;
809 }
810
811 /**
812 * Returns a list of people who've requested to be added to the given user's buddylist
813 * and a list of people who this given user has requested to be buddies with.
814 */
815 function theme_buddylist_pending_requests($id) {
816
817 $thisuser = user_load(array('uid' => $id));
818 drupal_set_title(t('@username\'s @buddylist', array('@username' => $thisuser->name) + buddylist_translation()));
819
820 return theme('box', t('Received requests'), buddylist_pending_requester_list($thisuser)) .
821 theme('box', t('Sent requests'), buddylist_pending_requested_list($thisuser));
822 }
823
824 /**
825 * Returns a list of people who've requested to be added to the given user's buddylist
826 */
827 function buddylist_pending_requester_list(&$account) {
828 global $user;
829
830 $viewing_own_account = ($user->uid == $account->uid);
831 $result = db_query('SELECT bpr.requester_uid as uid, u.name FROM {buddylist_pending_requests} bpr INNER JOIN {users} u ON bpr.requester_uid = u.uid WHERE requestee_uid = %d', $account->uid);
832
833 if (!db_num_rows($result)) {
834 $output = '<p>'. t("!someone currently !does_or_do not have any pending @buddy requests from other users.", array('!someone' => ($viewing_own_account ? t('You') : $account->name), '!does_or_do' => $viewing_own_account ? t('do') : t('does')) + buddylist_translation()) .'</p>';
835 }
836 else {
837 $output = '<p>'. t("The following people have requested to be !someones @buddy.", array('!someones' => ($viewing_own_account ? t('your') : $account->name ."'s ")) + buddylist_translation()) .'</p>';
838
839 $html_rows = array();
840 while ($row = db_fetch_object($result)) {
841 $html_row = array();
842 $html_row[] = theme('username', $row);
843 $html_row[] = theme('buddylist_accept_request_link', $account->uid, $row->uid) . " | " . theme('buddylist_deny_request_link', $account->uid, $row->uid);
844 $html_rows[] = $html_row;
845 }
846
847 $output .= theme('table', NULL, $html_rows);
848 }
849
850 return $output;
851 }
852
853 /**
854 * Returns a list of user's who this given user has requested to be buddies with.
855 */
856 function buddylist_pending_requested_list(&$account) {
857 global $user;
858
859 $viewing_own_account = ($user->uid == $account->uid);
860 $result = db_query('SELECT bpr.requestee_uid as uid, u.name FROM {buddylist_pending_requests} bpr INNER JOIN {users} u ON bpr.requestee_uid = u.uid WHERE requester_uid = %d', $account->uid);
861
862 if (!db_num_rows($result)) {
863 $output = t('!Person !do_or_does not have any pending @buddy requests that !person !have_or_has made.',
864 array(
865 '!Person' => ($viewing_own_account ? t('You') : $account->name),
866 '!do_or_does' => ($viewing_own_account ? t('do') : t('does')),
867 '!have_or_has' => ($viewing_own_account ? t('have') : t('has')),
868 '!person' => ($viewing_own_account ? t('you') : $account->name) ) + buddylist_translation());
869 }
870 else {
871 $output = t('!person !have_or_has requested to be added to the @buddylist of the following users.', array('!person' => ($viewing_own_account ? t('You') : $account->name), '!have_or_has' => ($viewing_own_account ? t('have') : t('has'))) + buddylist_translation());
872
873 $html_rows = array();
874 while ($row = db_fetch_object($result)) {
875 $html_row = array();
876 $html_row[] = theme('username', $row);
877 $html_row[] = theme('buddylist_sent_requests_cancel_link', $account->uid, $row->uid);
878 $html_rows[] = $html_row;
879 }
880
881 $output .= theme('table', NULL, $html_rows);
882 }
883
884 return $output;
885 }
886
887 function buddylist_pending_requested_accept($requestee_uid, $requester_uid) {
888 $requestee_account = user_load(array('uid' => $requestee_uid));
889 $requester_account = user_load(array('uid' => $requester_uid));
890 $output = confirm_form(
891 buddylist_confirm_form($requester_account, $requestee_account),
892 t('Accept Request'),
893 'buddylist/'.$requestee_uid.'/buddies/requests',
894 t("Are you sure you want to accept the request from !name?", array('!name' => theme('username', $requester_account))),
895 t('Yes'), t('No'),
896 'buddylist_request_accept_confirm');
897
898 return $output;
899 }
900
901 function buddylist_cancel_request($requestee_uid, $requester_uid){
902 $requestee_account = user_load(array('uid' => $requestee_uid));
903 $requester_account = user_load(array('uid' => $requester_uid));
904 $output = confirm_form(
905 buddylist_request_cancel_form($requestee_uid, $requester_uid),
906 t('Cancel Request'),
907 'buddylist/'.$requestee_uid.'/buddies/requests',
908 t("Are you sure you want to cancel the request to !name?", array('!name' => theme('username', $requester_account))),
909 t('Yes'), t('No'),
910 'buddylist_cancel_request_confirm');
911
912 return $output;
913
914 }
915
916 function buddylist_cancel_request_submit($form_id, $form_values){
917 db_query('DELETE FROM {buddylist_pending_requests} WHERE requestee_uid = %d AND requester_uid = %d', $form_values['requester_uid'], $form_values['requestee_uid']);
918
919 $former_potential_buddy = user_load(array('uid' => $form_values['requester_uid']));
920 drupal_set_message(t('The request to add !user_name has been cancelled.', array('!user_name' => theme('username', $former_potential_buddy))));
921
922 return 'buddylist/'. $form_values['requester_uid'] .'/buddies/requests';
923 }
924
925 function buddylist_pending_requested_deny($requestee_uid, $requester_uid) {
926 $requestee_account = user_load(array('uid' => $requestee_uid));
927 $requester_account = user_load(array('uid' => $requester_uid));
928 $output = confirm_form(
929 buddylist_confirm_form($requester_account, $requestee_account),
930 t('Accept Request'),
931 'buddylist/'.$requestee_uid.'/buddies/requests',
932 t("Are you sure you want to deny the request from !name?", array('!name' => theme('username', $requester_account))),
933 t('Yes'), t('No'),
934 'buddylist_request_deny_confirm');
935
936 return $output;
937 }
938
939 function buddylist_pending_requested_accept_submit($form_id, $form_values) {
940 $requestee_account = $form_values['requestee_account']; // most likely global user, unless admin looking
941 $requester_account = $form_values['requester_account'];
942
943 // Delete pending request from {buddylist_penging_requests}
944 $result = db_query('SELECT * FROM {buddylist_pending_requests} WHERE requestee_uid = %d AND requester_uid = %d', $requestee_account->uid, $requester_account->uid);
945
946 if (db_num_rows($result) == 0) {
947 // The other user cancelled since viewing this page
948 drupal_set_message(t('!linktouser has cancelled the request to join your @buddylist.', array('!linktouser' => theme('username', $requester_account)) + buddylist_translation()));
949 return 'buddylist/'. $requestee_account->uid .'/buddies/requests';
950 }
951
952 db_query('DELETE FROM {buddylist_pending_requests} WHERE requestee_uid = %d AND requester_uid = %d', $requestee_account->uid, $requester_account->uid);
953
954 // Make sure, for some weird reason, we don't already have these guys marked as buddies of each other in the database
955 $result = db_query('SELECT * FROM {buddylist} WHERE uid = %d AND buddy = %d', $requestee_account->uid, $requester_account->uid);
956
957 $time = time();
958
959 if (!db_num_rows($result)) {
960 db_query('INSERT INTO {buddylist} (uid, buddy, timestamp, received) VALUES (%d, %d, %d, %d)', $requestee_account->uid, $requester_account->uid, $time, 1);
961 }
962
963 $result = db_query('SELECT * FROM {buddylist} WHERE uid = %d AND buddy = %d', $requester_account->uid, $requestee_account->uid);
964 if (!db_num_rows($result)) {
965 db_query('INSERT INTO {buddylist} (uid, buddy, timestamp, received) VALUES (%d, %d, %d, %d)', $requester_account->uid, $requestee_account->uid, $time, 1);
966 }
967
968 if (variable_get('buddylist_send_approval', FALSE)) {
969 buddylist_mail_user('approval', $requester_account, $requestee_account);
970 }
971
972 drupal_set_message(t('Congratulations! !linktouser is now your buddy.', array('!linktouser' => theme('username', $requester_account)) + buddylist_translation()));
973
974 return 'buddylist/'. $requestee_account->uid .'/buddies/requests';
975 }
976
977 function buddylist_pending_requested_deny_submit($form_id, $form_values) {
978 $requestee_account = $form_values['requestee_account']; // most likely global user, unless admin looking
979 $requester_account = $form_values['requester_account'];
980
981 // Delete pending request from {buddylist_penging_requests}
982 db_query('DELETE FROM {buddylist_pending_requests} WHERE requestee_uid = %d AND requester_uid = %d', $requestee_account->uid, $requester_account->uid);
983
984 drupal_set_message(t("!user's request to be your buddy has been denied.", array('!user' => theme('username', $requester_account)) + buddylist_translation()));
985
986 return 'buddylist/'. $requestee_account->uid .'/buddies/requests';
987 }
988
989 function buddylist_confirm_form($requester_account, $requestee_account) {
990 $form = array();
991
992 $form['requester_account'] = array(
993 '#type' => 'value'