#113653 by MarcoR: enhances block admin, including special message if buddylist is...
[project/buddylist.git] / buddylist.module
1 <?php
2 // $Id$
3
4 if (module_exists('views')) {
5 include_once('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 @buddy list"));
11 define('BUDDYLIST_REQUEST_SUBJECT', variable_get('buddylist_request_subject', "[@site] @adder_name has requested to add you to his/her @buddy list"));
12 define('BUDDYLIST_APPROVAL_SUBJECT', variable_get('buddylist_approval_subject', "[@site] @addee_name has approved your @buddy list 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/settings/modules#description':
41 return t('Enable @buddy list functionality.', buddlist_translation());
42 case 'admin/help#buddylist':
43 $output = t("
44 <p>@Buddy list enables users to keep a list of @buddies from their social network in their user account.
45 Users can also track what their @buddies are posting to the site.
46 Furthermore, they can track their <i>@buddies'</i> @buddies and thereby explore their social network.</p>
47 <p>If the administrator has enabled the profile module, users can add @buddies via their @buddies' user profiles.
48 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.
49 If a user is already in your @buddy list, the 'delete' action will remove the @buddy. Administrators can also enable the @buddylist block.
50 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 @buddy lists with other FOAF-aware social networking applications.</p>
51 <p>You can:</p>
52 <ul>
53 <li>add a @buddy by looking at their profile: <a href=\"@userprofiles\" title=\"View user profiles\">view user profiles</a></li>
54 <li>allow users to view profiles in <a href=\"@setaccesspermissions\" title=\"set access permissions\">administer &raquo; access control</a></li>
55 <li>enable the @buddy list block at <a href=\"@blockadministration\" title=\"block administration\">administer &raquo; block</a></li>
56 <li>administer the @buddy list block at <a href=\"@buddylistsettings\" title=\"@buddylist settings\">administer &raquo; settings &raquo; @buddylist</a></li>
57 </ul>
58
59 <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>",
60 array('@userprofiles' => url('profile'),
61 '@setaccesspermissions' => url('admin/user/access'),
62 '@blockadministration' => url('admin/build/block'),
63 '@buddylistsettings' => url('admin/settings/buddylist')
64 ) + buddylist_translation());
65 return $output;
66 }
67 }
68
69
70 /**
71 * Implementation of hook_perm
72 */
73 function buddylist_perm() {
74 return array('maintain buddy list', 'view buddy lists');
75 }
76
77 /**
78 * Implementation of hook_menu
79 */
80 function buddylist_menu($may_cache) {
81 global $user;
82
83 $items = array();
84 $id = is_numeric(arg(1)) ? arg(1) : $user->uid;
85
86 if ($may_cache) {
87 // buddylist settings page
88 $items[] = array(
89 'path' => 'admin/settings/buddylist',
90 'title' => t('Buddylist'), // Note that this isn't translated on purpose since it is for the admin
91 'description' => t('Buddylist configuration options for blocks, email, etc.'),
92 'callback' => 'drupal_get_form',
93 'callback arguments' => 'buddylist_admin_settings',
94 'access' => user_access('administer site configuration'),
95 );
96 // my buddylist menu item
97 $items[] = array(
98 'path' => 'buddylist',
99 'title' => t('My @buddylist', buddylist_translation()),
100 'access' => (user_access('maintain buddy list') && $id),
101 'callback' => 'buddylist_buddylisting_page',
102 'callback arguments' => array($user->uid, 'buddies'),
103 );
104 }
105 else {
106 // 'edit access' only granted to user's own buddy list or to administrative users
107 $editAccess = (
108 ($id == $user->uid && user_access('maintain buddy list') && $user->uid)
109 || user_access('administer users'));
110
111 $approval_required = variable_get('buddylist_require_approval', 0);
112
113 $items[] = array(
114 'path' => 'buddy/add',
115 'title' => t('Add to @buddylist', buddylist_translation()),
116 'access' => $editAccess,
117 'callback' => 'drupal_get_form',
118 'callback arguments' => array('buddylist_addbuddy', arg(2)),
119 'type' => MENU_CALLBACK,
120 );
121 $items[] = array(
122 'path' => 'buddy/delete',
123 'title' => t('Delete from @buddylist', buddylist_translation()),
124 'access' => $editAccess,
125 'callback' => 'drupal_get_form',
126 'callback arguments' => array('buddylist_deletebuddy', arg(2)),
127 'type' => MENU_CALLBACK,
128 );
129
130 // 'view only' tabs
131 $viewAccess = (($id == $user->uid && user_access('maintain buddy list')) || user_access('view buddy lists'));
132
133 // If buddylist approval is required, then upon approval, both parties become buddies of each other.
134 // So, in effect, idea 'buddyof' becomes redundant.
135 if (!$approval_required) {
136 $items[] = array(
137 'path' => 'buddylist/'. $id .'/buddies',
138 'title' => t('@Buddies', buddylist_translation()),
139 'access' => $viewAccess,
140 'callback' => 'buddylist_buddylisting_page',
141 'type' => MENU_DEFAULT_LOCAL_TASK,
142 'weight' => -1,
143 'callback arguments' => array($id)
144 );
145 $items[] = array(
146 'path' => 'buddylist/'. $id .'/buddyof',
147 'title' => t('@Buddyof', buddylist_translation()),
148 'access' => $viewAccess,
149 'callback' => 'buddylist_buddylisting_page',
150 'type' => MENU_LOCAL_TASK,
151 'weight' => 1,
152 'callback arguments' => array($id, 'buddyof')
153 );
154 }
155
156 // subtabs
157 $items[] = array(
158 'path' => 'buddylist/'. $id .'/buddies/list',
159 'title' => t('@Buddylist', buddylist_translation()),
160 'access' => $viewAccess,
161 'callback' => 'buddylist_buddylisting_page',
162 'type' => MENU_DEFAULT_LOCAL_TASK,
163 'weight' => -1,
164 'callback arguments' => array($id),
165 );
166 $items[] = array(
167 'path' => 'buddylist/'. $id .'/buddies/recent',
168 'title' => t('Recent posts'),
169 'access' => ($viewAccess && module_exists('tracker')),
170 'callback' => 'buddylist_buddiesrecent_page',
171 'type' => MENU_LOCAL_TASK,
172 'weight' => 3,
173 'callback arguments' => array($id),
174 );
175 if (variable_get('buddylist_buddygroups', FALSE)) {
176 $items[] = array(
177 'path' => 'buddylist/'. $id .'/buddies/groups/view',
178 'title' => t('View groups'),
179 'access' => $viewAccess,
180 'callback' => 'buddylist_buddiesgroups_page',
181 'type' => MENU_LOCAL_TASK,
182 'weight' => 5,
183 'callback arguments' => array($id),
184 );
185 $items[] = array(
186 'path' => 'buddylist/'. $id .'/buddies/groups/edit',
187 'title' => t('Edit groups'),
188 'access' => $editAccess,
189 'callback' => 'buddylist_buddiesgroups_edit',
190 'type' => MENU_LOCAL_TASK,
191 'weight' => 6,
192 'callback arguments' => array($id),
193 );
194 }
195
196 // sub-subtabs
197 if ($approval_required && $editAccess) {
198 $items[] = array(
199 'path' => 'buddylist/'. $id .'/buddies/requests',
200 'title' => t('Pending requests'),
201 'access' => $editAccess,
202 'callback' => 'theme',
203 'type' => MENU_LOCAL_TASK,
204 'weight' => 0,
205 'callback arguments' => array('buddylist_pending_requests', $id)
206 );
207 }
208
209 // other callbacks
210 if ($id != $user->uid) {
211 // This callback can interfere with the 'my buddylist' menu item,
212 // so we only load it if the user is viewing another user's list.
213 $items[] = array(
214 'path' => 'buddylist/'. $id,
215 'title' => t('@Buddylist', buddylist_translation()),
216 'access' => (($viewAccess || $editAccess) && $id),
217 'callback' => 'buddylist_buddylisting_page',
218 'type' => MENU_CALLBACK,
219 'callback arguments' => array($id),
220 );
221 }
222 $items[] = array(
223 'path' => 'buddylist/'. $id .'/buddies/recent/feed',
224 'title' => t('Xml feed'),
225 'access' => $viewAccess,
226 'callback' => 'buddylist_buddyfeed',
227 'type' => MENU_CALLBACK,
228 'callback arguments' => array($id),
229 );
230 }
231
232 return $items;
233 }
234
235 /**
236 * Buddylist administration settings page
237 */
238 function buddylist_admin_settings() {
239 $form['general'] = array(
240 '#type' => 'fieldset',
241 '#title' => t('General settings'),
242 );
243
244 $form['general']['buddylist_require_approval'] = array(
245 '#type' => 'radios',
246 '#title' => t('Require approval'),
247 '#default_value' => variable_get('buddylist_require_approval', 0),
248 '#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()),
249 '#options' => array(1 => t('Yes'), 0 => t('No'))
250 );
251 $form['general']['buddylist_buddygroups'] = array(
252 '#type' => 'checkbox',
253 '#title' => t('Enable @buddy groups', buddylist_translation()),
254 '#description' => t('Enables @buddylist @buddy groups. Users will be able to create @buddy groups to manage their @buddies.', buddylist_translation()),
255 '#default_value' => variable_get('buddylist_buddygroups', FALSE),
256 );
257
258 // User profile page settings
259 $form['profile_settings'] = array(
260 '#type' => 'fieldset',
261 '#title' => t('Profile page options'),
262 );
263 $form['profile_settings']['buddylist_prof_buddies'] = array(
264 '#type' => 'select',
265 '#title' => t('Number of @buddies and users who\'ve added me', buddylist_translation()),
266 '#default_value' => variable_get('buddylist_prof_buddies', 5),
267 '#options' => drupal_map_assoc(range(0, 10)),
268 '#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()),
269 );
270
271 // TODO: move these to block settings
272 $form['block_settings'] = array(
273 '#type' => 'fieldset',
274 '#title' => t('@Buddylist block options', buddylist_translation()),
275 );
276 $form['block_settings']['buddylist_blocklisting_size'] = array(
277 '#type' => 'select',
278 '#title' => t("Number of @buddies to list in the user's @buddy block", buddylist_translation()),
279 '#default_value' => variable_get('buddylist_blocklisting_size', 5),
280 '#options' => drupal_map_assoc(array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20, 25, 30)),
281 '#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()),
282 );
283 $form['block_settings']['buddylist_posts_block'] = array(
284 '#type' => 'select',
285 '#title' => t("Number of posts to list in the @buddies' recent posts block", buddylist_translation()),
286 '#default_value' => variable_get('buddylist_posts_block', 7),
287 '#options' => drupal_map_assoc(array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20, 25, 30)),
288 '#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()),
289 );
290 $form['block_settings']['buddylist_block_title'] = array(
291 '#type' => 'textfield',
292 '#title' => t('"My @buddies\' recent posts" block title', buddylist_translation()),
293 '#default_value' => variable_get('buddylist_block_title', t("My @buddies' recent posts", buddylist_translation())),
294 '#size' => 70,
295 '#maxlength' => 128,
296 '#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()),
297 );
298 $form['block_settings']['buddylist_status_block_title'] = array(
299 '#type' => 'textfield',
300 '#title' => t('"My @buddy list status" block title', buddylist_translation()),
301 '#default_value' => variable_get('buddylist_status_block_title', t("My @buddy list status", buddylist_translation())),
302 '#size' => 70,
303 '#maxlength' => 128,
304 '#description' => t('This will be the title for the @buddy list status block. If none is specified, "My @buddy list status" will be used.', buddylist_translation()),
305 );
306 $form['block_settings']['buddylist_list_block_title'] = array(
307 '#type' => 'textfield',
308 '#title' => t('"My @buddies list" block title', buddylist_translation()),
309 '#weight' => 1,
310 '#default_value' => variable_get('buddylist_list_block_title', t('My @buddy list', buddylist_translation())),
311 '#size' => 70,
312 '#maxlength' => 128,
313 '#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()),
314 );
315 $form['block_settings']['buddylist_block_if_no_buddies'] = array(
316 '#type' => 'checkbox',
317 '#title' => t('Show "My @buddies list" block even if @buddylist is empty', buddylist_translation()),
318 '#weight' => 2,
319 '#default_value' => variable_get('buddylist_block_if_no_buddies', FALSE),
320 '#description' => t('If a user has no @buddies, the @buddy block can show a message.', buddylist_translation()),
321 );
322 $form['block_settings']['buddylist_empty_text'] = array(
323 '#type' => 'textarea',
324 '#title' => t('Show this text in "My @buddies list" if @buddylist is empty', buddylist_translation()),
325 '#weight' => 3,
326 '#default_value' => variable_get('buddylist_empty_text', t(buddylist_empty_text_default(), buddylist_translation())),
327 '#description' => t('If a user has no @buddies and the above checkbox is checked, this message is shown instead of a list.', buddylist_translation()),
328 );
329
330 $form['mail'] = array(
331 '#type' => 'fieldset',
332 '#title' => t('email'),
333 );
334
335 global $user;
336 $macros = implode(', ', array_keys(buddylist_mail_replacements($user, $user)));
337 $approval_macros = implode(', ', array_keys(buddylist_approval_mail_replacements($user, $user)));
338
339 $form['mail']['buddylist_user_mail'] = array(
340 '#type' => 'checkbox',
341 '#title' => t('Allow users to turn off buddylist messages'),
342 '#default_value' => variable_get('buddylist_user_mail', FALSE),
343 '#description' => t('If you check this, users will have a new setting on their account edit page.'),
344 );
345
346 $form['mail']['buddylist_send_add'] = array(
347 '#type' => 'checkbox',
348 '#title' => t('Send add messages'),
349 '#default_value' => variable_get('buddylist_send_add', FALSE),
350 );
351
352 $form['mail']['buddylist_add_subject'] = array(
353 '#type' => 'textfield',
354 '#title' => t('Added @buddy email subject', buddylist_translation()),
355 '#default_value' => BUDDYLIST_ADD_SUBJECT,
356 );
357
358 $form['mail']['buddylist_add_message'] = array(
359 '#type' => 'textarea',
360 '#title' => t('Added @buddy email message', buddylist_translation()),
361 '#default_value' => variable_get('buddylist_add_message', buddylist_mail_add_default()),
362 '#description' => t('Replacement strings are: %macros', array('%macros' => $macros)),
363 );
364
365 $form['mail']['buddylist_send_remove'] = array(
366 '#type' => 'checkbox',
367 '#title' => t('Send remove messages'),
368 '#default_value' => variable_get('buddylist_send_remove', FALSE),
369 );
370
371 $form['mail']['buddylist_remove_subject'] = array(
372 '#type' => 'textfield',
373 '#title' => t('Removed @buddy email subject', buddylist_translation()),
374 '#default_value' => BUDDYLIST_REMOVE_SUBJECT,
375 );
376
377 $form['mail']['buddylist_remove_message'] = array(
378 '#type' => 'textarea',
379 '#title' => t('Removed @buddy email message', buddylist_translation()),
380 '#default_value' => variable_get('buddylist_remove_message', buddylist_mail_remove_default()),
381 '#description' => t('Replacement strings are: %macros', array('%macros' => $macros)),
382 );
383
384 $form['mail']['buddylist_send_request'] = array(
385 '#type' => 'checkbox',
386 '#title' => t('Send request messages.'),
387 '#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.'),
388 '#default_value' => variable_get('buddylist_send_request', FALSE)
389 );
390
391 $form['mail']['buddylist_request_subject'] = array(
392 '#type' => 'textfield',
393 '#title' => t('@buddy request email subject', buddylist_translation()),
394 '#default_value' => BUDDYLIST_REQUEST_SUBJECT,
395 );
396
397 $form['mail']['buddylist_request_message'] = array(
398 '#type' => 'textarea',
399 '#title' => t('@buddy request email message', buddylist_translation()),
400 '#default_value' => variable_get('buddylist_request_message', buddylist_mail_request_default()),
401 '#description' => t('Replacement strings are: %macros', array('%macros' => $macros)),
402 );
403
404 $form['mail']['buddylist_send_approval'] = array(
405 '#type' => 'checkbox',
406 '#title' => t('Send approval messages'),
407 '#default_value' => variable_get('buddylist_send_approval', FALSE),
408 '#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())
409 );
410
411 $form['mail']['buddylist_approval_subject'] = array(
412 '#type' => 'textfield',
413 '#title' => t('@buddy request email subject', buddylist_translation()),
414 '#default_value' => BUDDYLIST_APPROVAL_SUBJECT,
415 );
416
417 $form['mail']['buddylist_approval_message'] = array(
418 '#type' => 'textarea',
419 '#title' => t('@buddy approval email message', buddylist_translation()),
420 '#default_value' => variable_get('buddylist_approval_message', buddylist_mail_approval_default()),
421 '#description' => t('Replacement strings are: %macros', array('%macros' => $approval_macros)),
422 );
423
424 return system_settings_form($form);
425 }
426
427
428 /**
429 * Implementation of hook_user
430 */
431 function buddylist_user($type, &$edit, &$thisuser, $category = NULL) {
432 global $user;
433
434 $output = array();
435 // show any buddylist notifications upon login and upon viewing own profile
436 if (user_access('maintain buddy list') && (($type == 'login') || ($type == 'view') && ($thisuser->uid == $user->uid))) {
437 buddylist_setmsg_received($thisuser);
438 }
439 if ($type == 'view') {
440 if ($list = buddylist_get_buddylist($thisuser)) {
441 $output[] = array('title' => t('@Buddies', buddylist_translation()), 'value' => $list, 'class' => 'buddylist');
442 }
443 if ($list = buddylist_get_buddylist($thisuser, TRUE)) {
444 $output[] = array('title' => t('@buddy of', buddylist_translation()), 'value' => $list, 'class' => 'buddyoflist');
445 }
446 if ($actions = buddylist_get_buddy_actions($user, $thisuser)) {
447 $output[] = array('title' => t('@Buddy actions', buddylist_translation()), 'value' => theme('item_list', $actions), 'class' => 'buddylist_actions');
448 }
449 if(count($output) > 0) {
450 return array(t('@Buddy List', buddylist_translation()) => $output);
451 }
452 }
453 else if ($type == 'delete') {
454 db_query("DELETE FROM {buddylist} WHERE uid = %d OR buddy = %d", $thisuser->uid, $thisuser->uid);
455 db_query("DELETE FROM {buddylist_buddy_group} WHERE uid = %d OR buddy = %d", $thisuser->uid, $thisuser->uid);
456 db_query("DELETE FROM {buddylist_groups} WHERE uid = %d", $thisuser->uid);
457 db_query("DELETE FROM {buddylist_pending_requests} WHERE requester_uid = %d OR requestee_uid = %d", $thisuser->uid, $thisuser->uid);
458 }
459 else if ($type == 'load') {
460 $thisuser->buddies = buddylist_get_buddies($thisuser->uid);
461 }
462 else if ($type == 'form' && $category == 'account' && variable_get('buddylist_user_mail', FALSE) && user_access('maintain buddy list', $thisuser)) {
463 // when user tries to edit his own data
464 $form['buddylist_settings'] = array(
465 '#type' => 'fieldset',
466 '#title' => t('Buddylist settings'),
467 '#weight' => 5);
468 $form['buddylist_settings']['buddylist_mail'] = array(
469 '#type' => 'checkbox',
470 '#title' => t('Receive @buddylist notification mails', buddylist_translation()),
471 '#default_value' => isset($edit['buddylist_mail']) ? $edit['buddylist_mail'] : 1,
472 '#description' => t('If you check this, you will be notified about important actions regarding your @Buddylist.', buddylist_translation()));
473 return $form;
474 }
475 }
476
477 /*
478 * Return a formatted list of buddies for the given user
479 * @param $buddy_of If set to TRUE, a formatted list of users is returned, for whom this user is a buddy.
480 */
481 function buddylist_get_buddylist($user, $buddy_of = FALSE) {
482
483 if (user_access('view buddy lists') && !$buddy_of) {
484 $i = 0;
485 if ($buddies = buddylist_get_buddies($user->uid)) {
486 foreach(array_keys($buddies) as $buddy) {
487 $account = user_load(array('uid' => $buddy));
488 $listbuddies[] = $account;
489 $i++;
490 if ($i > variable_get('buddylist_prof_buddies', 5)) {
491 break;
492 }
493 }
494 return theme('user_list', $listbuddies);
495 }
496 }
497 else if (user_access('view buddy lists') && !variable_get('buddylist_require_approval', 0)) {
498 // This portion of code is used to see if this $thisuser is a buddy of others and, if s/he is, returns a list
499 // of people s/he is a buddy of.
500 // Note the distinction between having a buddy and being someone else's buddy (i.e., 'buddyof')
501 // Of course, this distinction doesn't exist if approval is required to add a buddy (in which case, buddy relationships are symmetric)
502 $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';
503 $result = db_query_range($sql, $user->uid, 0, variable_get('buddylist_prof_buddies', 5));
504 while ($row = db_fetch_object($result)) {
505 $listbuddyof[$row->uid] = $row;
506 }
507 if ($listbuddyof) {
508 return theme('user_list', $listbuddyof);
509 }
510 }
511 }
512
513
514 /*
515 * Returns an array of posible actions (html) for the viewing user,
516 * e.g. a link to make the viewed user a buddy
517 */
518 function buddylist_get_buddy_actions(&$viewing_user, &$viewed_user) {
519
520 $actions = array();
521 if (!user_access('maintain buddy list') || $viewing_user->uid == $viewed_user->uid) {
522 return $actions;
523 }
524
525 if (variable_get('buddylist_require_approval', FALSE) && in_array($viewed_user->uid, array_keys(buddylist_get_requestees($viewing_user->uid)))) {
526 $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());
527 }
528 else if (in_array($viewed_user->uid, array_keys(buddylist_get_buddies($viewing_user->uid)))) {
529 $actions[] = theme('remove_from_buddylist_link', $viewed_user);
530 }
531 else if (in_array($viewing_user->uid, array_keys(buddylist_get_requestees($viewed_user->uid)))) {
532 $actions[] = t('This user has requested to add you to your @buddylist.', buddylist_translation()) .
533 drupal_get_form('buddylist_approval_form', $viewing_user->uid, $viewed_user->uid);
534 }
535 else {
536 $actions[] = theme('add_to_buddylist_link', $viewed_user);
537 }
538
539 return $actions;
540 }
541
542
543 /**
544 * Implementation for hook_block
545 */
546 function buddylist_block($op = 'list', $delta = 0) {
547 global $user;
548
549 if ($op == 'list') {
550 $block[0]['info'] = variable_get('buddylist_list_block_title', t('My @buddy list', buddylist_translation()));
551 $block[1]['info'] = variable_get('buddylist_block_title', t('My @buddies\' recent posts', buddylist_translation()));
552 if (variable_get('buddylist_require_approval', 0)) {
553 $block[2]['info'] = variable_get('buddylist_status_block_title', t('My @buddy status', buddylist_translation()));
554 }
555 return $block;
556 }
557 else if ($op == 'view' && user_access('access content') && user_access('maintain buddy list') && $user->uid > 0) {
558 switch ($delta) {
559 case 0 : // Shows buddylist block
560 if ($buddies = buddylist_get_buddies()) {
561 // we have buddies defined and generate the list
562 $i = 0;
563 foreach (array_keys($buddies) as $buddy) {
564 $users[] = user_load(array('uid' => $buddy));
565 $i++;
566 if ($i == variable_get('buddylist_blocklisting_size', 5)) {
567 break;
568 }
569 }
570 $block['content'] = theme('user_list', $users);
571 } else {
572 // buddylist is empty
573 if(variable_get('buddylist_block_if_no_buddies', FALSE)) {
574 // Show a message that we have no buddies yet
575 $block['content'] = variable_get('buddylist_empty_text', t(buddylist_empty_text_default(), buddylist_translation()));
576 } else {
577 // If no buddies defined and no message available, end 'case' without returning block.
578 break;
579 }
580 }
581 // this is the same output whether buddylist or not
582 $block['subject'] = variable_get('buddylist_list_block_title', t('My @buddy list', buddylist_translation()));
583
584 // check if a "more" link should generated by seeing if there are more buddies than the specified $upperlimit
585 if (count($buddies) > variable_get('buddylist_blocklisting_size', 5)) {
586 $block['content'] .= '<div class="more-link">' . l(t('more'), 'buddylist', array('title' => t('View more.'))) . '</div>';
587 }
588 return $block;
589 break;
590
591 case 1: // Shows my buddies recent posts block
592 $buddies = buddylist_get_buddies();
593 $keys = array_keys($buddies);
594 if (count($keys) > 0) {
595 $str_buddies = implode(',', $keys);
596 $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));
597
598 if (db_num_rows($result)) {
599 $block['subject'] = variable_get('buddylist_block_title', t('My @buddies\' recent posts', buddylist_translation()));
600 $block['content'] = node_title_list($result);
601
602 // check if a "more" link should generated by seeing if there are more buddies than the specified $upperlimit
603 $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);
604 $countresult = db_fetch_object($result);
605
606 if (variable_get('buddylist_posts_block', 7) < $countresult->node_count) {
607 $block['content'] .= '<div class="more-link">'. l(t('more'), 'buddylist/'. $user->uid .'/buddies/recent', array('title' => t('View more.'))) .'</div>';
608 }
609 return $block;
610 }
611 }
612 break;
613
614 case 2: // Buddylist status
615 $block['subject'] = variable_get('buddylist_status_block_title', t('My @buddy status', buddylist_translation()));
616
617 $count = db_result(db_query("SELECT COUNT(uid) FROM {buddylist} WHERE uid = %d", $user->uid));
618 $sent = db_result(db_query("SELECT COUNT(requester_uid) FROM {buddylist_pending_requests} WHERE requester_uid = %d", $user->uid));
619 $received = db_result(db_query("SELECT COUNT(requestee_uid) FROM {buddylist_pending_requests} WHERE requestee_uid = %d", $user->uid));
620
621 $block['content'] = theme('buddylist_status_block', $count, $received, $sent);
622 return $block;
623 break;
624 }
625 }
626 }
627
628 /**
629 * Public API for retrieving buddies. Feel free to use this from other
630 * modules.
631 * $key can be 'uid' or 'label'.
632 */
633 function buddylist_get_buddies($uid = NULL, $key = 'uid') {
634 static $buddies;
635
636 if (!$uid) {
637 global $user;
638 $uid = $user->uid;
639 }
640 if (!isset($buddies[$key][$uid])) {
641 $buddies[$key][$uid] = array();
642 $sql = 'SELECT b.buddy, u.name, u.mail, u.uid FROM {buddylist} b
643 INNER JOIN {users} u ON b.buddy = u.uid
644 WHERE b.uid = %d';
645 $result = db_query($sql, $uid);
646 while ($row = db_fetch_object($result)) {
647 $buddies[$key][$uid][$row->buddy]['uid'] = $row->uid;
648 $buddies[$key][$uid][$row->buddy]['name'] = $row->name;
649 $buddies[$key][$uid][$row->buddy]['mail'] = $row->mail;
650 $buddies[$key][$uid][$row->buddy]['groups'] = buddylist_get_buddy_groups($uid, $row->buddy);
651 $buddies[$key][$uid][$row->buddy]['online'] = 0;
652 $selectlist .= $row->buddy.",";
653 }
654 // Add the online flag
655 if (db_num_rows($result)) {
656 $sql = 'SELECT uid FROM {sessions} WHERE uid IN (%s) AND timestamp > %d';
657 $result = db_query($sql, substr($selectlist,0,-1), time()-1800);
658 while ($row = db_fetch_object($result)) {
659 $buddies[$key][$uid][$row->uid]['online'] = 1;
660 }
661 }
662 }
663
664 return $buddies[$key][$uid];
665 }
666
667 /**
668 * Returns an array of uid => name of people that user with param $uid has made a buddy request to
669 */
670 function buddylist_get_requestees($uid) {
671 $buddies = array();
672
673 $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);
674
675 while ($row = db_fetch_object($result)) {
676 $buddies[$row->requestee_uid] = $row->name;
677 }
678
679 return $buddies;
680 }
681
682 function buddylist_setmsg_received($thisuser) {
683 global $user;
684
685 if (variable_get('buddylist_require_approval', 0)) {
686 // Go through and find new buddylist add-requests, (i.e., the ones in {buddylist_pending_requests} w/ received column == 0
687 $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);
688 $acknowledged_uids = array();
689 while ($row = db_fetch_object($result)) {
690 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()));
691 $acknowledged_uids[] = $row->uid;
692 }
693 if (count($acknowledged_uids)) {
694 db_query('UPDATE {buddylist_pending_requests} SET received = 1 WHERE requestee_uid = %d AND requester_uid IN (%s)', $user->uid, implode(',', $acknowledged_uids));
695 }
696 }
697 else {
698 $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);
699 while ($rec = db_fetch_object($check_received)) {
700 if (($rec->received) and ($thisuser->uid == $user->uid)) {
701 // TODO: This is where integration with Privatemsg could happen. If enabled, send a private message instead.
702 drupal_set_message(t('!linktouser has added you to his/her @buddylist.', array('!linktouser' => theme('username', $rec)) + buddylist_translation()));
703 db_query('UPDATE {buddylist} SET received = 0 WHERE buddy = %d', $user->uid);
704 }
705 }
706 }
707 }
708
709 /**
710 * expose add and remove links to theming.
711 */
712 function theme_remove_from_buddylist_link($buddyuser) {
713 return l(t('Remove %name from my @buddy list', array('%name' => $buddyuser->name) + buddylist_translation()), 'buddy/delete/' . $buddyuser->uid, NULL, drupal_get_destination(), NULL, FALSE, TRUE);
714 }
715
716 function theme_add_to_buddylist_link($buddyuser) {
717 return l(t('Add %name to my @buddy list', array('%name' => $buddyuser->name) + buddylist_translation()), 'buddy/add/' . $buddyuser->uid, NULL, drupal_get_destination(), NULL, FALSE, TRUE);
718 }
719
720
721 /**
722 * Displays a list of a given user's buddies.
723 */
724 function buddylist_buddylisting_page($uid = NULL, $mode = 'buddies') {
725 global $user;
726
727 if (empty($uid)) {
728 $uid = $user->uid;
729 }
730 // Check that the uid is valid, not the anonymous user, and the user exists
731 if (!(is_numeric($uid) && ($uid > 0) && $thisuser = user_load(array('uid' => $uid)))) {
732 drupal_not_found();
733 exit();
734 }
735
736 drupal_set_title(t('%username\'s @buddylist', array('%username' => $thisuser->name) + buddylist_translation()));
737
738 $buddies_per_page = 20;
739
740 //TODO: use the get_buddies function instead
741 if ($mode == 'buddies') {
742 $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";
743 }
744 else {
745 $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";
746 }
747 $result = pager_query($sql, $buddies_per_page, 0 , NULL, $uid);
748
749 $header = array(t('@buddy', buddylist_translation()), t('online'));
750 $online_interval = time() - variable_get('user_block_seconds_online', 180);
751
752 if (db_num_rows($result)) {
753 while ($account = db_fetch_object($result)) {
754 $online = $account->access > $online_interval;
755 $rows[] = array(theme('username', user_load(array('uid' => $account->buddy))), theme('buddylist_online', $online));
756 }
757 $output .= theme('table', $header, $rows);
758 }
759 else {
760 $output .= variable_get('buddylist_empty_text', t(buddylist_empty_text_default(), buddylist_translation()));
761 }
762
763 $output .= theme('pager', NULL, $buddies_per_page);
764
765 return $output;
766 }
767
768 /**
769 * Returns a list of people who've requested to be added to the given user's buddylist
770 * and a list of people who this given user has requested to be buddies with.
771 */
772 function theme_buddylist_pending_requests($id) {
773
774 $thisuser = user_load(array('uid' => $id));
775 drupal_set_title(t('@username\'s @buddylist', array('@username' => $thisuser->name) + buddylist_translation()));
776
777 return theme('box', t('Received requests'), buddylist_pending_requester_list($thisuser)) .
778 theme('box', t('Sent requests'), buddylist_pending_requested_list($thisuser));
779 }
780
781 /**
782 * Returns a list of people who've requested to be added to the given user's buddylist
783 */
784 function buddylist_pending_requester_list(&$account) {
785 global $user;
786
787 $viewing_own_account = ($user->uid == $account->uid);
788 $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);
789
790 if (!db_num_rows($result)) {
791 $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>';
792 }
793 else {
794 $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>';
795
796 $html_rows = array();
797 while ($row = db_fetch_object($result)) {
798 $html_row = array();
799 $html_row[] = theme('username', $row);
800 $html_row[] = drupal_get_form('buddylist_approval_form', $account->uid, $row->uid, $row->name);
801 $html_rows[] = $html_row;
802 }
803
804 $output .= theme('table', NULL, $html_rows);
805 }
806
807 return $output;
808 }
809
810 /**
811 * Returns a list of user's who this given user has requested to be buddies with.
812 */
813 function buddylist_pending_requested_list(&$account) {
814 global $user;
815
816 $viewing_own_account = ($user->uid == $account->uid);
817 $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);
818
819 if (!db_num_rows($result)) {
820 $output = t('!Person !do_or_does not have any pending @buddy requests that !person !have_or_has made.',
821 array(
822 '!Person' => ($viewing_own_account ? t('You') : $account->name),
823 '!do_or_does' => ($viewing_own_account ? t('do') : t('does')),
824 '!have_or_has' => ($viewing_own_account ? t('have') : t('has')),
825 '!person' => ($viewing_own_account ? t('you') : $account->name) ) + buddylist_translation());
826 }
827 else {
828 $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());
829
830 $html_rows = array();
831 while ($row = db_fetch_object($result)) {
832 $html_row = array();
833 $html_row[] = theme('username', $row);
834 $html_row[] = drupal_get_form('buddylist_request_cancel_form', $row->uid, $account->uid);
835 $html_rows[] = $html_row;
836 }
837
838 $output .= theme('table', NULL, $html_rows);
839 }
840
841 return $output;
842 }
843
844
845 function buddylist_approval_form($requestee_uid, $requester_uid) {
846 $form = array();
847
848 $form['requestee_uid'] = array(
849 '#type' => 'hidden',
850 '#value' => $requestee_uid,
851 );
852
853 $form['requester_uid'] = array(
854 '#type' => 'hidden',
855 '#value' => $requester_uid
856 );
857
858 $form['approve'] = array(
859 '#type' => 'submit',
860 '#value' => t('Approve')
861 );
862
863 $form['deny'] = array(
864 '#type' => 'submit',
865 '#value' => t('Deny'),
866 );
867
868 return $form;
869 }
870
871 function buddylist_approval_form_submit($form_id, $form_values) {
872 $requestee_account = user_load(array('uid' => $form_values['requestee_uid'])); // most likely global user, unless admin looking
873
874 // Delete pending request from {buddylist_penging_requests}
875 db_query('DELETE FROM {buddylist_pending_requests} WHERE requestee_uid = %d AND requester_uid = %d', $form_values['requestee_uid'], $form_values['requester_uid']);
876
877 $requester_account = user_load(array('uid' => $form_values['requester_uid']));
878
879 if ($form_values['op'] == t('Approve')) {
880 // Make sure, for some weird reason, we don't already have these guys marked as buddies of each other in the database
881 $result = db_query('SELECT * FROM {buddylist} WHERE uid = %d AND buddy = %d', $form_values['requestee_uid'], $form_values['reqeuster_uid']);
882
883 $time = time();
884
885 if (!db_num_rows($result)) {
886 db_query('INSERT INTO {buddylist} (uid, buddy, timestamp, received) VALUES (%d, %d, %d, %d)', $form_values['requestee_uid'], $form_values['requester_uid'], $time, 1);
887 }
888
889 $result = db_query('SELECT * FROM {buddylist} WHERE uid = %d AND buddy = %d', $form_values['requester_uid'], $form_values['requestee_uid']);
890 if (!db_num_rows($result)) {
891 db_query('INSERT INTO {buddylist} (uid, buddy, timestamp, received) VALUES (%d, %d, %d, %d)', $form_values['requester_uid'], $form_values['requestee_uid'], $time, 1);
892 }
893
894 if (variable_get('buddylist_send_approval', FALSE)) {
895 buddylist_mail_user('approval', $requester_account, $requestee_account);
896 }
897
898 drupal_set_message(t('Congratulations! !linktouser is now your @buddy.', array('!linktouser' => theme('username', $requester_account)) + buddylist_translation()));
899 }
900 else {
901 drupal_set_message(t("!user's request to be your @buddy has been denied.", array('!user' => theme('username', $requester_account)) + buddylist_translation()));
902 }
903 }
904
905 function buddylist_request_cancel_form($requestee_uid, $requester_uid) {
906 $form['requestee_uid'] = array(
907 '#type' => 'hidden',
908 '#value' => $requestee_uid,
909 );
910
911 $form['requester_uid'] = array(
912 '#type' => 'hidden',
913 '#value' => $requester_uid
914 );
915
916 $form['cancel'] = array(
917 '#type' => 'submit',
918 '#value' => t('Cancel')
919 );
920
921 return $form;
922 }
923
924 function buddylist_request_cancel_form_submit($form_id, $form_values) {
925 db_query('DELETE FROM {buddylist_pending_requests} WHERE requester_uid = %d AND requestee_uid = %d', $form_values['requester_uid'], $form_values['requestee_uid']);
926
927 $former_potential_buddy = user_load(array('uid' => $form_values['requestee_uid']));
928 drupal_set_message(t('The request to add !user_name has been cancelled.', array('!user_name' => theme('username', $former_potential_buddy))));
929
930 return 'buddylist/'. $form_values['requester_uid'] .'/buddies/requests';
931 }
932
933 function buddylist_form_buddiesrecent_page($buddies) {
934 foreach ($buddies as $user_id => $buddy) {
935 $form[] = array('#type' => 'fieldset',
936 '#title' => $buddy['name'],
937 '#collapsible' => 'true',
938 '#value' => tracker_page($user_id),
939 );
940 }
941 return $form;
942 }
943
944 function buddylist_buddiesrecent_page($uid) {
945 global $user;
946
947 $thisuser = user_load(array('uid' => $uid));
948 drupal_set_title(t('%username\'s @buddylist', array('%username' => $thisuser->name) + buddylist_translation()));
949
950 $buddies = buddylist_get_buddies($uid);
951 $output .= drupal_get_form('buddylist_form_buddiesrecent_page', $buddies);
952 $output .= theme('xml_icon', url('buddylist/'. $uid .'/buddies/recent/feed'));
953 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') .'" />');
954
955 return $output;
956 }
957
958 function buddylist_buddiesgroups_page($uid) {
959 global $user;
960 $thisuser = user_load(array('uid' => $uid));
961 drupal_set_title(t('%username\'s @buddy groups', array('%username' => $thisuser->name) + buddylist_translation()));
962
963 $headers = array(t('@buddy', buddylist_translation()), t('online'), t('# of @buddies', buddylist_translation()), t("@buddy's posts", buddylist_translation()));
964
965 $result = db_query('SELECT label, label_id FROM {buddylist_groups} WHERE uid = %d ORDER BY label ASC', $thisuser->uid);
966 $groups = array();
967 while ($row = db_fetch_object($result)) {
968 $groups[$row->label_id] = $row->label;
969 }
970
971 if (count($groups) == 0) {
972 if ($thisuser->uid == $user->uid) {
973 drupal_set_message(
974 t("To organize your @buddies into groups, visit the !edit_groups page",
975 array('!edit_groups' =>
976 l(t('edit groups'), "buddylist/$uid/buddies/groups/edit")) + buddylist_translation())
977 );
978 }
979 return t('No groups found.');
980 }
981
982 $online_interval = time() - variable_get('user_block_seconds_online', 180);
983 $buddies = buddylist_get_buddies($thisuser->uid);
984
985 foreach ($groups as $label_id => $label) {
986 $result = pager_query('SELECT bg.buddy, u.access FROM {buddylist_buddy_group} bg INNER JOIN {users} u ON bg.buddy = u.uid WHERE bg.uid = %d and bg.label_id = %d', 10, 0, NULL, $thisuser->uid, $label_id);
987 $rows = array();
988 while ($row = db_fetch_object($result)) {
989 $online = $row->access > $online_interval;
990 $rows[] = array(
991 theme('username', (object)$buddies[$row->buddy]),
992 theme('buddylist_online', $online),
993 buddylist_count_buddies($row->buddy),
994 l(t('view posts'), 'user/'. $row->buddy. '/track')
995 );
996 }
997 $output .= theme('box', check_plain($label), $rows ? theme('table', $headers, $rows) : t('Group is empty.'));
998 }
999 return $output;
1000 }
1001
1002 function buddylist_count_buddies($uid) {
1003 $result = db_query("SELECT count(DISTINCT buddy) AS buddies FROM {buddylist} WHERE uid = %d", $uid);
1004 return db_result($result);
1005 }
1006
1007
1008 function buddylist_get_buddy_groups($uid, $buddy = NULL) {
1009 if (isset($buddy)) {
1010 $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 bg.label_id = bbg.label_id AND bbg.buddy = %d ", $uid, $buddy);
1011 }
1012 else {
1013 $result = db_query("SELECT * FROM {buddylist_groups} ", $uid);
1014 }
1015 $buddy_groups = array();
1016 while ($row = db_fetch_array($result)) {
1017 $buddy_groups[$row['label_id']] = $buddy ? $row : $row['label'];
1018 }
1019 return $buddy_groups;
1020 }
1021
1022
1023 function buddylist_form_edit_groups_add() {
1024 // Add group form
1025 $form['add_group'] = array(
1026 '#type' => 'textfield',
1027 '#title' => t('Add new group'),
1028 '#description' => t('Groups are a way to keep your @buddies organized. Groups can be named whatever you like.', buddylist_translation()),
1029 );
1030
1031 $form['submit'] = array(
1032 '#type' => 'submit',
1033 '#value' => t('Add'),
1034 );
1035
1036 return $form;
1037 }
1038
1039 function buddylist_form_edit_groups_remove($all_groups) {
1040 // Make a form to remove groups
1041 $form['remove']['groups'] = array(
1042 '#type' => 'checkboxes',
1043 '#return_value' => 1,
1044 '#title' => '',
1045 '#default_value' => null,
1046 '#options' => array_map('check_plain', $all_groups),
1047 );
1048
1049 $form['remove']['submit'] = array(
1050 '#type' => 'submit',
1051 '#value' => t('Remove'),
1052 );
1053
1054 return $form;
1055 }
1056
1057 function buddylist_form_edit_groups_table($buddies, $all_groups, $thisuser) {
1058 // Build the table with buddies and their groups
1059 $form['table']['groups'] = array ('#tree' => true);
1060 foreach ($buddies as $uid => $buddy) {
1061 $items = array();
1062 foreach ($buddy['groups'] as $group) {
1063 $items[] = $group['label_id'];
1064 }
1065
1066 if (count($all_groups) > 0) {
1067 $form['table']['groups'][$uid] = array(
1068 '#type' => 'checkboxes',
1069 '#title' => '',
1070 '#default_value' => $items,
1071 '#options' => array_map('check_plain', $all_groups),
1072 );
1073 }
1074 }
1075
1076 $form['table']['user'] = array(
1077 '#type' => 'value',
1078 '#value' => $thisuser->uid,
1079 );
1080
1081 if (count($form['table']['groups']) > 0) {
1082 $form['table']['submit'] = array(
1083 '#type' => 'submit',
1084 '#value' => t('Submit'),
1085 );
1086 }
1087
1088 return $form;
1089 }
1090
1091 /**
1092 * Callback for the buddygroup editing page
1093 */
1094 function buddylist_buddiesgroups_edit($uid) {
1095 $thisuser = user_load(array('uid' => $uid));
1096 drupal_set_title(t('%username\'s @buddy groups', array('%username' => $thisuser->name) + buddylist_translation()));
1097
1098 if ($buddies = buddylist_get_buddies($thisuser->uid)) {
1099 $output['add'] = drupal_get_form('buddylist_form_edit_groups_add');
1100
1101 $groups = buddylist_get_buddy_groups($uid);
1102
1103 if (count($groups) > 0) {
1104 $output['remove'] = drupal_get_form('buddylist_form_edit_groups_remove', $groups);
1105 $output['table'] = drupal_get_form('buddylist_form_edit_groups_table', $buddies, $groups, $thisuser);
1106 }
1107 else {
1108 drupal_set_message(t("You don't have any groups defined."));
1109 }
1110
1111 return theme('buddylist_edit_groups', $output);
1112 }
1113 else {
1114 drupal_set_message(t('Unable to edit @buddy groups. Add @buddies to your @buddylist before making groups.', buddylist_translation()));
1115 return t('No @buddies found.', buddylist_translation());
1116 }
1117 }
1118
1119 function theme_buddylist_edit_groups($forms) {
1120 $output = '<span id="buddylist-group-add-form">'.
1121 $forms['add'].
1122 '</span>'.
1123 '<span id="buddylist-group-remove-form">'.
1124 $forms['remove'].
1125 '</span>'.
1126 '<span id="buddlist-groups-form">'.
1127 $forms['table'].
1128 '</span>';
1129 return $output;
1130 }
1131
1132 function theme_buddylist_form_edit_groups_table($form) {
1133 $rows = array();
1134
1135 foreach ($form['table']['groups'] as $key => $value) {
1136 if(is_numeric($key)) {
1137 $rows[] = array(theme('username', user_load(array('uid' => $key))), drupal_render($form['table']['groups'][$key]));
1138 }
1139 }
1140
1141 $headers = array(t('buddy'), t('@buddy groups', buddylist_translation()));
1142 $output .= theme('table', $headers, $rows);
1143
1144 $output .= drupal_render($form);
1145
1146 return $output;
1147 }
1148
1149 function theme_buddylist_status_block($count, $received_count, $sent_count) {
1150 global $user;
1151
1152 $stats .= "<div class='buddylist-status'>";
1153 $stats .= "<div class='total'>" . l(format_plural($count, '@count buddy', '@count buddies'), 'buddylist') . "</div>";
1154 $stats .= "<div class='pending_received'>" . l(format_plural($received_count, '@count pending received request', '@count pending received requests'), 'buddylist/'. $user->uid .'/buddies/requests') . "</div>";
1155 $stats .= "<div class='pending_sent'>" . l(format_plural($sent_count, '@count pending sent request', '@count pending sent requests'), 'buddylist/'. $user->uid .'/buddies/requests') . "</div>";
1156 $stats .= "</div>";
1157
1158 return $stats;
1159 }
1160
1161 function buddylist_form_edit_groups_add_submit($form_id, $form_values) {
1162 global $user;
1163 $label_id = buddylist_buddygroup_new($user->uid, $form_values['add_group']);
1164 }
1165
1166 function buddylist_form_edit_groups_remove_submit($form_id, $form_values) {
1167 global $user;
1168 foreach ($form_values['groups'] as $label_id => $remove) {
1169 if ($remove > 0) {
1170 buddylist_buddygroup_remove($user->uid, $label_id);
1171 }
1172 }
1173 }
1174
1175 function buddylist_form_edit_groups_table_submit($form_id, $form_values) {
1176 $userid = $form_values['user'];
1177 foreach ($form_values['groups'] as $buddy => $groups) {
1178 foreach ($groups as $label_id => $checked) {
1179 if ($checked == 0) {
1180 buddylist_buddygroup_remove_buddy($userid, $buddy, $label_id);
1181 }
1182 else {
1183 buddylist_buddygroup_add_buddy($userid, $buddy, $label_id);
1184 }
1185 }
1186 }
1187
1188 drupal_set_message(t('@buddy groups saved.', buddylist_translation()));
1189 }
1190
1191 /**
1192 * Creates a new buddy group for a user
1193 *
1194 * @param $uid user id of the user to whom the group will belong.
1195 * @param $group string; name of the group
1196 * @param $visible determines whether the user's buddies can see which groups they've been put in.
1197 *
1198 * @return $label_id the existing or newly created id for the name of this group.
1199 */
1200 function buddylist_buddygroup_new($uid, $group, $visible = TRUE) {
1201 $label_id = db_result(db_query("SELECT label_id FROM {buddylist_groups} WHERE uid = %d AND label = '%s'", $uid, $group));
1202 if ($label_id === FALSE) {
1203 $new_label_id = db_next_id('buddygroup');
1204 db_query("INSERT INTO {buddylist_groups} VALUES (%d, %d, '%s', %d)", $uid, $new_label_id, $group, $visible);
1205 return $new_label_id;
1206 }
1207 else {
1208 return $label_id;
1209 }
1210 }
1211
1212 /**
1213 * Removes a buddy group for a user
1214 *
1215 * @param $uid user id of the user to whom the group belongs.
1216 * @param $label_id id of the group
1217 */
1218 function buddylist_buddygroup_remove($uid, $label_id) {
1219 db_query("DELETE FROM {buddylist_groups} WHERE uid = %d AND label_id = %d", $uid, $label_id);
1220 db_query("DELETE FROM {buddylist_buddy_group} WHERE uid = %d AND label_id = %d", $uid, $label_id);
1221 }
1222
1223 function buddylist_buddygroup_remove_buddy($uid, $buddy, $label_id) {
1224 db_query("DELETE FROM {buddylist_buddy_group} WHERE uid = %d AND buddy = %d AND label_id = %d", $uid, $buddy, $label_id);
1225 }
1226
1227 function buddylist_buddygroup_add_buddy($uid, $buddy, $label_id) {
1228 db_lock_table('buddylist_buddy_group');
1229 buddylist_buddygroup_remove_buddy($uid, $buddy, $label_id);
1230 db_query('INSERT INTO {buddylist_buddy_group} VALUES (%d, %d, %d)', $uid, $buddy, $label_id);
1231 db_unlock_tables();
1232 }
1233
1234 /**
1235 * Feed for buddies recent posts
1236 */
1237 function buddylist_buddyfeed($uid) {
1238 if (!(is_numeric($uid) && $uid > 0)) {
1239 return drupal_not_found();
1240 exit();
1241 }
1242
1243 $buddy_ids = array_keys(buddylist_get_buddies($uid));
1244
1245 // false query to be used if no posts from buddies are available (as in this user has no buddies).
1246 $result = db_query('SELECT nid FROM {node} WHERE 0');
1247 if (count($buddy_ids)) {
1248 $buddy_ids_str = '('. implode(',', $buddy_ids). ')';
1249 $result = db_query(db_rewrite_sql('SELECT nid FROM {node} WHERE status = 1 AND uid IN %s ORDER BY nid DESC'), $buddy_ids_str);
1250 }
1251 $channel['title'] = t('@buddies recent posts on %site', array('%site' => variable_get('site_name', 'drupal')) + buddylist_translation());
1252 $channel['link'] = url('buddylist/'. $uid .'/buddies/recent', NULL, NULL, TRUE);
1253
1254 node_feed($result, $channel);
1255 }
1256
1257 function buddylist_addbuddy($uid) {
1258 global $user;
1259 $buddy = user_load(array('uid' => $uid));
1260
1261 if (empty($buddy->name)) {
1262 drupal_set_message(t('This user does not exist'));
1263 }
1264 elseif (in_array($uid, array_keys(buddylist_get_buddies($user->uid)))) {
1265 drupal_set_message(t('This user is already on your @buddy list', buddylist_translation()));
1266 }
1267 elseif ($user->uid == $uid) {
1268 drupal_set_message(t('Cannot add yourself to @buddy list', buddylist_translation()));
1269 }
1270 else {
1271 $form['uid'] = array('#type' => 'hidden', '#value' => $uid);
1272 $form['name'] = array('#type' => 'hidden', '#value' => $buddy->name);
1273 $output = confirm_form(
1274 $form,
1275 t('Add user %name to your @buddy list?', array('%name' => $buddy->name) + buddylist_translation()),
1276 $_GET['destination'],
1277 '',
1278 t('Add'), t('Cancel'),
1279 'buddylist_addbuddy_confirm');
1280 return $output;
1281 }
1282 drupal_goto();
1283 }
1284 //function buddylist_form_alter($a, $b) {dprint_r($a); dprint_r($b);}
1285
1286 /**
1287 * Confirm and add a buddy.
1288 */
1289 function buddylist_addbuddy_submit($form_id, $form_values) {
1290 if (variable_get('buddylist_require_approval', 0)) {
1291 buddylist_add_request($form_values['uid']);
1292 }
1293 else {
1294 buddylist_add($form_values['uid']);
1295 drupal_set_message(t('%name will be be notified the next time s/he logs in.', array('%name' => $form_values['name'])));
1296 }
1297 return 'user';
1298 };
1299
1300 /**
1301 * Removes the user $uid from the global user's account.
1302 * TODO: generalize this so that two uids can be given
1303 */
1304 function buddylist_deletebuddy($uid) {
1305 global $user;
1306 $buddy = user_load(array('uid' => $uid));
1307
1308 if (empty($buddy->name)) {
1309 drupal_set_message('This user does not exist');
1310 }
1311 else if (!in_array($uid, array_keys(buddylist_get_buddies($user->uid)))) {
1312 drupal_set_message('This user is not on your @buddy list', buddylist_translation());
1313 }
1314 else {
1315 $form['uid'] = array('#type' => 'hidden', '#value' => $uid);
1316 $form['name'] = array('#type' => 'hidden', '#value' => $buddy->name);
1317 $output = confirm_form(
1318 $form,
1319 t('Remove user %name from your @buddy list?', array('%name' => $buddy->name) + buddylist_translation()),
1320 $_GET['destination'],
1321 '',
1322 t('Remove'), t('Cancel'),
1323 'buddylist_deletebuddy_confirm');
1324 return $output;
1325 }
1326 drupal_goto();
1327 }
1328
1329 /**
1330 * Confirm and add a buddy.
1331 */
1332 function buddylist_deletebuddy_submit($form_id, $form_values) {
1333 buddylist_remove($form_values['uid']);
1334 drupal_set_message(t('@name will be be notified of being removed.', array('@name' => $form_values['name'])));
1335 return 'user';
1336 };
1337
1338 function buddylist_add($id) {
1339 global $user;
1340 $user_to_add = user_load(array('uid' => $id));
1341
1342 if (!in_array($id, array_keys(buddylist_get_buddies($user->uid)))) {
1343 db_query('INSERT INTO {buddylist} (received, uid, buddy, timestamp) VALUES (1, %d, %d, %d)' , $user->uid , $id , time());
1344 // DB value buddylist.received set to 1, meaning buddy has a message waiting
1345 // letting them know you added them as a buddy
1346 // buddylist.received set back to 0 when user logs in along with being informed of new buddy
1347 if (variable_get('buddylist_send_add', FALSE)) {
1348 buddylist_mail_user('add', $user_to_add);
1349 }
1350 drupal_set_message(t('%username has been added to your @buddy list', array('%username' => $user_to_add->name) + buddylist_translation()));
1351 }
1352 else {
1353 drupal_set_message(t('%username is already on your @buddylist', array('%username' => $user_to_add->name) + buddylist_translation()));
1354 }
1355 }
1356
1357 function buddylist_add_request($id) {
1358 global $user;
1359 $user_to_add = user_load(array('uid' => $id));
1360
1361 $already_requested = in_array($id, array_keys(buddylist_get_requestees($user->uid)));
1362 $already_buddies = in_array($id, array_keys(buddylist_get_buddies($user->uid)));
1363
1364 if (!$already_requested && !$already_buddies) {
1365 db_query('INSERT INTO {buddylist_pending_requests} (requester_uid, requestee_uid, received) VALUES (%d, %d, %d)', $user->uid, $id, 0);
1366
1367 if (variable_get('buddylist_send_request', FALSE)) {
1368 buddylist_mail_user('request', $user_to_add);
1369 }
1370 drupal_set_message(t('Your request to add %username to your @buddy list has been submitted. %username will be notified.', array('%username' => $user_to_add->name) + buddylist_translation()));
1371 }
1372 else {
1373 if ($already_requested) {
1374 drupal_set_message(t('You have already requested to add %username to your @buddylist', array('%username' => $user_to_add->name) + buddylist_translation()));
1375 }
1376
1377 if ($already_buddies) {
1378 drupal_set_message(t('%username is already on your @buddylist', array('%username' => $user_to_add->name) + buddylist_translation()));
1379 }
1380 }
1381 }
1382
1383 function buddylist_remove($id) {
1384 global $user;
1385 db_query('DELETE FROM {buddylist} WHERE uid = %d AND buddy = %d' , $user->uid , $id);
1386 db_query('DELETE FROM {buddylist_buddy_group} WHERE uid = %d AND buddy = %d' , $user->uid , $id);
1387 $thisuser = user_load(array('uid' => $id));
1388 if (variable_get('buddylist_send_remove', FALSE)) {
1389 buddylist_mail_user('remove', $thisuser);
1390 }
1391 drupal_set_message(t('%username has been removed from your @buddylist', array('%username' => $thisuser->name) + buddylist_translation()));
1392
1393 if (variable_get('buddylist_require_approval', 0)) {
1394 db_query('DELETE FROM {buddylist} WHERE uid = %d AND buddy = %d', $id, $user->uid);
1395 db_query('DELETE FROM {buddylist_buddy_group} WHERE uid = %d AND buddy = %d', $id, $user->uid);
1396 }
1397 }
1398
1399 function buddylist_cancel_add($id) {
1400 $thisuser = user_load(array('uid' => $id));
1401 drupal_set_message(t('User %name was NOT added to your @buddylist.', array('%name' => $thisuser->name) + buddylist_translation()));
1402 }
1403
1404 function buddylist_cancel_remove($id) {
1405 $thisuser = user_load(array('uid' => $id));
1406 drupal_set_message(t('User %name was NOT removed from your @buddylist.', array('%name' => $thisuser->name) + buddylist_translation()));
1407 }
1408
1409 function theme_buddylist_online($online) {
1410 return $online ? t('yes') : t('no');
1411 }
1412
1413 /*
1414 * Sends mail to a buddy, which is added/removed/deleted/requested by $user
1415 */
1416 function buddylist_mail_user($op, $buddy, $user = NULL) {
1417
1418 if (variable_get('buddylist_user_mail', FALSE) && isset($buddy->buddylist_mail) && !$buddy->buddylist_mail) {
1419 return; //the user has turned mails off
1420 }
1421
1422 if (is_null($user)){
1423 global $user;
1424 }
1425 switch($op) {
1426 case 'add':
1427 $subject = BUDDYLIST_ADD_SUBJECT;
1428 $message = variable_get('buddylist_add_message', buddylist_mail_add_default());
1429 break;
1430 case 'remove':
1431 $subject = BUDDYLIST_REMOVE_SUBJECT;
1432 $message = variable_get('buddylist_remove_message', buddylist_mail_remove_default());
1433 break;
1434 case 'request':
1435 $subject = BUDDYLIST_REQUEST_SUBJECT;
1436 $message = variable_get('buddylist_request_message', buddylist_mail_request_default());
1437 break;
1438 case 'approval':
1439 $subject = BUDDYLIST_APPROVAL_SUBJECT;
1440 $message = variable_get('buddylist_approval_message', buddylist_mail_approval_default());
1441 break;
1442 }
1443
1444 $replacements = buddylist_translation() + (($op == 'approval') ? buddylist_approval_mail_replacements($user, $buddy) : buddylist_mail_replacements($buddy, $user));
1445 $subject = t($subject, $replacements);
1446 $message = t($message, $replacements);
1447
1448 $site_mail = variable_get('site_mail', "");
1449 if (!strlen($site_mail)) {
1450 if (user_access('administer site configuration')){
1451 drupal_set_message(t('You should create an !link for your site.', array('!link' => l(t('an administrator mail address'), 'admin/settings/site-information'))), 'warning');
1452 }
1453 $site_mail = 'nobody@localhost';
1454 }
1455
1456 // send the email
1457 if ($op != 'approval') {
1458 if (drupal_mail("buddylist_mail_user_$op", $buddy->mail, $subject, $message, $site_mail)) {
1459 $message = t('%type message was sent to %username', array('%type' => $op, '%username' => $buddy->name));
1460 watchdog('buddylist', $message);
1461 }
1462 else {
1463 $message = t('There was a problem sending the %type message to %username', array('%type' => $op, '%username' => $buddy->name));
1464 watchdog('buddylist', $message, WATCHDOG_WARNING);
1465 }
1466 }
1467 else {
1468 if (drupal_mail("buddylist_mail_user_$op", $buddy->mail, $subject, $message, $site_mail)) {
1469 $message = t('%type message was sent to %username', array('%type' => $op, '%username' => $buddy->name));
1470 watchdog('buddylist', $message);
1471 }
1472 else {
1473 $message = t('There was a problem sending the %type message to %username', array('%type' => $op, '%username' => $buddy->name));
1474 watchdog('buddylist', $message, WATCHDOG_WARNING);
1475 }
1476 }
1477 }
1478
1479 function buddylist_mail_add_default() {
1480 return <<<MESSAGE
1481 Hi @addee_name,
1482
1483 You are @adder_name's newest @buddy.
1484
1485 Here's a link to @adder_name's profile. If you'd like, you can add them as one of your @buddies:
1486
1487 @adder_link
1488
1489 Regards,
1490 The @site team
1491 MESSAGE;
1492 }
1493
1494 function buddylist_mail_remove_default() {
1495 return <<<MESSAGE
1496 Hi @addee_name,
1497
1498 You have been removed from @adder_name's @buddy list.
1499
1500 Here's a link to @adder_name's profile:
1501
1502 @adder_link
1503
1504 Enjoy your new freedom!
1505
1506 Regards,
1507 The @site team
1508 MESSAGE;
1509 }
1510
1511 function buddylist_mail_request_default() {
1512 return <<<MESSAGE
1513 Hi @addee_name,
1514
1515 @adder_name has requested to add you to his/her @buddy list.
1516
1517 Here's a link to @adder_name's profile:
1518
1519 @adder_link
1520
1521 To approve/deny this request, log in to @siteurl and see your pending @buddy requests
1522 at @pending_requests_link.
1523
1524 Enjoy your new freedom!
1525
1526 Regards,
1527 The @site team
1528 MESSAGE;
1529 }
1530
1531 function buddylist_mail_approval_default() {
1532 return <<<MESSAGE
1533 Hi @adder_name,
1534
1535 @addee_name has approved your request to join his/her @buddy list.
1536
1537 Here's a link to your buddylist:
1538
1539 @adder_list_link
1540
1541 Enjoy your new freedom!
1542
1543 Regards,
1544 The @site team
1545
1546 MESSAGE;
1547 }
1548
1549 function buddylist_mail_replacements(&$buddy, &$user){
1550 return array(
1551 '@adder_name' => $user->name,
1552 '@adder_link' => url("user/". $user->uid, NULL, NULL, TRUE),
1553 '@adder_uid' => $user->uid,
1554 '@addee_name' => $buddy->name,
1555 '@addee_link' => url("user/". $buddy->uid, NULL, NULL, TRUE),
1556 '@addee_uid' => $buddy->uid,
1557 '@site' => variable_get("site_name", "Drupal"),
1558 '@siteurl' => $GLOBALS["base_url"],
1559 '@adder_list_link' => url("buddylist/". $user->uid ."/buddies/list", NULL, NULL, TRUE),
1560 '@pending_requests_link' => url("buddylist/". $buddy->uid ."/buddies/requests", NULL, NULL, TRUE),
1561 );
1562 }
1563
1564
1565
1566 function buddylist_approval_mail_replacements(&$buddy, &$user) {
1567 return array(
1568 '@adder_name' => $user->name,
1569 '@adder_link' => url("user/". $user->uid, NULL, NULL, TRUE),
1570 '@adder_uid' => $user->uid,
1571 '@addee_name' => $buddy->name,
1572 '@addee_link' => url("user/". $buddy->uid, NULL, NULL, TRUE),
1573 '@addee_uid' => $buddy->uid,
1574 '@site' => variable_get("site_name", "Drupal"),
1575 '@siteurl' => $GLOBALS["base_url"],
1576 '@adder_list_link' => url("buddylist/". $user->uid ."/buddies/list", NULL, NULL, TRUE),
1577 );
1578 }
1579
1580 function buddylist_empty_text_default() {
1581 return <<<MESSAGE
1582 <p>You haven't made any @buddies, yet.</p>
1583
1584 <p>You can add a @buddy by visiting a user's profile page.</p>
1585 MESSAGE;
1586 }
1587