move code up one directory
[atutor.git] / mods / _standard / social / lib / friends.inc.php
1 <?php
2 /****************************************************************/
3 /* ATutor                                                                                                               */
4 /****************************************************************/
5 /* Copyright (c) 2002-2009                                                                              */
6 /* Inclusive Design Institute                                   */
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  * @param       int             the number of entries to skip over from the result set. 
268  * @return      array of friends of this member; id=>[first name, last name, profile picture]
269  *
270  * TODO: search needs work.  Order by the most matches to the least matches
271  */ 
272 function searchFriends($name, $searchMyFriends = false, $offset=-1){
273         global $db, $addslashes;
274         $result = array(); 
275         $my_friends = array();
276         $exact_match = false;
277
278         //break the names by space, then accumulate the query
279         if (preg_match("/^\\\\?\"(.*)\\\\?\"$/", $name, $matches)){
280                 $exact_match = true;
281                 $name = $matches[1];
282         }
283         $name = $addslashes($name);     
284         $sub_names = explode(' ', $name);
285         foreach($sub_names as $piece){
286                 if ($piece == ''){
287                         continue;
288                 }
289
290                 //if there are 2 double quotes around a search phrase, then search it as if it's "first_name last_name".
291                 //else, match any contact in the search phrase.
292                 if ($exact_match){
293                         $match_piece = "= '$piece' ";
294                 } else {
295                         $match_piece = "LIKE '%$piece%' ";
296                 }
297                 $query .= "(first_name $match_piece OR second_name $match_piece OR last_name $match_piece OR login $match_piece ) AND ";
298         }
299         //trim back the extra "AND "
300         $query = substr($query, 0, -4);
301
302         //Check if this is a search on all people
303         if ($searchMyFriends == true){
304                 //If searchMyFriend is true, return the "my friends" array
305                 //If the member_id is empty, (this happens when we are doing a search without logging in) then get all members?
306                 //else, use "my friends" array to distinguish which of these are already in my connection
307                 if(!isset($_SESSION['member_id'])){
308                         $sql = 'SELECT member_id FROM '.TABLE_PREFIX.'members WHERE ';
309                 } else {
310                         $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 ';
311                         $sql .= $query;
312                         $sql .= ' UNION ';
313                         $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 ';
314                 }
315                 $sql .= $query;
316
317                 $rs = mysql_query($sql, $db);
318                 if ($rs){
319                         while ($row = mysql_fetch_assoc($rs)){
320                                 if ($row['member_id']==$_SESSION['member_id']){
321                                         $this_id = $row['friend_id'];
322                                 } else {
323                                         $this_id = $row['member_id'];
324                                 }
325                                 $temp =& $my_friends[$this_id]; 
326                                 $temp['obj'] = new Member($this_id);
327                                 if ($searchMyFriends){
328                                         $temp['added'] = 1;
329                                 }
330                         }
331                 }
332                 unset($this_id);  //don't want the following statements to reuse this
333                 return $my_friends;
334         } else {
335                 /*
336                 * Harris' note:
337                 * IF the 'search my friend' is off, then it should search all members inside that table
338                 * don't know why i did the search inside [friends x members]
339                 * Also this query is gonna pull out all members cept 'myself'
340                 * raised a small problem for public use, cause there is no member_id
341                 * end note;
342                 */
343                 //$sql = 'SELECT * FROM '.TABLE_PREFIX.'social_friends F LEFT JOIN '.TABLE_PREFIX.'members M ON F.friend_id=M.member_id WHERE ';
344                 $sql = 'SELECT * FROM '.TABLE_PREFIX.'members M WHERE ';
345                 if (isset($_SESSION['member_id'])){
346                         $sql .= 'member_id!='.$_SESSION['member_id'].' AND ';
347                 }
348         }
349         $sql = $sql . $query;
350         if ($offset >= 0){
351                 $sql .= " LIMIT $offset, ". SOCIAL_FRIEND_SEARCH_MAX;
352         }
353         $rs = mysql_query($sql, $db);
354
355         //Get all members out
356         while($row = mysql_fetch_assoc($rs)){
357 //              if ($row['member_id']==$_SESSION['member_id']){
358 //                      $this_id = $row['friend_id'];
359 //              } else {
360                         $this_id = $row['member_id'];
361 //              }
362
363                 //skip empty entry, don't know why there would be empty entry. 
364                 //TODO: Trace this. could be a bug in query
365                 if ($this_id == ''){
366                         continue;
367                 }
368
369                 $temp =& $result[$this_id];     
370                 $temp['id'] = $this_id;
371 //              $temp['first_name'] = $row['first_name'];
372 //              $temp['last_name'] = $row['last_name'];
373
374                 //if this person exists in "my friends" list, mark it.
375                 if (isset($my_friends[$this_id])){
376                         $temp['added'] = 1;
377                 }
378         } 
379         return $result;
380 }
381
382
383 /**
384  * 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.
385  * @param       int             the user id
386  * @param       array   the given array of friends
387  * @return      marked array
388  */
389  function markFriends($id, $connections){
390         //get all friends
391         $my_friends = getFriends($id);
392         $pending_requests = getPendingRequests(true);
393
394         foreach($my_friends as $friends){
395                 //if it is in the connection, set the attribute
396                 if($connections[$friends] != null){
397                         $connections[$friends]['added'] = 1;
398                 } 
399         }
400
401         foreach ($pending_requests as $friends=>$garbage){
402                 //if it is already added, set pending =1
403                 if ($connections[$friends] != null){
404                         $connections[$friends]['pending'] = 1;
405                 }
406         }
407         return $connections;
408  }
409
410
411 /**
412  * Invite other members
413  * @param       int             The member that we are going to invite
414  * @param       int             The group id in which we are inviting the person to.
415  */
416  function addGroupInvitation($member_id, $group_id){
417          global $db;
418
419          $sql = 'INSERT INTO '.TABLE_PREFIX."social_groups_invitations (sender_id, group_id, member_id) VALUES ($_SESSION[member_id], $group_id, $member_id)";
420 //       echo $sql;
421          $result = mysql_query($sql, $db);
422          if($result){
423                  return true;
424          } 
425          return false;
426  }
427
428
429 /**
430  * Get invitation from "ME", which is the logged in person
431  * @return      list of groups id + sender_id
432  */
433  function getGroupInvitations(){
434         global $db;
435         $inv = array();
436
437         $sql = 'SELECT * FROM '.TABLE_PREFIX.'social_groups_invitations WHERE member_id='.$_SESSION['member_id'];
438
439         $result = mysql_query($sql, $db);
440         if ($result){
441                 while ($row = mysql_fetch_assoc($result)){
442                         $inv[$row['group_id']][] = $row['sender_id'];
443                 }
444         }
445
446         return $inv;
447  }
448
449
450  /** 
451   * Get group requests for "ME", which is the logged in person.
452   * @return     list of groups id + sender_id
453   */
454  function getGroupRequests(){
455          global $db;
456          $requests = array();
457
458          $sql = 'SELECT * FROM '.TABLE_PREFIX.'social_groups_requests WHERE member_id='.$_SESSION['member_id'];
459
460          $result = mysql_query($sql, $db);
461          if ($result){
462                 while ($row = mysql_fetch_assoc($result)){
463                         $requests[$row['group_id']][] = $row['sender_id'];
464                 }
465          }
466
467          return $requests;
468  }
469
470
471  /**
472   * Accept "my" group invitation
473   * @param      int             group id
474   * @param      int             sender's member_id
475   */
476 function acceptGroupInvitation($group_id){
477         global $db;
478         
479         //will only add member if the group_id is valid.
480         if ($group_id <= 0){
481                 return;
482         }
483
484         $sg = new SocialGroup($group_id);
485         $isSucceeded = $sg->addMember($_SESSION['member_id']);
486
487         if ($isSucceeded){
488                 removeGroupInvitation($group_id);
489         }
490 }
491
492
493  /**
494   * Reject "my" group invitation
495   */
496  function rejectGroupInvitation($group_id){
497          return removeGroupInvitation($group_id);
498  }
499
500
501
502  /**
503   * Remove "my" group invitation
504   * @param      int             group id
505   */
506  function removeGroupInvitation($group_id){
507         global $db;
508         $group_id = intval($group_id);
509
510         //delete invitation based on 3 primary keys
511 //      $sql = 'DELETE FROM '.TABLE_PREFIX."social_groups_invitations WHERE group_id=$group_id AND sender_id=$sender_id AND member_id=$member_id";
512         //doesn't need sender_id cause we want to remove all anyway.
513         $sql = 'DELETE FROM '.TABLE_PREFIX."social_groups_invitations WHERE group_id=$group_id AND member_id=$_SESSION[member_id]";
514         $result = mysql_query($sql, $db);
515         if ($result){
516                 return true;
517         }
518         return false;
519  }
520
521
522  /** 
523   * Accept the group request
524   * @param      int             group id
525   * @param      int             member that made this request
526   */
527  function acceptGroupRequest($group_id, $sender_id){
528         global $db;
529         
530         //will only add member if the group_id is valid.
531         if ($group_id <= 0){
532                 return;
533         }
534
535         $sg = new SocialGroup($group_id);
536         $isSucceeded = $sg->addMember($sender_id);
537
538         if ($isSucceeded){
539                 removeGroupRequest($group_id, $sender_id);
540         }
541  }
542
543
544  /**
545   * Reject the group request
546   * @param      int             group id
547   * @param  int         member that made this request
548   */
549  function rejectGroupRequest($group_id, $sender_id) {
550          return removeGroupRequest($group_id, $sender_id);
551  }
552
553
554
555  /** 
556   * Remove group requests
557   * @param      int             group id
558    * @param  int                member that made this request
559   */
560  function removeGroupRequest($group_id, $sender_id){
561          global $db;
562          $group_id = intval($group_id);
563          $sender_id = intval($sender_id);
564
565          $sql = 'DELETE FROM '.TABLE_PREFIX."social_groups_requests WHERE group_id=$group_id AND member_id=$_SESSION[member_id] AND sender_id=$sender_id";
566
567          $result = mysql_query($sql, $db);
568          if ($result){
569                  return true;
570          }
571          return false;
572  }
573
574
575 /** 
576   * Print social name, with AT_print and profile link 
577   * @param      int             member id
578   * @param      link    will return a hyperlink when set to true
579   * return      the name to be printed.
580   */
581 function printSocialName($id, $link=true){
582         $str .= AT_print(get_display_name($id), 'members.full_name');
583         if ($link) {
584                 return getProfileLink($id, $str);
585         } 
586         return $str;
587 }
588
589
590 /** 
591  * Mimic vital's print_profile_img function, but with a more customized image definition
592  * @param       int     the member id
593  * @param       1 for thumbnail, 2 for profile
594  * @param       true will return a href link to the profile page, false otherwise
595  * @return      the profile image link
596  */
597 function printSocialProfileImg($id, $type=1, $link=true) {
598         global $moduleFactory;
599         $str = '';
600         $username = htmlspecialchars(AT_print(get_display_name($id), 'members.full_name'), ENT_QUOTES, 'UTF-8');
601         $mod = $moduleFactory->getModule('_standard/profile_pictures');
602         if ($mod->isEnabled() === FALSE) {
603                 return;
604         }
605         if (profile_image_exists($id)) {
606                 if ($type==1){
607                         $str = '<img src="get_profile_img.php?id='.$id.'" alt="'.$username.'" />';
608                 } elseif ($type==2){
609                         $str = '<img src="get_profile_img.php?id='.$id.SEP.'size=p" alt="'.$username.'" />';
610                 }
611         } else {
612                 $str = '<img src="'.AT_SOCIAL_BASENAME.'images/nophoto.gif" alt="'.$username.'" />';
613         }
614         if (!$link){
615                 return $str;
616         }
617         return getProfileLink($id, $str);
618 }
619
620
621 /**
622  * Generate the a href link to the designated profile
623  * For now, it's to sprofile, but in the future, we want ATutor + Opensocial to have only 1 profile, which should
624  * point to the default atutor profile page.
625  *
626  * @private
627  * @param       int             member id
628  * @param       string  Image tag, or any string
629  * @return      the hyperlink to the profile
630  */
631 function getProfileLink($id, $str){
632         $link = '<a href="'.url_rewrite(AT_SOCIAL_BASENAME.'sprofile.php?id='.$id, AT_PRETTY_URL_IS_HEADER).'">';
633         $link .= $str;
634         $link .= '</a>';
635         return $link;
636 }
637
638 /**
639  * This function will return a list of the member's activities 
640  * @param       member_id       The id of the member we wish to get the activities from.
641  */
642 function getMemberActivities($member_id){
643 }
644
645 ?>