ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
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();
28 private $availableSettings = array(
29 'object_id' => 'integer',
30 'online_status' => 'integer',
31 'allow_anonymous' => 'boolean',
32 'allow_custom_usernames' => 'boolean',
33 'enable_history' => 'boolean',
34 'restrict_history' => 'boolean',
35 'autogen_usernames' => 'string',
36 'room_type' => 'string',
37 'allow_private_rooms' => 'integer',
38 'display_past_msgs' => 'integer',
39 'private_rooms_enabled' => 'boolean'
40 );
41 private $roomId;
42
43 private $object;
44
52 public static function checkUserPermissions($permissions, $ref_id, $send_info = true)
53 {
54 global $DIC;
55
56 if (!is_array($permissions)) {
57 $permissions = array($permissions);
58 }
59
60 $hasPermissions = self::checkPermissions($DIC->user()->getId(), $ref_id, $permissions);
61 if (!$hasPermissions && $send_info) {
62 ilUtil::sendFailure($DIC->language()->txt('permission_denied'), true);
63
64 return false;
65 }
66
67 return $hasPermissions;
68 }
69
78 public static function checkPermissionsOfUser($usr_id, $permissions, $ref_id)
79 {
80 if (!is_array($permissions)) {
81 $permissions = array($permissions);
82 }
83
84 return self::checkPermissions($usr_id, $ref_id, $permissions);
85 }
86
93 protected static function checkPermissions($usrId, $refId, array $permissions)
94 {
95 global $DIC;
96
97 require_once 'Modules/Chatroom/classes/class.ilObjChatroom.php';
98 $pub_ref_id = ilObjChatroom::_getPublicRefId();
99
100 foreach ($permissions as $permission) {
101 if ($pub_ref_id == $refId) {
102 $hasAccess = $DIC->rbac()->system()->checkAccessOfUser($usrId, $permission, $refId);
103 if ($hasAccess) {
104 $hasWritePermission = $DIC->rbac()->system()->checkAccessOfUser($usrId, 'write', $refId);
105 if ($hasWritePermission) {
106 continue;
107 }
108
109 $visible = null;
110 $a_obj_id = ilObject::_lookupObjId($refId);
111 $active = ilObjChatroomAccess::isActivated($refId, $a_obj_id, $visible);
112
113 switch ($permission) {
114 case 'visible':
115 if (!$active) {
116 $GLOBALS['DIC']->access()->addInfoItem(IL_NO_OBJECT_ACCESS, $GLOBALS['DIC']->language()->txt('offline'));
117 }
118
119 if (!$active && !$visible) {
120 return false;
121 }
122 break;
123
124 case 'read':
125 if (!$active) {
126 $GLOBALS['DIC']->access()->addInfoItem(IL_NO_OBJECT_ACCESS, $GLOBALS['DIC']->language()->txt('offline'));
127 return false;
128 }
129 break;
130 }
131 }
132 } else {
133 $hasAccess = $DIC->access()->checkAccessOfUser($usrId, $permission, '', $refId);
134 }
135
136 if (!$hasAccess) {
137 return false;
138 }
139 }
140
141 return true;
142 }
143
149 public static function byObjectId($object_id)
150 {
151 global $DIC;
152
153 $query = 'SELECT * FROM ' . self::$settingsTable . ' WHERE object_id = %s';
154 $types = array('integer');
155 $values = array($object_id);
156 $rset = $DIC->database()->queryF($query, $types, $values);
157
158 if ($row = $DIC->database()->fetchAssoc($rset)) {
159 $room = new self();
160 $room->initialize($row);
161 return $room;
162 }
163 }
164
170 public function initialize(array $rowdata)
171 {
172 $this->roomId = $rowdata['room_id'];
173
174 foreach ($this->availableSettings as $setting => $type) {
175 if (isset($rowdata[$setting])) {
176 settype($rowdata[$setting], $this->availableSettings[$setting]);
177 $this->setSetting($setting, $rowdata[$setting]);
178 }
179 }
180 }
181
187 public function setSetting($name, $value)
188 {
189 $this->settings[$name] = $value;
190 }
191
197 public static function byRoomId($room_id, $initObject = false)
198 {
199 global $DIC;
200
201 $query = 'SELECT * FROM ' . self::$settingsTable . ' WHERE room_id = %s';
202
203 $types = array('integer');
204 $values = array($room_id);
205
206 $rset = $DIC->database()->queryF($query, $types, $values);
207
208 if ($row = $DIC->database()->fetchAssoc($rset)) {
209 $room = new self();
210 $room->initialize($row);
211
212 if ($initObject) {
213 $room->object = ilObjectFactory::getInstanceByObjId($row['object_id']);
214 }
215
216 return $room;
217 }
218 }
219
223 public static function disconnectAllUsersFromAllRooms()
224 {
225 global $DIC;
226
227 $DIC->database()->manipulate('DELETE FROM ' . self::$userTable);
228 $DIC->database()->manipulate('UPDATE ' . self::$privateRoomsTable . ' SET closed = ' . $DIC->database()->quote(time(), 'integer') . ' WHERE closed = 0 OR closed IS NULL');
229 $DIC->database()->manipulate('UPDATE ' . self::$privateSessionsTable . ' SET disconnected = ' . $DIC->database()->quote(time(), 'integer') . ' WHERE disconnected = 0');
233 }
234
235 public static function findDeletablePrivateRooms()
236 {
237 global $DIC;
238
239 $query = '
240 SELECT private_rooms.proom_id id, MIN(disconnected) min_disconnected, MAX(disconnected) max_disconnected
241 FROM ' . self::$privateSessionsTable . ' private_sessions
242 INNER JOIN ' . self::$privateRoomsTable . ' private_rooms
243 ON private_sessions.proom_id = private_rooms.proom_id
244 WHERE closed = 0
245 GROUP BY private_rooms.proom_id
246 HAVING MIN(disconnected) > 0 AND MAX(disconnected) < %s';
247 $rset = $DIC->database()->queryF(
248 $query,
249 array('integer'),
250 array(time() + 60 * 5)
251 );
252
253 $rooms = array();
254
255 while ($row = $DIC->database()->fetchAssoc($rset)) {
256 $rooms[$row['id']] = $row['id'];
257 }
258
259 $query = 'SELECT DISTINCT proom_id, room_id, object_id FROM ' . self::$privateRoomsTable
260 . ' INNER JOIN ' . self::$settingsTable . ' ON parent_id = room_id '
261 . ' WHERE ' . $DIC->database()->in('proom_id', $rooms, false, 'integer');
262
263 $rset = $DIC->database()->query($query);
264 $rooms = array();
265 while ($row = $DIC->database()->fetchAssoc($rset)) {
266 $rooms[] = array(
267 'proom_id' => $row['proom_id'],
268 'room_id' => $row['room_id'],
269 'object_id' => $row['object_id']
270 );
271 }
272
273 return $rooms;
274 }
275
276 public static function getUntrashedChatReferences($filter = array())
277 {
278 global $DIC;
279
280 // Check for parent because of an invalid parent node for the old public chat (thx @ jposselt ;-)).
281 // We cannot find this old public chat and clean this automatically
282 $query = '
283 SELECT od.obj_id, od.title, ore.ref_id, od.type, odp.title parent_title
284 FROM object_data od
285 INNER JOIN object_reference ore ON ore.obj_id = od.obj_id
286 INNER JOIN tree t ON t.child = ore.ref_id
287 INNER JOIN tree p ON p.child = t.parent
288 INNER JOIN object_reference orep ON orep.ref_id = p.child
289 INNER JOIN object_data odp ON odp.obj_id = orep.obj_id
290 INNER JOIN object_reference pre ON pre.ref_id = t.parent
291 INNER JOIN object_data pod ON pod.obj_id = pre.obj_id
292 ';
293
294 if (isset($filter['last_activity'])) {
295 $threshold = $DIC->database()->quote($filter['last_activity'], 'integer');
296 $query .= "
297 INNER JOIN chatroom_settings ON chatroom_settings.object_id = od.obj_id
298 INNER JOIN chatroom_history ON chatroom_history.room_id = chatroom_settings.room_id AND chatroom_history.timestamp > $threshold
299 ";
300 }
301
302 $query .= '
303 WHERE od.type = %s AND t.tree > 0 AND ore.deleted IS NULL
304 GROUP BY od.obj_id, od.title, ore.ref_id, od.type, odp.title
305 ORDER BY od.title
306 ';
307 $res = $DIC->database()->queryF($query, array('text'), array('chtr'));
308
309 $chats = array();
310 while ($row = $DIC->database()->fetchAssoc($res)) {
311 $chats[] = $row;
312 }
313
314 return $chats;
315 }
316
317 public function getDescription()
318 {
319 if (!$this->object) {
320 $this->object = ilObjectFactory::getInstanceByObjId($this->getSetting('object_id'));
321 }
322
323 return $this->object->getDescription();
324 }
325
331 public function getSetting($name)
332 {
333 return $this->settings[$name];
334 }
335
339 public function save()
340 {
341 $this->saveSettings($this->settings);
342 }
343
348 public function saveSettings(array $settings)
349 {
350 global $DIC;
351
352 $localSettings = array();
353
354 foreach ($this->availableSettings as $setting => $type) {
355 if (isset($settings[$setting])) {
356 if ($type == 'boolean') {
357 $settings[$setting] = (boolean) $settings[$setting];
358 }
359 $localSettings[$setting] = array($this->phpTypeToMDBType($type), $settings[$setting]);
360 }
361 }
362
363 if (!$localSettings['room_type'][1]) {
364 $localSettings['room_type'][1] = 'repository';
365 }
366
367 if ($this->roomId) {
368 $DIC->database()->update(
369 self::$settingsTable,
370 $localSettings,
371 array('room_id' => array('integer', $this->roomId))
372 );
373 } else {
374 $this->roomId = $DIC->database()->nextId(self::$settingsTable);
375
376 $localSettings['room_id'] = array(
377 $this->availableSettings['room_id'], $this->roomId
378 );
379
380 $DIC->database()->insert(self::$settingsTable, $localSettings);
381 }
382 }
383
384 private function phpTypeToMDBType($type)
385 {
386 switch ($type) {
387 case 'string':
388 return 'text';
389 default:
390 return $type;
391 }
392 }
393
401 public function addHistoryEntry($message, $recipient = null, $publicMessage = true)
402 {
403 global $DIC;
404
405 $subRoom = 0;
406 $timestamp = 0;
407 if (is_array($message)) {
408 $subRoom = (int) $message['sub'];
409 $timestamp = (int) $message['timestamp'];
410 } elseif (is_object($message)) {
411 $subRoom = (int) $message->sub;
412 $timestamp = (int) $message->timestamp;
413 }
414
415 $id = $DIC->database()->nextId(self::$historyTable);
416 $DIC->database()->insert(
417 self::$historyTable,
418 array(
419 'hist_id' => array('integer', $id),
420 'room_id' => array('integer', $this->roomId),
421 'sub_room' => array('integer', $subRoom),
422 'message' => array('text', json_encode($message)),
423 'timestamp' => array('integer', ($timestamp > 0 ? $timestamp : time())),
424 )
425 );
426 }
427
438 {
439 global $DIC;
440
441 $userdata = array(
442 'login' => $user->getUsername(),
443 'id' => $user->getUserId()
444 );
445
446 $query = 'SELECT user_id FROM ' . self::$userTable . ' WHERE room_id = %s AND user_id = %s';
447 $types = array('integer', 'integer');
448 $values = array($this->roomId, $user->getUserId());
449
450 if (!$DIC->database()->fetchAssoc($DIC->database()->queryF($query, $types, $values))) {
451 // Notice: Using replace instead of insert looks strange, because we actually know whether the selected data exists or not
452 // But we occasionally found some duplicate key errors although the data set should not exist when the following code is reached
453 $DIC->database()->replace(
454 self::$userTable,
455 array(
456 'room_id' => array('integer', $this->roomId),
457 'user_id' => array('integer', $user->getUserId())
458 ),
459 array(
460 'userdata' => array('text', json_encode($userdata)),
461 'connected' => array('integer', time()),
462 )
463 );
464
465 return true;
466 }
467
468 return false;
469 }
470
478 public function getConnectedUsers($only_data = true)
479 {
480 global $DIC;
481
482 $query = 'SELECT ' . ($only_data ? 'userdata' : '*') . ' FROM ' . self::$userTable . ' WHERE room_id = %s';
483 $types = array('integer');
484 $values = array($this->roomId);
485 $rset = $DIC->database()->queryF($query, $types, $values);
486 $users = array();
487
488 while ($row = $DIC->database()->fetchAssoc($rset)) {
489 $users[] = $only_data ? json_decode($row['userdata']) : $row;
490 }
491
492 return $users;
493 }
494
500 public function disconnectUser($user_id)
501 {
502 $this->disconnectUsers(array($user_id));
503 }
504
511 public function disconnectUsers(array $userIds)
512 {
513 global $DIC;
514
515 $query = 'SELECT * FROM ' . self::$userTable . ' WHERE room_id = %s AND ' .
516 $DIC->database()->in('user_id', $userIds, false, 'integer');
517
518 $types = array('integer');
519 $values = array($this->roomId);
520 $rset = $DIC->database()->queryF($query, $types, $values);
521
522 if ($row = $DIC->database()->fetchAssoc($rset)) {
523 $query = 'SELECT proom_id FROM ' . self::$privateRoomsTable . ' WHERE parent_id = %s';
524 $rset_prooms = $DIC->database()->queryF($query, array('integer'), array($this->roomId));
525
526 $prooms = array();
527
528 while ($row_prooms = $DIC->database()->fetchAssoc($rset_prooms)) {
529 $prooms[] = $row_prooms['proom_id'];
530 }
531
532 if (true || $this->getSetting('enable_history')) {
533 $query = 'UPDATE ' . self::$privateSessionsTable . ' SET disconnected = %s WHERE ' . $DIC->database()->in('user_id', $userIds, false, 'integer') . ' AND ' . $DIC->database()->in('proom_id', $prooms, false, 'integer');
534 $DIC->database()->manipulateF($query, array('integer'), array(time()));
535 } else {
536 $query = 'DELETE FROM ' . self::$privateSessionsTable . ' WHERE ' . $DIC->database()->in('user_id', $userIds, false, 'integer') . ' AND ' . $DIC->database()->in('proom_id', $prooms, false, 'integer');
537 $DIC->database()->manipulate($query);
538 }
539
540 $query = 'DELETE FROM ' . self::$userTable . ' WHERE room_id = %s AND ' .
541 $DIC->database()->in('user_id', $userIds, false, 'integer');
542
543 $types = array('integer');
544 $values = array($this->roomId);
545 $DIC->database()->manipulateF($query, $types, $values);
546
547 do {
548 if ($this->getSetting('enable_history')) {
549 $id = $DIC->database()->nextId(self::$sessionTable);
550 $DIC->database()->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 } while ($row = $DIC->database()->fetchAssoc($rset));
563 }
564 }
565
570 public function getSettings()
571 {
572 return $this->settings;
573 }
574
581 public function isSubscribed($chat_userid)
582 {
583 global $DIC;
584
585 $query = 'SELECT count(user_id) as cnt FROM ' . self::$userTable .
586 ' WHERE room_id = %s AND user_id = %s';
587
588 $types = array('integer', 'integer');
589 $values = array($this->roomId, $chat_userid);
590 $rset = $DIC->database()->queryF($query, $types, $values);
591
592 if ($rset && ($row = $DIC->database()->fetchAssoc($rset)) && $row['cnt'] == 1) {
593 return true;
594 }
595
596 return false;
597 }
598
599 public function isAllowedToEnterPrivateRoom($chat_userid, $proom_id)
600 {
601 global $DIC;
602
603 $query = 'SELECT count(user_id) cnt FROM ' . self::$privateRoomsAccessTable .
604 ' WHERE proom_id = %s AND user_id = %s';
605
606 $types = array('integer', 'integer');
607 $values = array($proom_id, $chat_userid);
608 $rset = $DIC->database()->queryF($query, $types, $values);
609
610 if ($rset && ($row = $DIC->database()->fetchAssoc($rset)) && $row['cnt'] == 1) {
611 return true;
612 }
613
614 $query = 'SELECT count(*) cnt FROM ' . self::$privateRoomsTable .
615 ' WHERE proom_id = %s AND owner = %s';
616
617 $types = array('integer', 'integer');
618 $values = array($proom_id, $chat_userid);
619 $rset = $DIC->database()->queryF($query, $types, $values);
620
621 if ($rset && ($row = $DIC->database()->fetchAssoc($rset)) && $row['cnt'] == 1) {
622 return true;
623 }
624
625 return false;
626 }
627
637 public function getHistory(ilDateTime $from = null, ilDateTime $to = null, $restricted_session_userid = null, $proom_id = 0, $respect_target = true)
638 {
639 global $DIC;
640
641 $join = '';
642
643 if ($proom_id) {
644 $join .=
645 'INNER JOIN ' . self::$privateSessionsTable . ' pSessionTable ' .
646 'ON pSessionTable.user_id = ' . $DIC->database()->quote($restricted_session_userid, 'integer') . ' ' .
647 'AND pSessionTable.proom_id = historyTable.sub_room ' .
648 'AND timestamp >= pSessionTable.connected ' .
649 'AND timestamp <= pSessionTable.disconnected ';
650 }
651
652 $query =
653 'SELECT historyTable.* ' .
654 'FROM ' . self::$historyTable . ' historyTable ' . $join . ' ' .
655 'WHERE historyTable.room_id = ' . $this->getRoomId();
656
657 if ($proom_id !== null) {
658 $query .= ' AND historyTable.sub_room = ' . $DIC->database()->quote($proom_id, 'integer');
659 }
660
661 $filter = array();
662
663 if ($from != null) {
664 $filter[] = 'timestamp >= ' . $DIC->database()->quote($from->getUnixTime(), 'integer');
665 }
666
667 if ($to != null) {
668 $filter[] = 'timestamp <= ' . $DIC->database()->quote($to->getUnixTime(), 'integer');
669 }
670
671 if ($filter) {
672 $query .= ' AND ' . join(' AND ', $filter);
673 }
674 $query .= ' ORDER BY timestamp ASC';
675
676 $rset = $DIC->database()->query($query);
677 $result = array();
678
679 while ($row = $DIC->database()->fetchAssoc($rset)) {
680 $message = json_decode($row['message']);
681 if ($message === null) {
682 $message = json_decode('{}');
683 }
684
685 $row['message'] = $message;
686 $row['message']->timestamp = $row['timestamp'];
687 if (
688 $respect_target &&
689 $row['message']->target !== null &&
690 !$row['message']->target->public &&
691 !in_array($DIC->user()->getId(), explode(',', $row['recipients']))
692 ) {
693 continue;
694 }
695
696 $result[] = $row;
697 }
698 return $result;
699 }
700
705 public function getRoomId()
706 {
707 return $this->roomId;
708 }
709
710 public function getPrivateRoomSessions(ilDateTime $from = null, ilDateTime $to = null, $user_id = 0, $room_id = 0)
711 {
712 global $DIC;
713
714 $query = 'SELECT proom_id, title FROM ' . self::$privateRoomsTable . ' WHERE proom_id IN (
715 SELECT proom_id FROM ' . self::$privateSessionsTable . ' WHERE connected >= %s AND disconnected <= %s AND user_id = %s
716
717 ) AND parent_id = %s';
718
719 $rset = $DIC->database()->queryF($query, array('integer', 'integer', 'integer', 'integer'), array($from->getUnixTime(), $to->getUnixTime(), $user_id, $room_id));
720 $result = array();
721 while ($row = $DIC->database()->fetchAssoc($rset)) {
722 $result[] = $row;
723 }
724 return $result;
725 }
726
733 public function saveFileUploadToDb($user_id, $filename, $type)
734 {
735 global $DIC;
736
737 $upload_id = $DIC->database()->nextId(self::$uploadTable);
738
739 $DIC->database()->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, $actor_id, $comment = '')
759 {
760 global $DIC;
761
762 $DIC->database()->replace(
763 self::$banTable,
764 array(
765 'room_id' => array('integer', $this->roomId),
766 'user_id' => array('integer', $user_id)
767 ),
768 array(
769 'actor_id' => array('integer', $actor_id),
770 'timestamp' => array('integer', time()),
771 'remark' => array('text', $comment)
772 )
773 );
774 }
775
782 public function unbanUser($user_id)
783 {
784 global $DIC;
785
786 if (!is_array($user_id)) {
787 $user_id = array($user_id);
788 }
789
790 $query = 'DELETE FROM ' . self::$banTable . ' WHERE room_id = %s AND ' . $DIC->database()->in('user_id', $user_id, false, 'integer');
791
792 $types = array('integer');
793 $values = array($this->getRoomId());
794
795 return $DIC->database()->manipulateF($query, $types, $values);
796 }
797
804 public function isUserBanned($user_id)
805 {
806 global $DIC;
807
808 $query = 'SELECT COUNT(user_id) cnt FROM ' . self::$banTable . ' WHERE user_id = %s AND room_id = %s';
809
810 $types = array('integer', 'integer');
811 $values = array($user_id, $this->getRoomId());
812
813 $rset = $DIC->database()->queryF($query, $types, $values);
814
815 if ($rset && ($row = $DIC->database()->fetchAssoc($rset)) && $row['cnt']) {
816 return true;
817 }
818
819 return false;
820 }
821
827 public function getBannedUsers()
828 {
829 global $DIC;
830
831 $query = 'SELECT chb.* FROM ' . self::$banTable . ' chb INNER JOIN usr_data ud ON chb.user_id = ud.usr_id WHERE chb.room_id = %s ';
832 $types = array('integer');
833 $values = array($this->getRoomId());
834 $rset = $DIC->database()->queryF($query, $types, $values);
835 $result = array();
836
837 if ($rset) {
838 while ($row = $DIC->database()->fetchAssoc($rset)) {
839 if ($row['user_id'] > 0) {
840 $user = new ilObjUser($row['user_id']);
841 $userdata = array(
842 'user_id' => $user->getId(),
843 'firstname' => $user->getFirstname(),
844 'lastname' => $user->getLastname(),
845 'login' => $user->getLogin(),
846 'timestamp' => $row['timestamp'],
847 'actor_id' => $row['actor_id'],
848 'remark' => $row['remark']
849 );
850
851 $result[] = $userdata;
852 }
853 }
854 }
855
856 return $result;
857 }
858
867 {
868 global $DIC;
869
870 $query = 'SELECT * FROM ' . self::$sessionTable . ' WHERE user_id = ' .
871 $DIC->database()->quote($user->getUserId(), 'integer') .
872 ' ORDER BY connected DESC';
873
874 $DIC->database()->setLimit(1);
875 $rset = $DIC->database()->query($query);
876
877 if ($row = $DIC->database()->fetchAssoc($rset)) {
878 return $row;
879 }
880 }
881
890 {
891 global $DIC;
892
893 $query = 'SELECT * FROM ' . self::$sessionTable
894 . ' WHERE room_id = ' .
895 $DIC->database()->quote($this->getRoomId(), 'integer') .
896 ' ORDER BY connected DESC';
897
898 $rset = $DIC->database()->query($query);
899
900 $result = array();
901
902 while ($row = $DIC->database()->fetchAssoc($rset)) {
903 $result[] = $row;
904 }
905
906 return $result;
907 }
908
910 {
911 global $DIC;
912
913 $nextId = $DIC->database()->nextId(self::$privateRoomsTable);
914 $DIC->database()->insert(
915 self::$privateRoomsTable,
916 array(
917 'proom_id' => array('integer', $nextId),
918 'parent_id' => array('integer', $this->roomId),
919 'title' => array('text', $title),
920 'owner' => array('integer', $owner->getUserId()),
921 'closed' => array('integer', (isset($settings['closed']) ? $settings['closed'] : 0)),
922 'created' => array('integer', (isset($settings['created']) ? $settings['created'] : time())),
923 'is_public' => array('integer', $settings['public']),
924 )
925 );
926
927 return $nextId;
928 }
929
930 public function closePrivateRoom($id)
931 {
932 global $DIC;
933
934 $DIC->database()->manipulateF(
935 'UPDATE ' . self::$privateRoomsTable . ' SET closed = %s WHERE proom_id = %s',
936 array('integer', 'integer'),
937 array(time(), $id)
938 );
939 }
940
941 public function isOwnerOfPrivateRoom($user_id, $proom_id)
942 {
943 global $DIC;
944
945 $query = 'SELECT proom_id FROM ' . self::$privateRoomsTable . ' WHERE proom_id = %s AND owner = %s';
946 $types = array('integer', 'integer');
947 $values = array($proom_id, $user_id);
948
949 $rset = $DIC->database()->queryF($query, $types, $values);
950
951 if ($rset && $DIC->database()->fetchAssoc($rset)) {
952 return true;
953 }
954 return false;
955 }
956
965 public function sendInvitationNotification($gui, $sender, $recipient_id, $subScope = 0, $invitationLink = '')
966 {
967 global $DIC;
968
969 if ($gui && !$invitationLink) {
970 $invitationLink = $this->getChatURL($gui, $subScope);
971 }
972
973 if ($recipient_id > 0 && !in_array(ANONYMOUS_USER_ID, array($recipient_id))) {
974 if (is_numeric($sender) && $sender > 0) {
975 $sender_id = $sender;
980 $public_name = $usr->getPublicName();
981 } elseif ($sender instanceof ilChatroomUser) {
982 if ($sender->getUserId() > 0) {
983 $sender_id = $sender->getUserId();
984 } else {
985 $sender_id = ANONYMOUS_USER_ID;
986 }
987 $public_name = $sender->getUsername();
988 } else {
989 throw new InvalidArgumentException('$sender must be an instance of ilChatroomUser or an id of an ilObjUser instance');
990 }
991
992 $userLang = ilLanguageFactory::_getLanguageOfUser($recipient_id);
993 $userLang->loadLanguageModule('mail');
994 require_once 'Services/Mail/classes/class.ilMail.php';
995 $bodyParams = array(
996 'link' => $invitationLink,
997 'inviter_name' => $public_name,
998 'room_name' => $this->getTitle(),
999 'salutation' => ilMail::getSalutation($recipient_id, $userLang)
1000 );
1001
1002 if ($subScope) {
1003 $bodyParams['room_name'] .= ' - ' . self::lookupPrivateRoomTitle($subScope);
1004 }
1005
1006 require_once 'Services/Notifications/classes/class.ilNotificationConfig.php';
1007 $notification = new ilNotificationConfig('chat_invitation');
1008 $notification->setTitleVar('chat_invitation', $bodyParams, 'chatroom');
1009 $notification->setShortDescriptionVar('chat_invitation_short', $bodyParams, 'chatroom');
1010 $notification->setLongDescriptionVar('chat_invitation_long', $bodyParams, 'chatroom');
1011 $notification->setAutoDisable(false);
1012 $notification->setLink($invitationLink);
1013 $notification->setIconPath('templates/default/images/icon_chtr.svg');
1014 $notification->setValidForSeconds(ilNotificationConfig::TTL_LONG);
1015 $notification->setVisibleForSeconds(ilNotificationConfig::DEFAULT_TTS);
1016
1017 $notification->setHandlerParam('mail.sender', $sender_id);
1018
1019 $notification->notifyByUsers(array($recipient_id));
1020 }
1021 }
1022
1028 public function getChatURL($gui, $scope_id = 0)
1029 {
1030 include_once 'Services/Link/classes/class.ilLink.php';
1031
1032 $url = '';
1033
1034 if (is_object($gui)) {
1035 if ($scope_id) {
1036 $url = ilLink::_getStaticLink($gui->object->getRefId(), $gui->object->getType(), true, '_' . $scope_id);
1037 } else {
1038 $url = ilLink::_getStaticLink($gui->object->getRefId(), $gui->object->getType());
1039 }
1040 }
1041
1042 return $url;
1043 }
1044
1045 public function getTitle()
1046 {
1047 if (!$this->object) {
1048 $this->object = ilObjectFactory::getInstanceByObjId($this->getSetting('object_id'));
1049 }
1050
1051 return $this->object->getTitle();
1052 }
1053
1054 public static function lookupPrivateRoomTitle($proom_id)
1055 {
1056 global $DIC;
1057
1058 $query = 'SELECT title FROM ' . self::$privateRoomsTable . ' WHERE proom_id = %s';
1059 $types = array('integer');
1060 $values = array($proom_id);
1061
1062 $rset = $DIC->database()->queryF($query, $types, $values);
1063
1064 if ($row = $DIC->database()->fetchAssoc($rset)) {
1065 return $row['title'];
1066 }
1067
1068 return 'unkown';
1069 }
1070
1071 public function inviteUserToPrivateRoomByLogin($login, $proom_id)
1072 {
1073 $user_id = ilObjUser::_lookupId($login);
1074 $this->inviteUserToPrivateRoom($user_id, $proom_id);
1075 }
1076
1081 public function inviteUserToPrivateRoom($user_id, $proom_id)
1082 {
1083 global $DIC;
1084
1085 $DIC->database()->replace(self::$privateRoomsAccessTable, array(
1086 'user_id' => array('integer', $user_id),
1087 'proom_id' => array('integer', $proom_id)
1088 ), array());
1089 }
1090
1092 {
1093 global $DIC;
1094
1095 $query = '
1096 SELECT roomtable.title, roomtable.proom_id, accesstable.user_id id, roomtable.owner rowner
1097 FROM ' . self::$privateRoomsTable . ' roomtable
1098 LEFT JOIN ' . self::$privateRoomsAccessTable . ' accesstable
1099 ON roomtable.proom_id = accesstable.proom_id
1100 AND accesstable.user_id = %s
1101 WHERE parent_id = %s
1102 AND (closed = 0 OR closed IS NULL)
1103 AND (accesstable.user_id IS NOT NULL OR roomtable.owner = %s)';
1104 $types = array('integer', 'integer', 'integer');
1105 $values = array($userid, $this->roomId, $userid);
1106 $rset = $DIC->database()->queryF($query, $types, $values);
1107 $rooms = array();
1108
1109 while ($row = $DIC->database()->fetchAssoc($rset)) {
1110 $row['active_users'] = $this->listUsersInPrivateRoom($row['id']);
1111 $row['owner'] = $row['rowner'];
1112 $rooms[$row['proom_id']] = $row;
1113 }
1114
1115 return $rooms;
1116 }
1117
1118 public function listUsersInPrivateRoom($private_room_id)
1119 {
1120 global $DIC;
1121
1122 $query = '
1123 SELECT chatroom_users.user_id FROM ' . self::$privateSessionsTable . '
1124 INNER JOIN chatroom_users ON chatroom_users.user_id = ' . self::$privateSessionsTable . '.user_id WHERE proom_id = %s AND disconnected = 0
1125 ';
1126 $types = array('integer');
1127 $values = array($private_room_id);
1128 $rset = $DIC->database()->queryF($query, $types, $values);
1129
1130 $users = array();
1131
1132 while ($row = $DIC->database()->fetchAssoc($rset)) {
1133 $users[$row['user_id']] = $row['user_id'];
1134 }
1135
1136 return array_values($users);
1137 }
1138
1139 public function subscribeUserToPrivateRoom($room_id, $user_id)
1140 {
1141 global $DIC;
1142
1143 if (!$this->userIsInPrivateRoom($room_id, $user_id)) {
1144 $id = $DIC->database()->nextId(self::$privateSessionsTable);
1145 $DIC->database()->insert(
1146 self::$privateSessionsTable,
1147 array(
1148 'psess_id' => array('integer', $id),
1149 'proom_id' => array('integer', $room_id),
1150 'user_id' => array('integer', $user_id),
1151 'connected' => array('integer', time()),
1152 'disconnected' => array('integer', 0),
1153 )
1154 );
1155 }
1156 }
1157
1158 public function userIsInPrivateRoom($room_id, $user_id)
1159 {
1160 global $DIC;
1161
1162 $query = 'SELECT proom_id id FROM ' . self::$privateSessionsTable . ' WHERE user_id = %s AND proom_id = %s AND disconnected = 0';
1163 $types = array('integer', 'integer');
1164 $values = array($user_id, $room_id);
1165 $rset = $DIC->database()->queryF($query, $types, $values);
1166 if ($DIC->database()->fetchAssoc($rset)) {
1167 return true;
1168 }
1169 return false;
1170 }
1171
1176 public function unsubscribeUserFromPrivateRoom($room_id, $user_id)
1177 {
1178 global $DIC;
1179
1180 $DIC->database()->update(
1181 self::$privateSessionsTable,
1182 array(
1183 'disconnected' => array('integer', time())
1184 ),
1185 array(
1186 'proom_id' => array('integer', $room_id),
1187 'user_id' => array('integer', $user_id)
1188 )
1189 );
1190 }
1191
1192 public function countActiveUsers()
1193 {
1194 global $DIC;
1195
1196 $query = 'SELECT count(user_id) as cnt FROM ' . self::$userTable .
1197 ' WHERE room_id = %s';
1198
1199 $types = array('integer');
1200 $values = array($this->roomId);
1201 $rset = $DIC->database()->queryF($query, $types, $values);
1202
1203 if ($rset && ($row = $DIC->database()->fetchAssoc($rset)) && $row['cnt'] == 1) {
1204 return $row['cnt'];
1205 }
1206
1207 return 0;
1208 }
1209
1210 public function getPrivateRooms()
1211 {
1212 global $DIC;
1213
1214 $query = 'SELECT * FROM ' . self::$privateRoomsTable . ' WHERE parent_id = %s';
1215 $rset = $DIC->database()->queryF($query, array('integer'), array($this->roomId));
1216
1217 $rooms = array();
1218
1219 while ($row = $DIC->database()->fetchAssoc($rset)) {
1220 $rooms[] = $row;
1221 }
1222
1223 return $rooms;
1224 }
1225
1230 public function getPrivilegedUsersForPrivateRoom($subRoomId)
1231 {
1232 global $DIC;
1233
1234 $query = 'SELECT user_id FROM ' . self::$privateRoomsAccessTable . ' WHERE proom_id = %s';
1235 $rset = $DIC->database()->queryF($query, array('integer'), array($subRoomId));
1236
1237 $userIds = array();
1238
1239 while ($row = $DIC->database()->fetchAssoc($rset)) {
1240 $userIds[] = $row['user_id'];
1241 }
1242
1243 return $userIds;
1244 }
1245
1247 {
1248 global $DIC;
1249
1250 $query = 'SELECT title FROM ' . self::$privateRoomsTable . ' WHERE parent_id = %s and closed = 0';
1251 $rset = $DIC->database()->queryF($query, array('integer'), array($this->roomId));
1252
1253 $titles = array();
1254
1255 while ($row = $DIC->database()->fetchAssoc($rset)) {
1256 $titles[] = $row['title'];
1257 }
1258
1259 $suffix = '';
1260 $i = 0;
1261 do {
1262 if (!in_array($title . $suffix, $titles)) {
1263 $title .= $suffix;
1264 break;
1265 }
1266
1267 ++$i;
1268
1269 $suffix = ' (' . $i . ')';
1270 } while (true);
1271
1272 return $title;
1273 }
1274
1280 public function getAccessibleRoomIdByTitleMap($user_id)
1281 {
1282 global $DIC;
1283
1284 $query = "
1285 SELECT room_id, od.title, objr.ref_id
1286 FROM object_data od
1287 INNER JOIN " . self::$settingsTable . "
1288 ON object_id = od.obj_id
1289 INNER JOIN object_reference objr
1290 ON objr.obj_id = od.obj_id
1291 AND objr.deleted IS NULL
1292 INNER JOIN tree
1293 ON tree.child = objr.ref_id
1294 AND tree.tree = %s
1295 WHERE od.type = %s
1296 ";
1297
1298 $types = array('integer', 'text');
1299 $values = array(1, 'chtr');
1300
1301 $res = $DIC->database()->queryF($query, $types, $values);
1302
1303 $rooms = [];
1304
1305 while ($row = $DIC->database()->fetchAssoc($res)) {
1306 if (ilChatroom::checkPermissionsOfUser($user_id, 'read', $row['ref_id'])) {
1307 $rooms[$row['room_id']] = $row['title'];
1308 }
1309 }
1310
1311 return $rooms;
1312 }
1313
1314 public function getPrivateSubRooms($parent_room, $user_id)
1315 {
1316 global $DIC;
1317
1318 $query = "
1319 SELECT proom_id, parent_id
1320 FROM " . self::$privateRoomsTable . "
1321 WHERE parent_id = %s
1322 AND owner = %s
1323 AND closed = 0
1324 ";
1325
1326 $types = array('integer', 'integer');
1327 $values = array($parent_room, $user_id);
1328
1329 $res = $DIC->database()->queryF($query, $types, $values);
1330
1331 $priv_rooms = array();
1332
1333 while ($row = $DIC->database()->fetchAssoc($res)) {
1334 $proom_id = $row['proom_id'];
1335 $priv_rooms[$proom_id] = $row['parent_id'];
1336 }
1337
1338 return $priv_rooms;
1339 }
1340
1346 public function getRefIdByRoomId($room_id)
1347 {
1348 global $DIC;
1349
1350 $query = "
1351 SELECT objr.ref_id
1352 FROM object_reference objr
1353
1354 INNER JOIN chatroom_settings cs
1355 ON cs.object_id = objr.obj_id
1356
1357 INNER JOIN object_data od
1358 ON od.obj_id = cs.object_id
1359
1360 WHERE cs.room_id = %s
1361 ";
1362
1363 $types = array('integer');
1364 $values = array($room_id);
1365
1366 $res = $DIC->database()->queryF($query, $types, $values);
1367
1368 $row = $DIC->database()->fetchAssoc($res);
1369
1370 return $row['ref_id'];
1371 }
1372
1373 public function getLastMessagesForChatViewer($number, $chatuser = null)
1374 {
1375 return $this->getLastMessages($number, $chatuser);
1376 }
1377
1378 public function getLastMessages($number, $chatuser = null)
1379 {
1380 global $DIC;
1381
1382 // There is currently no way to check if a message is private or not
1383 // by sql. So we fetch twice as much as we need and hope that there
1384 // are not more than $number private messages.
1385 $DIC->database()->setLimit($number);
1386 $rset = $DIC->database()->query(
1387 'SELECT *
1388 FROM ' . self::$historyTable . '
1389 WHERE room_id = ' . $DIC->database()->quote($this->roomId, 'integer') . '
1390 AND sub_room = 0
1391 AND (
1392 (' . $DIC->database()->like('message', 'text', '%"type":"message"%') . ' AND NOT ' . $DIC->database()->like('message', 'text', '%"public":0%') . ')
1393 OR ' . $DIC->database()->like('message', 'text', '%"target":{%"id":"' . $chatuser->getUserId() . '"%') . '
1394 OR ' . $DIC->database()->like('message', 'text', '%"from":{"id":' . $chatuser->getUserId() . '%') . '
1395 )
1396 ORDER BY timestamp DESC'
1397 );
1398
1399 $result_count = 0;
1400 $results = array();
1401 while (($row = $DIC->database()->fetchAssoc($rset)) && $result_count < $number) {
1402 $tmp = json_decode($row['message']);
1403 if ($chatuser !== null && $tmp->target != null && $tmp->target->public == 0) {
1404 if ($chatuser->getUserId() == $tmp->target->id || $chatuser->getUserId() == $tmp->from->id) {
1405 $results[] = $tmp;
1406 ++$result_count;
1407 }
1408 } else {
1409 $results[] = $tmp;
1410 ++$result_count;
1411 }
1412 }
1413
1414 $rset = $DIC->database()->query(
1415 'SELECT *
1416 FROM ' . self::$historyTable . '
1417 WHERE room_id = ' . $DIC->database()->quote($this->roomId, 'integer') . '
1418 AND sub_room = 0
1419 AND ' . $DIC->database()->like('message', 'text', '%"type":"notice"%') . '
1420 AND timestamp <= ' . $DIC->database()->quote($results[0]->timestamp, 'integer') . ' AND timestamp >= ' . $DIC->database()->quote($results[$result_count - 1]->timestamp, 'integer') . '
1421
1422 ORDER BY timestamp DESC'
1423 );
1424
1425 while (($row = $DIC->database()->fetchAssoc($rset))) {
1426 $tmp = json_decode($row['message']);
1427 $results[] = $tmp;
1428 }
1429
1430 \usort($results, function ($a, $b) {
1431 $a_timestamp = strlen($a->timestamp) == 13 ? substr($a->timestamp, 0, -3) : $a->timestamp;
1432 $b_timestamp = strlen($b->timestamp) == 13 ? substr($b->timestamp, 0, -3) : $b->timestamp;
1433
1434 return $b_timestamp - $a_timestamp;
1435 });
1436
1437 return $results;
1438 }
1439
1440 public function clearMessages($sub_room)
1441 {
1442 global $DIC;
1443
1444 $DIC->database()->queryF(
1445 'DELETE FROM ' . self::$historyTable . ' WHERE room_id = %s AND sub_room = %s',
1446 array('integer', 'integer'),
1447 array($this->roomId, (int) $sub_room)
1448 );
1449
1450 if ($sub_room) {
1451 $DIC->database()->queryF(
1452 'DELETE FROM ' . self::$privateSessionsTable . ' WHERE proom_id = %s AND disconnected < %s',
1453 array('integer', 'integer'),
1454 array($sub_room, time())
1455 );
1456 } else {
1457 $DIC->database()->queryF(
1458 'DELETE FROM ' . self::$sessionTable . ' WHERE room_id = %s AND disconnected < %s',
1459 array('integer', 'integer'),
1460 array($this->roomId, time())
1461 );
1462 }
1463 }
1464}
$result
$users
Definition: authpage.php:44
$filename
Definition: buildRTE.php:89
$comment
Definition: buildRTE.php:83
foreach($mandatory_scripts as $file) $timestamp
Definition: buildRTE.php:81
An exception for terminatinating execution or to throw for unit testing.
const IL_NO_OBJECT_ACCESS
Class ilChatroomUser.
getUserId()
Returns Ilias User ID.
Class ilChatroom.
getBannedUsers()
Returns an multidimensional array containing userdata from users having an entry in banTable with mat...
getHistory(ilDateTime $from=null, ilDateTime $to=null, $restricted_session_userid=null, $proom_id=0, $respect_target=true)
Returns array containing history data selected from historyTable by given ilDateTime,...
getPrivateRoomSessions(ilDateTime $from=null, ilDateTime $to=null, $user_id=0, $room_id=0)
phpTypeToMDBType($type)
inviteUserToPrivateRoomByLogin($login, $proom_id)
addHistoryEntry($message, $recipient=null, $publicMessage=true)
Inserts entry into historyTable.
isSubscribed($chat_userid)
Returns true if entry exists in userTable matching given $chat_userid and $this->roomId.
getRefIdByRoomId($room_id)
Returns ref_id of given room_id.
saveFileUploadToDb($user_id, $filename, $type)
Saves information about file uploads in DB.
banUser($user_id, $actor_id, $comment='')
Inserts user into banTable, using given $user_id.
initialize(array $rowdata)
Sets $this->roomId by given array $rowdata and calls setSetting method foreach available setting in $...
isUserBanned($user_id)
Returns true if there's an entry in banTable matching roomId and given $user_id.
static $uploadTable
static $privateRoomsTable
addPrivateRoom($title, ilChatroomUser $owner, $settings)
static $sessionTable
saveSettings(array $settings)
Saves settings into settingsTable using given settings array.
static lookupPrivateRoomTitle($proom_id)
static findDeletablePrivateRooms()
connectUser(ilChatroomUser $user)
Connects user by inserting userdata into userTable.
isOwnerOfPrivateRoom($user_id, $proom_id)
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 byObjectId($object_id)
Returns ilChatroom object by given $object_id.
static byRoomId($room_id, $initObject=false)
Returns ilChatroom by given $room_id.
clearMessages($sub_room)
getPrivilegedUsersForPrivateRoom($subRoomId)
getAccessibleRoomIdByTitleMap($user_id)
Fetches and returns a Array<Integer, String> of all accessible repository object chats in the main tr...
save()
Saves settings using $this->settings.
getConnectedUsers($only_data=true)
Returns an array of connected users.
static $historyTable
userIsInPrivateRoom($room_id, $user_id)
static checkUserPermissions($permissions, $ref_id, $send_info=true)
Checks user permissions by given array and ref_id.
disconnectUsers(array $userIds)
Disconnects users by deleting userdata from userTable using given userId array.
getActivePrivateRooms($userid)
subscribeUserToPrivateRoom($room_id, $user_id)
getChatURL($gui, $scope_id=0)
listUsersInPrivateRoom($private_room_id)
getLastMessages($number, $chatuser=null)
static $privateRoomsAccessTable
setSetting($name, $value)
Sets given name and value as setting into $this->settings array.
getRoomId()
Returns roomID from $this->roomId.
unsubscribeUserFromPrivateRoom($room_id, $user_id)
getUniquePrivateRoomTitle($title)
getPrivateSubRooms($parent_room, $user_id)
disconnectUser($user_id)
Creates userId array by given $user object and calls disconnectUsers method.
static checkPermissions($usrId, $refId, array $permissions)
unbanUser($user_id)
Deletes entry from banTable matching roomId and given $user_id and returns true if sucessful.
getSettings()
Returns $this->settings array.
getSetting($name)
Returns setting from $this->settings array by given name.
static $settingsTable
static getUntrashedChatReferences($filter=array())
getSessions(ilChatroomUser $user)
Returns all session from user Returns all from sessionTable where user_id matches userId from given $...
static $privateSessionsTable
static disconnectAllUsersFromAllRooms()
Deletes all entrys from userTable.
isAllowedToEnterPrivateRoom($chat_userid, $proom_id)
getLastSession(ilChatroomUser $user)
Returns last session from user.
getLastMessagesForChatViewer($number, $chatuser=null)
inviteUserToPrivateRoom($user_id, $proom_id)
@classDescription Date and time handling
static _getLanguageOfUser($a_usr_id)
Get language object of user.
static getSalutation($a_usr_id, ilLanguage $a_language=null)
Describes a notification and provides methods for publishing this notification.
static isActivated($refId, $objId, &$a_visible_flag=null)
static _lookupId($a_user_str)
Lookup id by login.
static getInstanceByObjId($a_obj_id, $stop_on_error=true)
get an instance of an Ilias object by object id
static _lookupObjId($a_id)
static sendFailure($a_info="", $a_keep=false)
Send Failure Message to Screen.
if(empty($userids)) $userid
$login
Definition: cron.php:13
$i
Definition: disco.tpl.php:19
if(!array_key_exists('StateId', $_REQUEST)) $id
catch(Exception $e) $message
$user
Definition: migrateto20.php:57
$row
$GLOBALS['JPEG_Segment_Names']
Global Variable: XMP_tag_captions.
$query
$type
$url
global $DIC
Definition: saml.php:7
foreach($_POST as $key=> $value) $res
settings()
Definition: settings.php:2
$results
Definition: svg-scanner.php:47
$from
$values