ad03183bd82dba2f1b8915d0300644eaaf9b2ba2
[atutor.git] / mods / social / lib / friends.inc.php
1 <?php
2 /****************************************************************/
3 /* ATutor                                                                                                               */
4 /****************************************************************/
5 /* Copyright (c) 2002-2009                                                                              */
6 /* Adaptive Technology Resource Centre / University of Toronto  */
7 /* http://atutor.ca                                                                                             */
8 /*                                                              */
9 /* This program is free software. You can redistribute it and/or*/
10 /* modify it under the terms of the GNU General Public License  */
11 /* as published by the Free Software Foundation.                                */
12 /****************************************************************/
13 // $Id$
14
15 define('AT_INCLUDE_PATH', '../../include/');
16 require_once(AT_SOCIAL_INCLUDE.'classes/Activity.class.php');
17 require_once(AT_SOCIAL_INCLUDE.'classes/Member.class.php');
18
19 /** 
20  * Get all the connections from the given member id
21  * $obj->url should retrieve the member's profile link.
22  *
23  * @param       int             the person who we want to get friends from
24  * @param       int             the max number of friends to be returned
25  *
26  * TODO: Need optimization, too slow.
27  */
28 function getFriends($member_id, $limit=0){
29         global $db, $addslashes;
30         $friends = array();
31         
32         //All member_id = member_id, and All friend_id = member_id
33         $sql = 'SELECT F.member_id AS member_id, F.friend_id AS friend_id FROM '.TABLE_PREFIX.'social_friends F LEFT JOIN '.TABLE_PREFIX.'members M ON F.friend_id=M.member_id WHERE (F.member_id='.$member_id.' OR F.friend_id='.$member_id.')';
34         if ($limit > 0){
35                 $sql .= ' ORDER BY RAND() LIMIT '.$limit;
36         }
37         $result = mysql_query($sql, $db);
38
39         if ($result){
40                 while ($row = mysql_fetch_assoc($result)){
41                         if ($row['member_id']==$member_id){
42                                 //member_id=member_id case
43                                 $friends[$row['friend_id']]                     =       $row['friend_id'];
44         //                      $friends[$row['member_id']]['first_name']       =       $row['first_name'];
45         //                      $friends[$row['member_id']]['last_name']        =       $row['last_name'];
46                         } else {
47                                 //friend_id = member_id
48                                 $friends[$row['member_id']]                     =       $row['member_id'];
49         //                      $friends[$row['friend_id']]['first_name']       =       $row['first_name'];
50         //                      $friends[$row['friend_id']]['last_name']        =       $row['last_name'];
51                         }
52                 }
53         }
54 /*
55         //All friend_id = member_id
56         $sql = 'SELECT F.member_id AS member_id, F.friend_id AS friend_id FROM '.TABLE_PREFIX.'social_friends F LEFT JOIN '.TABLE_PREFIX.'members M ON F.friend_id=M.member_id WHERE F.friend_id='.$member_id;
57         $result = mysql_query($sql, $db);
58         while ($row = mysql_fetch_assoc($result)){
59                 $friends[$row['member_id']]                     =       new Member($row['member_id']);
60 //              $friends[$row['friend_id']]['first_name']       =       $row['first_name'];
61 //              $friends[$row['friend_id']]['last_name']        =       $row['last_name'];
62         }
63 */
64         return $friends;
65 }
66
67
68 /**
69  * Decide rather these two people are strictly friend of friend.  If they are already friends, return false.
70  *
71  * @param       int             person A's member_id
72  * @param       int             person B's member_id
73  * @return      true if they are friend of friend.
74  */
75 function isFriendOfFriend($member_a, $member_b){
76         $member_a = intval($member_a);
77         $member_b = intval($member_b);
78         $friends_of_a = getFriends($member_a);
79         
80         //if these two are already friends
81         if(isset($friends_of_a[$member_b])){
82                 return false;
83         }
84         
85         $friends_of_b = getFriends($member_b);
86         $fof = array_intersect($friends_of_a, $friends_of_b);   //friends of friends
87
88         //If it is not empty or not null, then they have friends 
89         if (!empty($fof) > 0){
90                 return true;
91         }
92         return false;
93 }
94
95
96 /**
97  * Get a list of people you may know
98  */
99 function getPeopleYouMayKnow(){
100         global $db;
101         $counter = 0;
102         $people_you_may_know = array();
103         $pending_requests = getPendingRequests(true);
104
105         $sql = 'SELECT MAX(member_id) FROM '.TABLE_PREFIX.'members';
106         $result = mysql_query($sql, $db);
107         if ($result){
108                 list($max_id) = mysql_fetch_array($result);
109         } else {
110                 return null;
111         }
112         
113         //if we ran out of people, quit;
114         while($counter++ < $max_id){
115                 //if we get enough people we might know, quit; 
116                 if (sizeof($people_you_may_know) >= SOCIAL_NUMBER_OF_PEOPLE_YOU_MAY_KNOW){
117                         break;
118                 }
119                 //get new random member
120                 $random_member = rand(1, $max_id);      //seed is generated automatically since php 4.2.0
121
122                 //if this person is myself, next
123                 if ($random_member==$_SESSION['member_id']){
124                         continue;
125                 }
126
127                 //if this person is already on pending, next.
128                 if (isset($pending_requests[$random_member])){
129                         continue;
130                 }
131                 
132
133                 //if we have added this random number before, next.
134                 if (in_array($random_member, $people_you_may_know)){
135                         continue;
136                 }
137
138                 if (isFriendOfFriend($_SESSION['member_id'], $random_member)){
139                         $people_you_may_know[] = $random_member;
140                 }
141         }
142         return $people_you_may_know;
143 }
144
145
146 /**
147  * Returns a list of friend requests to me/by me depends on the flag
148  * @param       flag, true for requests made by me, false for requests made to me. DEFAULT: false
149  * @return      array of friend requests
150  */
151 function getPendingRequests($request_by_me=false){
152         global $db;
153         /* NOTE: This table is not bilinear, unlike the friends table.
154          * In this table, please do not be confused, member_id is the one who requests
155          * friend_id is the member that needs to approve/reject.  Thus, when we want to retrieve 
156          * pending requests, we need to pull entries from friend_id.
157          */     
158         $requests = array();
159
160         if ($request_by_me==true) {
161                 $sql = 'SELECT friend_id AS id FROM '.TABLE_PREFIX.'social_friend_requests WHERE member_id='.$_SESSION['member_id'];
162         } else {
163                 $sql = 'SELECT member_id AS id FROM '.TABLE_PREFIX.'social_friend_requests WHERE friend_id='.$_SESSION['member_id'];
164         }
165         $rs = mysql_query($sql, $db);
166
167         //myself=> pending objs
168         while($row = mysql_fetch_assoc($rs)){
169                 $requests[$row['id']] = new Member($row['id']);
170         }
171         return $requests;
172 }
173
174
175 /**
176  * This function adds a friend to the database, remove the equivalent friend request.
177  *
178  * @param       int             the member being approved, not "MYSELF"
179  */
180 function approveFriendRequest($friend_id){
181         global $db;
182         $friend_id = intval($friend_id);
183
184         if ($friend_id < 1){
185                 return;
186         }
187         //TODO: hardcoded relationship = 1
188         $sql = "INSERT INTO ".TABLE_PREFIX."social_friends SET member_id=$_SESSION[member_id], friend_id=$friend_id, relationship=1";
189         $is_succeeded = mysql_query($sql, $db); 
190         //remove the equivalent friend request
191         if ($is_succeeded){
192                 $is_succeeded = removeFriendRequest($friend_id, $_SESSION['member_id']);
193         }
194
195         //add to activities log
196         if ($is_succeeded){
197                 $act = new Activity();          
198                 $str1 = _AT('now_friends1', printSocialName($friend_id)); 
199                 $act->addActivity($_SESSION['member_id'], $str1);
200                 $str2 = _AT('now_friends2', printSocialName($_SESSION['member_id'])); 
201                 $act->addActivity($friend_id, $str2);
202                 unset($act);
203         }
204 }
205
206
207 /**
208  * Reject friend request
209  * 
210  * @param       int             the member being rejected, not "MYSELF"
211  */
212 function rejectFriendRequest($friend_id){
213         global $db;
214         return removeFriendRequest($friend_id, $_SESSION['member_id']);
215 }
216
217
218 /**
219  * Remove Friend request
220  * @param       member_id       the one who make this request
221  * @param       friend_id       the member that decide approval/reject on this request
222  */
223 function removeFriendRequest($member_id, $friend_id){
224         global $db;
225         $sql = 'DELETE FROM '.TABLE_PREFIX."social_friend_requests WHERE member_id=$member_id AND friend_id=$friend_id";
226         $is_succeeded = mysql_query($sql, $db);
227         return $is_succeeded;
228 }
229
230
231 /**
232   * This function adds a friend request to the database
233   *
234   * @param      friend_id       the member_id of the friend
235   */
236 function addFriendRequest($friend_id){
237         global $db;
238         $friend_id = intval($friend_id);
239
240         if ($friend_id < 1){
241          return;
242         }
243
244         $sql = "INSERT INTO ".TABLE_PREFIX."social_friend_requests SET member_id=$_SESSION[member_id], friend_id=$friend_id";
245         mysql_query($sql, $db);         
246  }
247  
248
249 /**
250  * This function removes a friend from the the user.
251  *
252  * @param       int             user id
253  */
254 function removeFriend($friend_id){
255         global $db;
256         $friend_id = intval($friend_id);
257
258         $sql = 'DELETE FROM '.TABLE_PREFIX.'social_friends WHERE (member_id='.$_SESSION['member_id'].' AND '.'friend_id='.$friend_id.') OR (friend_id='.$_SESSION['member_id'].' AND '.'member_id='.$friend_id.')';
259         mysql_query($sql, $db);
260 }
261
262
263 /**
264  * This function will return a list of people from the network with the given name.  
265  * @param       string  to be searched in the members table, can have space.
266  * @param       [OPTIONAL] boolean      if true, will search only within this member.
267  * @return      array of friends of this member; id=>[first name, last name, profile picture]
268  *
269  * TODO: search needs work.  Order by the most matches to the least matches
270  */ 
271 function searchFriends($name, $searchMyFriends = false, $offset=-1){
272         global $db, $addslashes;
273         $result = array(); 
274         $my_friends = array();
275         $exact_match = false;
276
277         //break the names by space, then accumulate the query
278         if (preg_match("/^\\\\?\"(.*)\\\\?\"$/", $name, $matches)){
279                 $exact_match = true;
280                 $name = $matches[1];
281         }
282         $name = $addslashes($name);     
283         $sub_names = explode(' ', $name);
284         foreach($sub_names as $piece){
285                 if ($piece == ''){
286                         continue;
287                 }
288
289                 //if there are 2 double quotes around a search phrase, then search it as if it's "first_name last_name".
290                 //else, match any contact in the search phrase.
291                 if ($exact_match){
292                         $match_piece = "= '$piece' ";
293                 } else {
294                         $match_piece = "LIKE '%$piece%' ";
295                 }
296                 $query .= "(first_name $match_piece OR second_name $match_piece OR last_name $match_piece OR email LIKE '$piece') AND ";
297         }
298         //trim back the extra "AND "
299         $query = substr($query, 0, -4);
300
301         //Check if this is a search on all people
302         if ($searchMyFriends == true){
303                 //If searchMyFriend is true, return the "my friends" array
304                 //If the member_id is empty, (this happens when we are doing a search without logging in) then get all members?
305                 //else, use "my friends" array to distinguish which of these are already in my connection
306                 if(!isset($_SESSION['member_id'])){
307                         $sql = 'SELECT member_id FROM '.TABLE_PREFIX.'members WHERE ';
308                 } else {
309                         $sql = 'SELECT F.* FROM '.TABLE_PREFIX.'social_friends F LEFT JOIN '.TABLE_PREFIX.'members M ON F.friend_id=M.member_id WHERE (F.member_id='.$_SESSION['member_id'].') AND ';
310                         $sql .= $query;
311                         $sql .= ' UNION ';
312                         $sql .= 'SELECT F.* FROM '.TABLE_PREFIX.'social_friends F LEFT JOIN '.TABLE_PREFIX.'members M ON F.member_id=M.member_id WHERE (F.friend_id='.$_SESSION['member_id'].') AND ';
313                 }
314                 $sql .= $query;
315
316                 $rs = mysql_query($sql, $db);
317                 if ($rs){
318                         while ($row = mysql_fetch_assoc($rs)){
319                                 if ($row['member_id']==$_SESSION['member_id']){
320                                         $this_id = $row['friend_id'];
321                                 } else {
322                                         $this_id = $row['member_id'];
323                                 }
324                                 $temp =& $my_friends[$this_id]; 
325                                 $temp['obj'] = new Member($this_id);
326                                 if ($searchMyFriends){
327                                         $temp['added'] = 1;
328                                 }
329                         }
330                 }
331                 unset($this_id);  //don't want the following statements to reuse this
332                 return $my_friends;
333         } else {
334                 /*
335                 * Harris' note:
336                 * IF the 'search my friend' is off, then it should search all members inside that table
337                 * don't know why i did the search inside [friends x members]
338                 * Also this query is gonna pull out all members cept 'myself'
339                 * raised a small problem for public use, cause there is no member_id
340                 * end note;
341                 */
342                 //$sql = 'SELECT * FROM '.TABLE_PREFIX.'social_friends F LEFT JOIN '.TABLE_PREFIX.'members M ON F.friend_id=M.member_id WHERE ';
343                 $sql = 'SELECT * FROM '.TABLE_PREFIX.'members M WHERE ';
344                 if (isset($_SESSION['member_id'])){
345                         $sql .= 'member_id!='.$_SESSION['member_id'].' AND ';
346                 }
347         }
348         $sql = $sql . $query;
349         if ($offset >= 0){
350                 $sql .= " LIMIT $offset, ". SOCIAL_FRIEND_SEARCH_MAX;
351         }
352         $rs = mysql_query($sql, $db);
353
354         //Get all members out
355         while($row = mysql_fetch_assoc($rs)){
356 //              if ($row['member_id']==$_SESSION['member_id']){
357 //                      $this_id = $row['friend_id'];
358 //              } else {
359                         $this_id = $row['member_id'];
360 //              }
361
362                 //skip empty entry, don't know why there would be empty entry. 
363                 //TODO: Trace this. could be a bug in query
364                 if ($this_id == ''){
365                         continue;
366                 }
367
368                 $temp =& $result[$this_id];     
369                 $temp['id'] = $this_id;
370 //              $temp['first_name'] = $row['first_name'];
371 //              $temp['last_name'] = $row['last_name'];
372
373                 //if this person exists in "my friends" list, mark it.
374                 if (isset($my_friends[$this_id])){
375                         $temp['added'] = 1;
376                 }
377         } 
378         return $result;
379 }
380
381
382 /**
383  * Given an array list of friends, this function will add an attribute 'added' into the array if this person is already connected to the user.
384  * @param       int             the user id
385  * @param       array   the given array of friends
386  * @return      marked array
387  */
388  function markFriends($id, $connections){
389         //get all friends
390         $my_friends = getFriends($id);
391         $pending_requests = getPendingRequests(true);
392
393         foreach($my_friends as $friends){
394                 //if it is in the connection, set the attribute
395                 if($connections[$friends] != null){
396                         $connections[$friends]['added'] = 1;
397                 } 
398         }
399
400         foreach ($pending_requests as $friends=>$garbage){
401                 //if it is already added, set pending =1
402                 if ($connections[$friends] != null){
403                         $connections[$friends]['pending'] = 1;
404                 }
405         }
406         return $connections;
407  }
408
409
410 /**
411  * Invite other members
412  * @param       int             The member that we are going to invite
413  * @param       int             The group id in which we are inviting the person to.
414  */
415  function addGroupInvitation($member_id, $group_id){
416          global $db;
417
418          $sql = 'INSERT INTO '.TABLE_PREFIX."social_groups_invitations (sender_id, group_id, member_id) VALUES ($_SESSION[member_id], $group_id, $member_id)";
419 //       echo $sql;
420          $result = mysql_query($sql, $db);
421          if($result){
422                  return true;
423          } 
424          return false;
425  }
426
427
428 /**
429  * Get invitation from "ME", which is the logged in person
430  * @return      list of groups id + sender_id
431  */
432  function getGroupInvitations(){
433         global $db;
434         $inv = array();
435
436         $sql = 'SELECT * FROM '.TABLE_PREFIX.'social_groups_invitations WHERE member_id='.$_SESSION['member_id'];
437
438         $result = mysql_query($sql, $db);
439         if ($result){
440                 while ($row = mysql_fetch_assoc($result)){
441                         $inv[$row['group_id']][] = $row['sender_id'];
442                 }
443         }
444
445         return $inv;
446  }
447
448
449  /** 
450   * Get group requests for "ME", which is the logged in person.
451   * @return     list of groups id + sender_id
452   */
453  function getGroupRequests(){
454          global $db;
455          $requests = array();
456
457          $sql = 'SELECT * FROM '.TABLE_PREFIX.'social_groups_requests WHERE member_id='.$_SESSION['member_id'];
458
459          $result = mysql_query($sql, $db);
460          if ($result){
461                 while ($row = mysql_fetch_assoc($result)){
462                         $requests[$row['group_id']][] = $row['sender_id'];
463                 }
464          }
465
466          return $requests;
467  }
468
469
470  /**
471   * Accept "my" group invitation
472   * @param      int             group id
473   * @param      int             sender's member_id
474   */
475 function acceptGroupInvitation($group_id){
476         global $db;
477         
478         //will only add member if the group_id is valid.
479         if ($group_id <= 0){
480                 return;
481         }
482
483         $sg = new SocialGroup($group_id);
484         $isSucceeded = $sg->addMember($_SESSION['member_id']);
485
486         if ($isSucceeded){
487                 removeGroupInvitation($group_id);
488         }
489 }
490
491
492  /**
493   * Reject "my" group invitation
494   */
495  function rejectGroupInvitation($group_id){
496          return removeGroupInvitation($group_id);
497  }
498
499
500
501  /**
502   * Remove "my" group invitation
503   * @param      int             group id
504   */
505  function removeGroupInvitation($group_id){
506         global $db;
507         $group_id = intval($group_id);
508
509         //delete invitation based on 3 primary keys
510 //      $sql = 'DELETE FROM '.TABLE_PREFIX."social_groups_invitations WHERE group_id=$group_id AND sender_id=$sender_id AND member_id=$member_id";
511         //doesn't need sender_id cause we want to remove all anyway.
512         $sql = 'DELETE FROM '.TABLE_PREFIX."social_groups_invitations WHERE group_id=$group_id AND member_id=$_SESSION[member_id]";
513         $result = mysql_query($sql, $db);
514         if ($result){
515                 return true;
516         }
517         return false;
518  }
519
520
521  /** 
522   * Accept the group request
523   * @param      int             group id
524   * @param      int             member that made this request
525   */
526  function acceptGroupRequest($group_id, $sender_id){
527         global $db;
528         
529         //will only add member if the group_id is valid.
530         if ($group_id <= 0){
531                 return;
532         }
533
534         $sg = new SocialGroup($group_id);
535         $isSucceeded = $sg->addMember($sender_id);
536
537         if ($isSucceeded){
538                 removeGroupRequest($group_id, $sender_id);
539         }
540  }
541
542
543  /**
544   * Reject the group request
545   * @param      int             group id
546   * @param  int         member that made this request
547   */
548  function rejectGroupRequest($group_id, $sender_id) {
549          return removeGroupRequest($group_id, $sender_id);
550  }
551
552
553
554  /** 
555   * Remove group requests
556   * @param      int             group id
557    * @param  int                member that made this request
558   */
559  function removeGroupRequest($group_id, $sender_id){
560          global $db;
561          $group_id = intval($group_id);
562          $sender_id = intval($sender_id);
563
564          $sql = 'DELETE FROM '.TABLE_PREFIX."social_groups_requests WHERE group_id=$group_id AND member_id=$_SESSION[member_id] AND sender_id=$sender_id";
565
566          $result = mysql_query($sql, $db);
567          if ($result){
568                  return true;
569          }
570          return false;
571  }
572
573
574 /** 
575   * Print social name, with AT_print and profile link 
576   * @param      int             member id
577   * @param      link    will return a hyperlink when set to true
578   * return      the name to be printed.
579   */
580 function printSocialName($id, $link=true){
581         $str .= AT_print(get_display_name($id), 'members.full_name');
582         if ($link) {
583                 return getProfileLink($id, $str);
584         } 
585         return $str;
586 }
587
588
589 /** 
590  * Mimic vital's print_profile_img function, but with a more customized image definition
591  * @param       int     the member id
592  * @param       1 for thumbnail, 2 for profile
593  * @param       true will return a href link to the profile page, false otherwise
594  * @return      the profile image link
595  */
596 function printSocialProfileImg($id, $type=1, $link=true) {
597         global $moduleFactory;
598         $str = '';
599         $mod = $moduleFactory->getModule('_standard/profile_pictures');
600         if ($mod->isEnabled() === FALSE) {
601                 return;
602         }
603         if (profile_image_exists($id)) {
604                 if ($type==1){
605                         $str = '<img src="get_profile_img.php?id='.$id.'" alt="" />';
606                 } elseif ($type==2){
607                         $str = '<img src="get_profile_img.php?id='.$id.SEP.'size=p" alt="" />';
608                 }
609         } else {
610                 $str = '<img src="'.AT_SOCIAL_BASENAME.'images/nophoto.gif" alt="" />';
611         }
612         if (!$link){
613                 return $str;
614         }
615         return getProfileLink($id, $str);
616 }
617
618
619 /**
620  * Generate the a href link to the designated profile
621  * For now, it's to sprofile, but in the future, we want ATutor + Opensocial to have only 1 profile, which should
622  * point to the default atutor profile page.
623  *
624  * @private
625  * @param       int             member id
626  * @param       string  Image tag, or any string
627  * @return      the hyperlink to the profile
628  */
629 function getProfileLink($id, $str){
630         $link = '<a href="'.url_rewrite(AT_SOCIAL_BASENAME.'sprofile.php?id='.$id).'">';
631         $link .= $str;
632         $link .= '</a>';
633         return $link;
634 }
635
636 /**
637  * Convert all input to htmlentities output, in UTF-8.
638  * @param       string  input to be convert
639  * @param       boolean true if we wish to change all carrier returns to a <br/> tag, false otherwise.
640  */
641 function htmlentities_utf8($str, $use_nl2br=true){
642         $return = htmlentities($str, ENT_QUOTES, 'UTF-8');
643         if ($use_nl2br){
644                 return nl2br($return);
645         } 
646         return $return;
647 }
648
649 /**
650  * This function will return a list of the member's activities 
651  * @param       member_id       The id of the member we wish to get the activities from.
652  */
653 function getMemberActivities($member_id){
654 }
655
656 ?>