ILIAS  release_5-2 Revision v5.2.25-18-g3f80b828510
class.ilChatroom.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (c) 1998-2009 ILIAS open source, Extended GPL, see docs/LICENSE */
3 
11 {
12  private static $settingsTable = 'chatroom_settings';
13  private static $historyTable = 'chatroom_history';
14  private static $userTable = 'chatroom_users';
15  private static $sessionTable = 'chatroom_sessions';
16  private static $banTable = 'chatroom_bans';
17  private static $privateRoomsTable = 'chatroom_prooms';
18  private static $privateSessionsTable = 'chatroom_psessions';
19  private static $uploadTable = 'chatroom_uploads';
20  private static $privateRoomsAccessTable = 'chatroom_proomaccess';
21  private $settings = array();
29  'object_id' => 'integer',
30  'allow_anonymous' => 'boolean',
31  'allow_custom_usernames' => 'boolean',
32  'enable_history' => 'boolean',
33  'restrict_history' => 'boolean',
34  'autogen_usernames' => 'string',
35  'room_type' => 'string',
36  'allow_private_rooms' => 'integer',
37  'display_past_msgs' => 'integer',
38  'private_rooms_enabled' => 'boolean'
39  );
40  private $roomId;
41 
42  private $object;
43 
50  public static function checkUserPermissions($permissions, $ref_id, $send_info = true)
51  {
52  global $rbacsystem, $lng;
53 
54  if(!is_array($permissions))
55  {
56  $permissions = array($permissions);
57  }
58 
59  foreach($permissions as $permission)
60  {
61  if(!$rbacsystem->checkAccess($permission, $ref_id))
62  {
63  if($send_info)
64  {
65  ilUtil::sendFailure($lng->txt("permission_denied"), true);
66  }
67  return false;
68  }
69  }
70 
71  return true;
72  }
73 
84  public static function checkPermissionsOfUser($usr_id, $permissions, $ref_id)
85  {
86  global $rbacsystem, $lng;
87 
88  if(!is_array($permissions))
89  {
90  $permissions = array($permissions);
91  }
92 
93  foreach($permissions as $permission)
94  {
95  if(!$rbacsystem->checkAccessOfUser($usr_id, $permission, $ref_id))
96  {
97  return false;
98  }
99  }
100 
101  return true;
102  }
103 
110  public static function byObjectId($object_id)
111  {
112  global $ilDB;
113  $query = 'SELECT * FROM ' . self::$settingsTable . ' WHERE object_id = %s';
114  $types = array('integer');
115  $values = array($object_id);
116  $rset = $ilDB->queryF($query, $types, $values);
117 
118  if($row = $ilDB->fetchAssoc($rset))
119  {
120  $room = new self();
121  $room->initialize($row);
122  return $room;
123  }
124  }
125 
131  public function initialize(array $rowdata)
132  {
133  $this->roomId = $rowdata['room_id'];
134 
135  foreach($this->availableSettings as $setting => $type)
136  {
137  if(isset($rowdata[$setting]))
138  {
139  settype($rowdata[$setting], $this->availableSettings[$setting]);
140  $this->setSetting($setting, $rowdata[$setting]);
141  }
142  }
143  }
144 
150  public function setSetting($name, $value)
151  {
152  $this->settings[$name] = $value;
153  }
154 
161  public static function byRoomId($room_id, $initObject = false)
162  {
163  global $ilDB;
164 
165  $query = 'SELECT * FROM ' . self::$settingsTable . ' WHERE room_id = %s';
166 
167  $types = array('integer');
168  $values = array($room_id);
169 
170  $rset = $ilDB->queryF($query, $types, $values);
171 
172  if($row = $ilDB->fetchAssoc($rset))
173  {
174  $room = new self();
175  $room->initialize($row);
176 
177  if($initObject)
178  {
179  $room->object = ilObjectFactory::getInstanceByObjId($row['object_id']);
180  }
181 
182  return $room;
183  }
184  }
185 
190  public static function disconnectAllUsersFromAllRooms()
191  {
192  global $ilDB;
193 
194  $ilDB->manipulate('DELETE FROM ' . self::$userTable);
195  $ilDB->manipulate('UPDATE ' . self::$privateRoomsTable . ' SET closed = ' . $ilDB->quote(time(), 'integer') . ' WHERE closed = 0 OR closed IS NULL');
196  $ilDB->manipulate('UPDATE ' . self::$privateSessionsTable . ' SET disconnected = ' . $ilDB->quote(time(), 'integer') . ' WHERE disconnected = 0');
200  }
201 
202  public static function findDeletablePrivateRooms()
203  {
204  global $ilDB;
205 
206  $query = '
207  SELECT private_rooms.proom_id id, MIN(disconnected) min_disconnected, MAX(disconnected) max_disconnected
208  FROM ' . self::$privateSessionsTable . ' private_sessions
209  INNER JOIN ' . self::$privateRoomsTable . ' private_rooms
210  ON private_sessions.proom_id = private_rooms.proom_id
211  WHERE closed = 0
212  GROUP BY private_rooms.proom_id
213  HAVING MIN(disconnected) > 0 AND MAX(disconnected) < %s';
214  $rset = $ilDB->queryF(
215  $query,
216  array('integer'),
217  array(time() + 60 * 5)
218  );
219 
220  $rooms = array();
221 
222  while($row = $ilDB->fetchAssoc($rset))
223  {
224  $rooms[$row['id']] = $row['id'];
225  }
226 
227  $query = 'SELECT DISTINCT proom_id, room_id, object_id FROM ' . self::$privateRoomsTable
228  . ' INNER JOIN ' . self::$settingsTable . ' ON parent_id = room_id '
229  . ' WHERE ' . $ilDB->in('proom_id', $rooms, false, 'integer');
230 
231  $rset = $ilDB->query($query);
232  $rooms = array();
233  while($row = $ilDB->fetchAssoc($rset))
234  {
235  $rooms[] = array(
236  'proom_id' => $row['proom_id'],
237  'room_id' => $row['room_id'],
238  'object_id' => $row['object_id']
239  );
240  }
241 
242  return $rooms;
243  }
244 
245  public static function getUntrashedChatReferences($filter = array())
246  {
250  global $ilDB;
251 
252  // Check for parent because of an invalid parent node for the old public chat (thx @ jposselt ;-)).
253  // We cannot find this old public chat and clean this automatically
254  $query = '
255  SELECT od.obj_id, od.title, ore.ref_id, od.type, odp.title parent_title
256  FROM object_data od
257  INNER JOIN object_reference ore ON ore.obj_id = od.obj_id
258  INNER JOIN tree t ON t.child = ore.ref_id
259  INNER JOIN tree p ON p.child = t.parent
260  INNER JOIN object_reference orep ON orep.ref_id = p.child
261  INNER JOIN object_data odp ON odp.obj_id = orep.obj_id
262  INNER JOIN object_reference pre ON pre.ref_id = t.parent
263  INNER JOIN object_data pod ON pod.obj_id = pre.obj_id
264  ';
265 
266  if(isset($filter['last_activity']))
267  {
268  $threshold = $ilDB->quote($filter['last_activity'], 'integer');
269  $query .= "
270  INNER JOIN chatroom_settings ON chatroom_settings.object_id = od.obj_id
271  INNER JOIN chatroom_history ON chatroom_history.room_id = chatroom_settings.room_id AND chatroom_history.timestamp > $threshold
272  ";
273  }
274 
275  $query .= '
276  WHERE od.type = %s AND t.tree > 0 AND ore.deleted IS NULL
277  GROUP BY od.obj_id, od.title, ore.ref_id, od.type, odp.title
278  ORDER BY od.title
279  ';
280  $res = $ilDB->queryF($query, array('text'), array('chtr'));
281 
282  $chats = array();
283  while($row = $ilDB->fetchAssoc($res))
284  {
285  $chats[] = $row;
286  }
287 
288  return $chats;
289  }
290 
291  public function getDescription()
292  {
293  if(!$this->object)
294  {
295  $this->object = ilObjectFactory::getInstanceByObjId($this->getSetting('object_id'));
296  }
297 
298  return $this->object->getDescription();
299  }
300 
306  public function getSetting($name)
307  {
308  return $this->settings[$name];
309  }
310 
314  public function save()
315  {
316  $this->saveSettings($this->settings);
317  }
318 
324  public function saveSettings(array $settings)
325  {
326  global $ilDB;
327 
328  $localSettings = array();
329 
330  foreach($this->availableSettings as $setting => $type)
331  {
332  if(isset($settings[$setting]))
333  {
334  if($type == 'boolean')
335  {
336  $settings[$setting] = (boolean)$settings[$setting];
337  }
338  $localSettings[$setting] = array($this->phpTypeToMDBType($type), $settings[$setting]);
339  }
340  }
341 
342  if(!$localSettings['room_type'][1])
343  {
344  $localSettings['room_type'][1] = 'repository';
345  }
346 
347  if($this->roomId)
348  {
349  $ilDB->update(
350  self::$settingsTable,
351  $localSettings,
352  array('room_id' => array('integer', $this->roomId))
353  );
354  }
355  else
356  {
357  $this->roomId = $ilDB->nextId(self::$settingsTable);
358 
359  $localSettings['room_id'] = array(
360  $this->availableSettings['room_id'], $this->roomId
361  );
362 
363  $ilDB->insert(self::$settingsTable, $localSettings);
364  }
365  }
366 
367  private function phpTypeToMDBType($type)
368  {
369  switch($type)
370  {
371  case 'string':
372  return 'text';
373  default:
374  return $type;
375  }
376 
377  }
378 
387  public function addHistoryEntry($message, $recipient = null, $publicMessage = true)
388  {
389  global $ilDB;
390 
391  $subRoom = 0;
392  if(is_array($message))
393  {
394  $subRoom = (int)$message['sub'];
395  }
396  else if(is_object($message))
397  {
398  $subRoom = (int)$message->sub;
399  }
400 
401  $id = $ilDB->nextId(self::$historyTable);
402  $ilDB->insert(
403  self::$historyTable,
404  array(
405  'hist_id' => array('integer', $id),
406  'room_id' => array('integer', $this->roomId),
407  'sub_room' => array('integer', $subRoom),
408  'message' => array('text', json_encode($message)),
409  'timestamp' => array('integer', time()),
410  )
411  );
412  }
413 
424  public function connectUser(ilChatroomUser $user)
425  {
429  global $ilDB;
430 
431  $userdata = array(
432  'login' => $user->getUsername(),
433  'id' => $user->getUserId()
434  );
435 
436  $query = 'SELECT user_id FROM ' . self::$userTable . ' WHERE room_id = %s AND user_id = %s';
437  $types = array('integer', 'integer');
438  $values = array($this->roomId, $user->getUserId());
439 
440  if(!$ilDB->fetchAssoc($ilDB->queryF($query, $types, $values)))
441  {
442  // Notice: Using replace instead of insert looks strange, because we actually know whether the selected data exists or not
443  // But we occasionally found some duplicate key errors although the data set should not exist when the following code is reached
444  $ilDB->replace(
445  self::$userTable,
446  array(
447  'room_id' => array('integer', $this->roomId),
448  'user_id' => array('integer', $user->getUserId())
449  ),
450  array(
451  'userdata' => array('text', json_encode($userdata)),
452  'connected' => array('integer', time()),
453  )
454  );
455 
456  return true;
457  }
458 
459  return false;
460  }
461 
469  public function getConnectedUsers()
470  {
471  global $ilDB;
472 
473  $query = 'SELECT userdata FROM ' . self::$userTable . ' WHERE room_id = %s';
474  $types = array('integer');
475  $values = array($this->roomId);
476  $rset = $ilDB->queryF($query, $types, $values);
477  $users = array();
478 
479  while($row = $ilDB->fetchAssoc($rset))
480  {
481  $users[] = json_decode($row['userdata']);
482  }
483 
484  return $users;
485  }
486 
492  public function disconnectUser($user_id)
493  {
494  $this->disconnectUsers(array($user_id));
495  }
496 
504  public function disconnectUsers(array $userIds)
505  {
506  global $ilDB;
507 
508  $query = 'SELECT * FROM ' . self::$userTable . ' WHERE room_id = %s AND ' .
509  $ilDB->in('user_id', $userIds, false, 'integer');
510 
511  $types = array('integer');
512  $values = array($this->roomId);
513  $rset = $ilDB->queryF($query, $types, $values);
514 
515  if($row = $ilDB->fetchAssoc($rset))
516  {
517  $query = 'SELECT proom_id FROM ' . self::$privateRoomsTable . ' WHERE parent_id = %s';
518  $rset_prooms = $ilDB->queryF($query, array('integer'), array($this->roomId));
519 
520  $prooms = array();
521 
522  while($row_prooms = $ilDB->fetchAssoc($rset_prooms))
523  {
524  $prooms[] = $row_prooms['proom_id'];
525  }
526 
527  if(true || $this->getSetting('enable_history'))
528  {
529  $query = 'UPDATE ' . self::$privateSessionsTable . ' SET disconnected = %s WHERE ' . $ilDB->in('user_id', $userIds, false, 'integer') . ' AND ' . $ilDB->in('proom_id', $prooms, false, 'integer');
530  $ilDB->manipulateF($query, array('integer'), array(time()));
531  }
532  else
533  {
534  $query = 'DELETE FROM ' . self::$privateSessionsTable . ' WHERE ' . $ilDB->in('user_id', $userIds, false, 'integer') . ' AND ' . $ilDB->in('proom_id', $prooms, false, 'integer');
535  $ilDB->manipulate($query);
536  }
537 
538  $query = 'DELETE FROM ' . self::$userTable . ' WHERE room_id = %s AND ' .
539  $ilDB->in('user_id', $userIds, false, 'integer');
540 
541  $types = array('integer');
542  $values = array($this->roomId);
543  $ilDB->manipulateF($query, $types, $values);
544 
545  do
546  {
547  if($this->getSetting('enable_history'))
548  {
549  $id = $ilDB->nextId(self::$sessionTable);
550  $ilDB->insert(
551  self::$sessionTable,
552  array(
553  'sess_id' => array('integer', $id),
554  'room_id' => array('integer', $this->roomId),
555  'user_id' => array('integer', $row['user_id']),
556  'userdata' => array('text', $row['userdata']),
557  'connected' => array('integer', $row['connected']),
558  'disconnected' => array('integer', time())
559  )
560  );
561  }
562  }
563  while($row = $ilDB->fetchAssoc($rset));
564  }
565 
566  }
567 
572  public function getSettings()
573  {
574  return $this->settings;
575  }
576 
584  public function isSubscribed($chat_userid)
585  {
586  global $ilDB;
587 
588  $query = 'SELECT count(user_id) as cnt FROM ' . self::$userTable .
589  ' WHERE room_id = %s AND user_id = %s';
590 
591  $types = array('integer', 'integer');
592  $values = array($this->roomId, $chat_userid);
593  $rset = $ilDB->queryF($query, $types, $values);
594 
595  if($rset && ($row = $ilDB->fetchAssoc($rset)) && $row['cnt'] == 1)
596  return true;
597 
598  return false;
599  }
600 
601  public function isAllowedToEnterPrivateRoom($chat_userid, $proom_id)
602  {
603  //echo call_user_func_array('sprintf', array_merge(array($query), $values));
604  global $ilDB;
605 
606  $query = 'SELECT count(user_id) cnt FROM ' . self::$privateRoomsAccessTable .
607  ' WHERE proom_id = %s AND user_id = %s';
608 
609  $types = array('integer', 'integer');
610  $values = array($proom_id, $chat_userid);
611  $rset = $ilDB->queryF($query, $types, $values);
612 
613  if($rset && ($row = $ilDB->fetchAssoc($rset)) && $row['cnt'] == 1)
614  return true;
615 
616  $query = 'SELECT count(*) cnt FROM ' . self::$privateRoomsTable .
617  ' WHERE proom_id = %s AND owner = %s';
618 
619  $types = array('integer', 'integer');
620  $values = array($proom_id, $chat_userid);
621  $rset = $ilDB->queryF($query, $types, $values);
622 
623  if($rset && ($row = $ilDB->fetchAssoc($rset)) && $row['cnt'] == 1)
624  return true;
625 
626  return false;
627  }
628 
638  public function getHistory(ilDateTime $from = null, ilDateTime $to = null, $restricted_session_userid = null, $proom_id = 0)
639  {
640  global $ilDB, $ilUser;
641 
642  $join = '';
643 
644  if($proom_id)
645  {
646  $join .=
647  'INNER JOIN ' . self::$privateSessionsTable . ' pSessionTable ' .
648  'ON pSessionTable.user_id = ' . $ilDB->quote($restricted_session_userid, 'integer') . ' ' .
649  'AND pSessionTable.proom_id = historyTable.sub_room ' .
650  'AND timestamp >= pSessionTable.connected ' .
651  'AND timestamp <= pSessionTable.disconnected ';
652  }
653 
654  $query =
655  'SELECT historyTable.* ' .
656  'FROM ' . self::$historyTable . ' historyTable ' . $join . ' ' .
657  'WHERE historyTable.room_id = ' . $this->getRoomId();
658 
659  $query .= ' AND historyTable.sub_room = ' . $ilDB->quote($proom_id, 'integer');
660 
661  $filter = array();
662 
663  if($from != null)
664  {
665  $filter[] = 'timestamp >= ' . $ilDB->quote($from->getUnixTime(), 'integer');
666  }
667 
668  if($to != null)
669  {
670  $filter[] = 'timestamp <= ' . $ilDB->quote($to->getUnixTime(), 'integer');
671  }
672 
673  if($filter)
674  $query .= ' AND ' . join(' AND ', $filter);
675  $query .= ' ORDER BY timestamp ASC';
676 
677  $rset = $ilDB->query($query);
678  $result = array();
679 
680  while($row = $ilDB->fetchAssoc($rset))
681  {
682  $message = json_decode($row['message']);
683  if ($message === null) {
684  $message = json_decode('{}');
685  }
686 
687  $row['message'] = $message;
688  $row['message']->timestamp = $row['timestamp'];
689  if($row['message']->target !== null && !$row['message']->target->public && !in_array($ilUser->getId(), explode(',', $row['recipients'])))
690  {
691  continue;
692  }
693 
694  $result[] = $row;
695  }
696  return $result;
697  }
698 
703  public function getRoomId()
704  {
705  return $this->roomId;
706  }
707 
708  public function getPrivateRoomSessions(ilDateTime $from = null, ilDateTime $to = null, $user_id = 0, $room_id = 0)
709  {
710  global $ilDB;
711 
712  $query = 'SELECT proom_id, title FROM ' . self::$privateRoomsTable . ' WHERE proom_id IN (
713  SELECT proom_id FROM ' . self::$privateSessionsTable . ' WHERE connected >= %s AND disconnected <= %s AND user_id = %s
714 
715  ) AND parent_id = %s';
716 
717  $rset = $ilDB->queryF($query, array('integer', 'integer', 'integer', 'integer'), array($from->getUnixTime(), $to->getUnixTime(), $user_id, $room_id));
718  $result = array();
719  while($row = $ilDB->fetchAssoc($rset))
720  {
721  $result[] = $row;
722  }
723  return $result;
724  }
725 
733  public function saveFileUploadToDb($user_id, $filename, $type)
734  {
735  global $ilDB;
736 
737  $upload_id = $ilDB->nextId(self::$uploadTable);
738 
739  $ilDB->insert(
740  self::$uploadTable,
741  array(
742  'upload_id' => array('integer', $upload_id),
743  'room_id' => array('integer', $this->roomId),
744  'user_id' => array('integer', $user_id),
745  'filename' => array('text', $filename),
746  'filetype' => array('text', $type),
747  'timestamp' => array('integer', time())
748  )
749  );
750  }
751 
758  public function banUser($user_id, $comment = '')
759  {
760  global $ilDB;
761 
762  $ilDB->replace(
763  self::$banTable,
764  array(
765  'room_id' => array('integer', $this->roomId),
766  'user_id' => array('integer', $user_id)
767  ),
768  array(
769  'timestamp' => array('integer', time()),
770  'remark' => array('text', $comment)
771  )
772  );
773  }
774 
782  public function unbanUser($user_id)
783  {
784  global $ilDB;
785 
786  if(!is_array($user_id))
787  {
788  $user_id = array($user_id);
789  }
790 
791  $query = 'DELETE FROM ' . self::$banTable . ' WHERE room_id = %s AND ' . $ilDB->in('user_id', $user_id, false, 'integer');
792 
793  $types = array('integer');
794  $values = array($this->getRoomId());
795 
796  return $ilDB->manipulateF($query, $types, $values);
797  }
798 
806  public function isUserBanned($user_id)
807  {
808  global $ilDB;
809 
810  $query = 'SELECT COUNT(user_id) cnt FROM ' . self::$banTable . ' WHERE user_id = %s AND room_id = %s';
811 
812  $types = array('integer', 'integer');
813  $values = array($user_id, $this->getRoomId());
814 
815  $rset = $ilDB->queryF($query, $types, $values);
816 
817  if($rset && ($row = $ilDB->fetchAssoc($rset)) && $row['cnt'])
818  {
819  return true;
820  }
821 
822  return false;
823  }
824 
831  public function getBannedUsers()
832  {
833  global $ilDB;
834 
835  $query = 'SELECT chb.* FROM ' . self::$banTable . ' chb INNER JOIN usr_data ud ON chb.user_id = ud.usr_id WHERE chb.room_id = %s ';
836  $types = array('integer');
837  $values = array($this->getRoomId());
838  $rset = $ilDB->queryF($query, $types, $values);
839  $result = array();
840 
841  if($rset)
842  {
843  while($row = $ilDB->fetchAssoc($rset))
844  {
845  if($row['user_id'] > 0)
846  {
847  $user = new ilObjUser($row['user_id']);
848  $userdata = array(
849  'user_id' => $user->getId(),
850  'firstname' => $user->getFirstname(),
851  'lastname' => $user->getLastname(),
852  'login' => $user->getLogin(),
853  'remark' => $row['remark']
854  );
855 
856  $result[] = $userdata;
857  }
858  else
859  {
860  //@todo anonymous user
861  }
862  }
863  }
864 
865  return $result;
866  }
867 
876  public function getLastSession(ilChatroomUser $user)
877  {
878  global $ilDB;
879 
880  $query = 'SELECT * FROM ' . self::$sessionTable . ' WHERE user_id = ' .
881  $ilDB->quote($user->getUserId(), 'integer') .
882  ' ORDER BY connected DESC';
883 
884  $ilDB->setLimit(1);
885  $rset = $ilDB->query($query);
886 
887  if($row = $ilDB->fetchAssoc($rset))
888  {
889  return $row;
890  }
891  }
892 
901  public function getSessions(ilChatroomUser $user)
902  {
903  global $ilDB;
904 
905  $query = 'SELECT * FROM ' . self::$sessionTable
906  . ' WHERE room_id = ' .
907  $ilDB->quote($this->getRoomId(), 'integer') .
908  ' ORDER BY connected DESC';
909 
910  $rset = $ilDB->query($query);
911 
912  $result = array();
913 
914  while($row = $ilDB->fetchAssoc($rset))
915  {
916  $result[] = $row;
917  }
918 
919  return $result;
920  }
921 
922  public function addPrivateRoom($title, ilChatroomUser $owner, $settings)
923  {
924  global $ilDB;
925 
926  $nextId = $ilDB->nextId(self::$privateRoomsTable);
927  $ilDB->insert(
928  self::$privateRoomsTable,
929  array(
930  'proom_id' => array('integer', $nextId),
931  'parent_id' => array('integer', $this->roomId),
932  'title' => array('text', $title),
933  'owner' => array('integer', $owner->getUserId()),
934  'created' => array('integer', time()),
935  'is_public' => array('integer', $settings['public']),
936  )
937  );
938 
939  return $nextId;
940  }
941 
942  public function closePrivateRoom($id)
943  {
944  global $ilDB;
945 
946  $ilDB->manipulateF(
947  'UPDATE ' . self::$privateRoomsTable . ' SET closed = %s WHERE proom_id = %s',
948  array('integer', 'integer'),
949  array(time(), $id)
950  );
951  }
952 
953  public function isOwnerOfPrivateRoom($user_id, $proom_id)
954  {
955  global $ilDB;
956 
957  $query = 'SELECT proom_id FROM ' . self::$privateRoomsTable . ' WHERE proom_id = %s AND owner = %s';
958  $types = array('integer', 'integer');
959  $values = array($proom_id, $user_id);
960 
961  $rset = $ilDB->queryF($query, $types, $values);
962 
963  if($rset && $ilDB->fetchAssoc($rset))
964  {
965  return true;
966  }
967  return false;
968  }
969 
978  public function sendInvitationNotification($gui, $sender, $recipient_id, $subScope = 0, $invitationLink = '')
979  {
983  global $lng;
984 
985  if($gui && !$invitationLink)
986  {
987  $invitationLink = $this->getChatURL($gui, $subScope);
988  }
989 
990  if($recipient_id > 0 && !in_array(ANONYMOUS_USER_ID, array($recipient_id)))
991  {
992  if(is_numeric($sender) && $sender > 0)
993  {
994  $sender_id = $sender;
998  $usr = ilObjectFactory::getInstanceByObjId($sender);
999  $public_name = $usr->getPublicName();
1000  }
1001  else if($sender instanceof ilChatroomUser)
1002  {
1003  if($sender->getUserId() > 0)
1004  {
1005  $sender_id = $sender->getUserId();
1006  }
1007  else
1008  {
1009  $sender_id = ANONYMOUS_USER_ID;
1010  }
1011  $public_name = $sender->getUsername();
1012  }
1013  else
1014  {
1015  throw new InvalidArgumentException('$sender must be an instance of ilChatroomUser or an id of an ilObjUser instance');
1016  }
1017 
1018  $lng->loadLanguageModule('mail');
1019 
1020  $recipient = ilObjectFactory::getInstanceByObjId($recipient_id);
1021  $bodyParams = array(
1022  'link' => $invitationLink,
1023  'inviter_name' => $public_name,
1024  'room_name' => $this->getTitle(),
1025  'salutation' => $lng->txt('mail_salutation_' . $recipient->getGender()) . ' ' . $recipient->getFullname()
1026  );
1027 
1028  if($subScope)
1029  {
1030  $bodyParams['room_name'] .= ' - ' . self::lookupPrivateRoomTitle($subScope);
1031  }
1032 
1033  require_once 'Services/Notifications/classes/class.ilNotificationConfig.php';
1034  $notification = new ilNotificationConfig('chat_invitation');
1035  $notification->setTitleVar('chat_invitation', $bodyParams, 'chatroom');
1036  $notification->setShortDescriptionVar('chat_invitation_short', $bodyParams, 'chatroom');
1037  $notification->setLongDescriptionVar('chat_invitation_long', $bodyParams, 'chatroom');
1038  $notification->setAutoDisable(false);
1039  $notification->setLink($invitationLink);
1040  $notification->setIconPath('templates/default/images/icon_chtr.svg');
1041  $notification->setValidForSeconds(ilNotificationConfig::TTL_LONG);
1042  $notification->setVisibleForSeconds(ilNotificationConfig::DEFAULT_TTS);
1043 
1044  $notification->setHandlerParam('mail.sender', $sender_id);
1045 
1046  $notification->notifyByUsers(array($recipient_id));
1047  }
1048  }
1049 
1055  public function getChatURL($gui, $scope_id = 0)
1056  {
1057  include_once 'Services/Link/classes/class.ilLink.php';
1058 
1059  $url = '';
1060 
1061  if(is_object($gui))
1062  {
1063  if($scope_id)
1064  {
1065  $url = ilLink::_getStaticLink($gui->object->getRefId(), $gui->object->getType(), true, '_' . $scope_id);
1066  }
1067  else
1068  {
1069  $url = ilLink::_getStaticLink($gui->object->getRefId(), $gui->object->getType());
1070  }
1071  }
1072 
1073  return $url;
1074  }
1075 
1076  public function getTitle()
1077  {
1078  if(!$this->object)
1079  {
1080  $this->object = ilObjectFactory::getInstanceByObjId($this->getSetting('object_id'));
1081  }
1082 
1083  return $this->object->getTitle();
1084  }
1085 
1086  public static function lookupPrivateRoomTitle($proom_id)
1087  {
1088  global $ilDB;
1089 
1090  $query = 'SELECT title FROM ' . self::$privateRoomsTable . ' WHERE proom_id = %s';
1091  $types = array('integer');
1092  $values = array($proom_id);
1093 
1094  $rset = $ilDB->queryF($query, $types, $values);
1095 
1096  if($row = $ilDB->fetchAssoc($rset))
1097  {
1098  return $row['title'];
1099  }
1100 
1101  return 'unkown';
1102  }
1103 
1104  public function inviteUserToPrivateRoomByLogin($login, $proom_id)
1105  {
1106  global $ilDB;
1107  $user_id = ilObjUser::_lookupId($login);
1108  $this->inviteUserToPrivateRoom($user_id, $proom_id);
1109  }
1110 
1115  public function inviteUserToPrivateRoom($user_id, $proom_id)
1116  {
1120  global $ilDB;
1121 
1122  $query = 'DELETE FROM ' . self::$privateRoomsAccessTable . ' WHERE user_id = %s AND proom_id = %s';
1123  $types = array('integer', 'integer');
1124  $values = array($user_id, $proom_id);
1125 
1126  $ilDB->manipulateF($query, $types, $values);
1127 
1128  $ilDB->insert(self::$privateRoomsAccessTable, array(
1129  'user_id' => array('integer', $user_id),
1130  'proom_id' => array('integer', $proom_id)
1131  ));
1132  }
1133 
1134  public function getActivePrivateRooms($userid)
1135  {
1136  global $ilDB;
1137 
1138  $query = '
1139  SELECT roomtable.title, roomtable.proom_id, accesstable.user_id id, roomtable.owner rowner
1140  FROM ' . self::$privateRoomsTable . ' roomtable
1141  LEFT JOIN ' . self::$privateRoomsAccessTable . ' accesstable
1142  ON roomtable.proom_id = accesstable.proom_id
1143  AND accesstable.user_id = %s
1144  WHERE parent_id = %s
1145  AND (closed = 0 OR closed IS NULL)
1146  AND (accesstable.user_id IS NOT NULL OR roomtable.owner = %s)';
1147  $types = array('integer', 'integer', 'integer');
1148  $values = array($userid, $this->roomId, $userid);
1149  $rset = $ilDB->queryF($query, $types, $values);
1150  $rooms = array();
1151 
1152  while($row = $ilDB->fetchAssoc($rset))
1153  {
1154  $row['active_users'] = $this->listUsersInPrivateRoom($row['id']);
1155  $row['owner'] = $row['rowner'];
1156  $rooms[$row['proom_id']] = $row;
1157  }
1158 
1159  return $rooms;
1160  }
1161 
1162  public function listUsersInPrivateRoom($private_room_id)
1163  {
1164  global $ilDB;
1165 
1166  $query = '
1167  SELECT chatroom_users.user_id FROM ' . self::$privateSessionsTable . '
1168  INNER JOIN chatroom_users ON chatroom_users.user_id = ' . self::$privateSessionsTable . '.user_id WHERE proom_id = %s AND disconnected = 0
1169  ';
1170  $types = array('integer');
1171  $values = array($private_room_id);
1172  $rset = $ilDB->queryF($query, $types, $values);
1173 
1174  $users = array();
1175 
1176  while($row = $ilDB->fetchAssoc($rset))
1177  {
1178  $users[$row['user_id']] = $row['user_id'];
1179  }
1180 
1181  return array_values($users);
1182  }
1183 
1184  public function subscribeUserToPrivateRoom($room_id, $user_id)
1185  {
1186  global $ilDB;
1187 
1188  if(!$this->userIsInPrivateRoom($room_id, $user_id))
1189  {
1190  $id = $ilDB->nextId(self::$privateSessionsTable);
1191  $ilDB->insert(
1192  self::$privateSessionsTable,
1193  array(
1194  'psess_id' => array('integer', $id),
1195  'proom_id' => array('integer', $room_id),
1196  'user_id' => array('integer', $user_id),
1197  'connected' => array('integer', time()),
1198  'disconnected' => array('integer', 0),
1199  )
1200  );
1201  }
1202  }
1203 
1204  public function userIsInPrivateRoom($room_id, $user_id)
1205  {
1206  global $ilDB;
1207 
1208  $query = 'SELECT proom_id id FROM ' . self::$privateSessionsTable . ' WHERE user_id = %s AND proom_id = %s AND disconnected = 0';
1209  $types = array('integer', 'integer');
1210  $values = array($user_id, $room_id);
1211  $rset = $ilDB->queryF($query, $types, $values);
1212  if($ilDB->fetchAssoc($rset))
1213  return true;
1214  return false;
1215  }
1216 
1222  public function unsubscribeUserFromPrivateRoom($room_id, $user_id)
1223  {
1224  global $ilDB;
1225 
1226  $ilDB->update(
1227  self::$privateSessionsTable,
1228  array(
1229  'disconnected' => array('integer', time())
1230  ),
1231  array(
1232  'proom_id' => array('integer', $room_id),
1233  'user_id' => array('integer', $user_id)
1234  )
1235  );
1236  }
1237 
1238  public function countActiveUsers()
1239  {
1240  global $ilDB;
1241 
1242  $query = 'SELECT count(user_id) as cnt FROM ' . self::$userTable .
1243  ' WHERE room_id = %s';
1244 
1245  $types = array('integer');
1246  $values = array($this->roomId);
1247  $rset = $ilDB->queryF($query, $types, $values);
1248 
1249  if($rset && ($row = $ilDB->fetchAssoc($rset)) && $row['cnt'] == 1)
1250  return $row['cnt'];
1251 
1252  return 0;
1253  }
1254 
1256  {
1257  global $ilDB;
1258 
1259  $query = 'SELECT title FROM ' . self::$privateRoomsTable . ' WHERE parent_id = %s and closed = 0';
1260  $rset = $ilDB->queryF($query, array('integer'), array($this->roomId));
1261 
1262  $titles = array();
1263 
1264  while($row = $ilDB->fetchAssoc($rset))
1265  {
1266  $titles[] = $row['title'];
1267  }
1268 
1269  $suffix = '';
1270  $i = 0;
1271  do
1272  {
1273  if(!in_array($title . $suffix, $titles))
1274  {
1275  $title .= $suffix;
1276  break;
1277  }
1278 
1279  ++$i;
1280 
1281  $suffix = ' (' . $i . ')';
1282  }
1283  while(true);
1284 
1285  return $title;
1286  }
1287 
1295  public function getAllRooms($user_id)
1296  {
1300  global $ilDB;
1301 
1302  $query = "
1303  SELECT room_id, od.title
1304  FROM object_data od
1305 
1306  INNER JOIN " . self::$settingsTable . "
1307  ON object_id = od.obj_id
1308 
1309  INNER JOIN " . self::$privateRoomsTable . " prt
1310  ON prt.owner = %s
1311 
1312  WHERE od.type = 'chtr'
1313  ";
1314 
1315  $types = array('integer');
1316  $values = array($user_id);
1317 
1318  $res = $ilDB->queryF($query, $types, $values);
1319 
1320  $rooms = array();
1321 
1322  while($row = $ilDB->fetchAssoc($res))
1323  {
1324  $room_id = $row['room_id'];
1325  $rooms[$room_id] = $row['title'];
1326  }
1327 
1328  return $rooms;
1329  }
1330 
1331  public function getPrivateSubRooms($parent_room, $user_id)
1332  {
1333  global $ilDB;
1334 
1335  $query = "
1336  SELECT proom_id, parent_id
1337  FROM chatroom_prooms
1338  WHERE parent_id = %s
1339  AND owner = %s
1340  AND closed = 0
1341  ";
1342 
1343  $types = array('integer', 'integer');
1344  $values = array($parent_room, $user_id);
1345 
1346  $res = $ilDB->queryF($query, $types, $values);
1347 
1348  $priv_rooms = array();
1349 
1350  while($row = $ilDB->fetchAssoc($res))
1351  {
1352  $proom_id = $row['proom_id'];
1353  $priv_rooms[$proom_id] = $row['parent_id'];
1354  }
1355 
1356  return $priv_rooms;
1357  }
1358 
1365  public function getRefIdByRoomId($room_id)
1366  {
1367  global $ilDB;
1368 
1369  $query = "
1370  SELECT objr.ref_id
1371  FROM object_reference objr
1372 
1373  INNER JOIN chatroom_settings cs
1374  ON cs.object_id = objr.obj_id
1375 
1376  INNER JOIN object_data od
1377  ON od.obj_id = cs.object_id
1378 
1379  WHERE cs.room_id = %s
1380  ";
1381 
1382  $types = array('integer');
1383  $values = array($room_id);
1384 
1385  $res = $ilDB->queryF($query, $types, $values);
1386 
1387  $row = $ilDB->fetchAssoc($res);
1388 
1389  return $row['ref_id'];
1390  }
1391 
1392  public function getLastMessagesForChatViewer($number, $chatuser = null)
1393  {
1394  return $this->getLastMessages($number, $chatuser);
1395  }
1396 
1397  public function getLastMessages($number, $chatuser = null)
1398  {
1399  global $ilDB;
1400 
1401  // There is currently no way to check if a message is private or not
1402  // by sql. So we fetch twice as much as we need and hope that there
1403  // are not more than $number private messages.
1404  $ilDB->setLimit($number);
1405  $rset = $ilDB->query(
1406  'SELECT *
1407  FROM ' . self::$historyTable . '
1408  WHERE room_id = ' . $ilDB->quote($this->roomId, 'integer') . '
1409  AND sub_room = 0
1410  AND (
1411  (' . $ilDB->like('message', 'text', '%"type":"message"%') . ' AND NOT ' . $ilDB->like('message', 'text', '%"public":0%') . ')
1412  OR ' . $ilDB->like('message', 'text', '%"target":{%"id":"' . $chatuser->getUserId() . '"%') . '
1413  OR ' . $ilDB->like('message', 'text', '%"from":{"id":' . $chatuser->getUserId() . '%') . '
1414  )
1415  ORDER BY timestamp DESC'
1416  );
1417  /*$rset = $ilDB->queryF('SELECT * FROM ' . self::$historyTable . ' WHERE room_id = %s AND sub_room = 0 ORDER BY timestamp DESC', array('integer'), array($this->roomId));*/
1418 
1419  $result_count = 0;
1420  $results = array();
1421  while(($row = $ilDB->fetchAssoc($rset)) && $result_count < $number)
1422  {
1423  $tmp = json_decode($row['message']);
1424  if($chatuser !== null && $tmp->target != null && $tmp->target->public == 0)
1425  {
1426  if($chatuser->getUserId() == $tmp->target->id || $chatuser->getUserId() == $tmp->from->id)
1427  {
1428  $results[] = $tmp;
1429  ++$result_count;
1430  }
1431  }
1432  else
1433  {
1434  $results[] = $tmp;
1435  ++$result_count;
1436  }
1437  }
1438 
1439  $rset = $ilDB->query(
1440  'SELECT *
1441  FROM ' . self::$historyTable . '
1442  WHERE room_id = ' . $ilDB->quote($this->roomId, 'integer') . '
1443  AND sub_room = 0
1444  AND ' . $ilDB->like('message', 'text', '%"type":"notice"%') . '
1445  AND timestamp <= ' . $ilDB->quote($results[0]->timestamp, 'integer') . ' AND timestamp >= ' . $ilDB->quote($results[$result_count - 1]->timestamp, 'integer') . '
1446 
1447  ORDER BY timestamp DESC'
1448  );
1449 
1450  while(($row = $ilDB->fetchAssoc($rset)))
1451  {
1452  $tmp = json_decode($row['message']);
1453  $results[] = $tmp;
1454  }
1455 
1456  \usort($results, function ($a, $b)
1457  {
1458  $a_timestamp = strlen($a->timestamp) == 13 ? substr($a->timestamp, 0, -3) : $a->timestamp;
1459  $b_timestamp = strlen($b->timestamp) == 13 ? substr($b->timestamp, 0, -3) : $b->timestamp;
1460 
1461  return $b_timestamp - $a_timestamp;
1462  });
1463 
1464  return $results;
1465  }
1466 
1467  public function clearMessages($sub_room)
1468  {
1469  global $ilDB;
1470 
1471  $ilDB->queryF(
1472  'DELETE FROM ' . self::$historyTable . ' WHERE room_id = %s AND sub_room = %s',
1473  array('integer', 'integer'),
1474  array($this->roomId, (int)$sub_room)
1475  );
1476 
1477  if($sub_room)
1478  {
1479  $ilDB->queryF(
1480  'DELETE FROM ' . self::$privateSessionsTable . ' WHERE proom_id = %s AND disconnected < %s',
1481  array('integer', 'integer'),
1482  array($sub_room, time())
1483  );
1484  }
1485  else
1486  {
1487  $ilDB->queryF(
1488  'DELETE FROM ' . self::$sessionTable . ' WHERE room_id = %s AND disconnected < %s',
1489  array('integer', 'integer'),
1490  array($this->roomId, time())
1491  );
1492  }
1493  }
1494 }
setSetting($name, $value)
Sets given name and value as setting into $this->settings array.
static $privateRoomsTable
getUserId()
Returns Ilias User ID.
getActivePrivateRooms($userid)
getUniquePrivateRoomTitle($title)
getPrivateSubRooms($parent_room, $user_id)
banUser($user_id, $comment='')
Inserts user into banTable, using given $user_id ilDBInterface $ilDB.
getRoomId()
Returns roomID from $this->roomId.
$result
getHistory(ilDateTime $from=null, ilDateTime $to=null, $restricted_session_userid=null, $proom_id=0)
Returns array containing history data selected from historyTable by given ilDateTime, $restricted_session_userid and matching roomId.
isUserBanned($user_id)
Returns true if there&#39;s an entry in banTable matching roomId and given $user_id ilDBInterface $ilDB...
static $settingsTable
getLastMessages($number, $chatuser=null)
getSettings()
Returns $this->settings array.
getLastSession(ilChatroomUser $user)
Returns last session from user.
getRefIdByRoomId($room_id)
Returns ref_id of given room_id ilDBInterface $ilDB.
getSetting($name)
Returns setting from $this->settings array by given name.
isSubscribed($chat_userid)
Returns true if entry exists in userTable matching given $chat_userid and $this->roomId.
static byRoomId($room_id, $initObject=false)
Returns ilChatroom by given $room_id ilDBInterface $ilDB.
getPrivateRoomSessions(ilDateTime $from=null, ilDateTime $to=null, $user_id=0, $room_id=0)
disconnectUsers(array $userIds)
Disconnects users by deleting userdata from userTable using given userId array.
static _lookupId($a_user_str)
Lookup id by login.
unsubscribeUserFromPrivateRoom($room_id, $user_id)
ilDBInterface $ilDB
$url
Definition: shib_logout.php:72
clearMessages($sub_room)
userIsInPrivateRoom($room_id, $user_id)
getChatURL($gui, $scope_id=0)
ilCtrl $ilCtrl
Describes a notification and provides methods for publishing this notification.
listUsersInPrivateRoom($private_room_id)
save()
Saves settings using $this->settings.
isOwnerOfPrivateRoom($user_id, $proom_id)
static $privateSessionsTable
static checkUserPermissions($permissions, $ref_id, $send_info=true)
Checks user permissions by given array and ref_id.
getBannedUsers()
Returns an multidimensional array containing userdata from users having an entry in banTable with mat...
addPrivateRoom($title, ilChatroomUser $owner, $settings)
getSessions(ilChatroomUser $user)
Returns all session from user Returns all from sessionTable where user_id matches userId from given $...
static findDeletablePrivateRooms()
addHistoryEntry($message, $recipient=null, $publicMessage=true)
Inserts entry into historyTable.
static lookupPrivateRoomTitle($proom_id)
Date and time handling
getConnectedUsers()
Returns an array of connected users.
$ilUser
Definition: imgupload.php:18
subscribeUserToPrivateRoom($room_id, $user_id)
saveFileUploadToDb($user_id, $filename, $type)
Saves information about file uploads in DB.
$results
unbanUser($user_id)
Deletes entry from banTable matching roomId and given $user_id and returns true if sucessful...
disconnectUser($user_id)
Creates userId array by given $user object and calls disconnectUsers method.
static getInstanceByObjId($a_obj_id, $stop_on_error=true)
get an instance of an Ilias object by object id
$comment
Definition: buildRTE.php:83
static disconnectAllUsersFromAllRooms()
Deletes all entrys from userTable.
Create styles array
The data for the language used.
static sendFailure($a_info="", $a_keep=false)
Send Failure Message to Screen.
Class ilChatroom.
getLastMessagesForChatViewer($number, $chatuser=null)
static $privateRoomsAccessTable
static $historyTable
settings()
Definition: settings.php:2
$ref_id
Definition: sahs_server.php:39
Class ilChatroomUser.
global $lng
Definition: privfeed.php:17
global $ilDB
inviteUserToPrivateRoomByLogin($login, $proom_id)
phpTypeToMDBType($type)
static byObjectId($object_id)
Returns ilChatroom object by given $object_id.
getUsername()
Returns username from Object or SESSION.
Add data(end) time
Method that wraps PHPs time in order to allow simulations with the workflow.
initialize(array $rowdata)
Sets $this->roomId by given array $rowdata and calls setSetting method foreach available setting in $...
static $uploadTable
static checkPermissionsOfUser($usr_id, $permissions, $ref_id)
Checks user permissions in question for a given user id in relation to a given ref_id.
static $sessionTable
saveSettings(array $settings)
Saves settings into settingsTable using given settings array.
isAllowedToEnterPrivateRoom($chat_userid, $proom_id)