4 require_once
'Services/Object/classes/class.ilObject.php';
5 require_once
'Modules/Forum/classes/class.ilForum.php';
6 require_once
'Modules/Forum/classes/class.ilFileDataForum.php';
7 require_once
'Modules/Forum/classes/class.ilForumProperties.php';
59 public function __construct($a_id = 0, $a_call_by_reference =
true)
70 $new_deadline = time() - 60 * 60 * 24 * 7 * ($this->ilias->getSetting(
'frm_store_new') ?
71 $this->ilias->getSetting(
'frm_store_new') :
73 define(
'NEW_DEADLINE', $new_deadline);
86 require_once(
"./Modules/File/classes/class.ilObjFileAccess.php");
87 return ilObjForumAccess::_lookupDiskUsage($this->
id);
90 public static function _lookupThreadSubject($a_thread_id)
98 $res = $ilDB->queryf(
'
99 SELECT thr_subject FROM frm_threads WHERE thr_pk = %s',
100 array(
'integer'), array($a_thread_id));
102 while(
$row = $ilDB->fetchObject(
$res))
104 return $row->thr_subject;
110 public function getCountUnread($a_usr_id, $a_thread_id = 0)
118 $a_frm_id = $this->
getId();
125 $ilBench->start(
"Forum",
'getCountRead');
129 $res = $ilDB->queryf(
'
130 SELECT top_pk FROM frm_data WHERE top_frm_fk = %s',
131 array(
'integer'), array($a_frm_id));
134 while(
$row = $ilDB->fetchObject(
$res))
136 $topic_id =
$row->top_pk;
140 $res = $ilDB->queryf(
'
141 SELECT COUNT(pos_pk) num_posts FROM frm_posts
142 WHERE pos_top_fk = %s',
143 array(
'integer'), array($topic_id));
145 while(
$row = $ilDB->fetchObject(
$res))
147 $num_posts =
$row->num_posts;
150 $res = $ilDB->queryf(
'
151 SELECT COUNT(post_id) count_read FROM frm_user_read
154 array(
'integer',
'integer'), array($a_frm_id, $a_usr_id));
156 while(
$row = $ilDB->fetchObject(
$res))
158 $count_read =
$row->count_read;
160 $unread = $num_posts - $count_read;
162 $ilBench->stop(
"Forum",
'getCountRead');
163 return $unread > 0 ? $unread : 0;
167 $res = $ilDB->queryf(
'
168 SELECT COUNT(pos_pk) num_posts FROM frm_posts
169 WHERE pos_thr_fk = %s',
170 array(
'integer'), array($a_thread_id));
173 $num_posts =
$row->num_posts;
175 $res = $ilDB->queryf(
'
176 SELECT COUNT(post_id) count_read FROM frm_user_read
180 array(
'integer',
'integer',
'integer'), array($a_frm_id, $a_frm_id, $a_thread_id));
183 $count_read =
$row->count_read;
185 $unread = $num_posts - $count_read;
187 $ilBench->stop(
"Forum",
'getCountRead');
188 return $unread > 0 ? $unread : 0;
190 $ilBench->stop(
"Forum",
'getCountRead');
195 public function markThreadRead($a_usr_id, $a_thread_id)
203 $res = $ilDB->queryf(
'
204 SELECT * FROM frm_posts WHERE pos_thr_fk = %s',
205 array(
'integer'), array($a_thread_id));
207 while(
$row = $ilDB->fetchObject(
$res))
209 $this->markPostRead($a_usr_id, $a_thread_id,
$row->pos_pk);
214 public function markAllThreadsRead($a_usr_id)
221 $res = $ilDB->queryf(
'
222 SELECT * FROM frm_data, frm_threads
223 WHERE top_frm_fk = %s
224 AND top_pk = thr_top_fk',
225 array(
'integer'), array($this->
getId()));
227 while(
$row = $ilDB->fetchObject(
$res))
229 $this->markThreadRead($a_usr_id,
$row->thr_pk);
236 public function markPostRead($a_usr_id, $a_thread_id, $a_post_id)
244 $res = $ilDB->queryf(
'
245 SELECT * FROM frm_user_read
250 array(
'integer',
'integer',
'integer',
'integer'),
251 array($a_usr_id, $this->
getId(), $a_thread_id, $a_post_id));
253 if($ilDB->numRows(
$res))
258 $res = $ilDB->manipulateF(
'
259 INSERT INTO frm_user_read
265 VALUES (%s,%s,%s,%s)',
266 array(
'integer',
'integer',
'integer',
'integer'),
267 array($a_usr_id, $this->
getId(), $a_thread_id, $a_post_id));
272 public function markPostUnread($a_user_id, $a_post_id)
279 $res = $ilDB->manipulateF(
'
280 DELETE FROM frm_user_read
283 array(
'integer',
'integer'),
284 array($a_user_id, $a_post_id));
287 public function isRead($a_usr_id, $a_post_id)
294 $res = $ilDB->queryf(
'
295 SELECT * FROM frm_user_read
298 array(
'integer',
'integer'),
299 array($a_usr_id, $a_post_id));
301 return $ilDB->numRows(
$res) ?
true :
false;
304 public function updateLastAccess($a_usr_id, $a_thread_id)
311 $res = $ilDB->queryf(
'
312 SELECT * FROM frm_thread_access
316 array(
'integer',
'integer',
'integer'),
317 array($a_usr_id, $this->
getId(), $a_thread_id));
319 if($ilDB->numRows(
$res))
322 UPDATE frm_thread_access
327 array(
'integer',
'integer',
'integer',
'integer'),
328 array(time(), $a_usr_id, $this->
getId(), $a_thread_id));
334 INSERT INTO frm_thread_access
340 VALUES (%s,%s,%s,%s,%s)',
341 array(
'integer',
'integer',
'integer',
'integer',
'integer'),
342 array(time(),
'0', $a_usr_id, $this->
getId(), $a_thread_id));
353 public static function _updateOldAccess($a_usr_id)
362 UPDATE frm_thread_access
363 SET access_old = access_last
365 array(
'integer'), array($a_usr_id));
367 $set = $ilDB->query(
"SELECT * FROM frm_thread_access " .
368 " WHERE usr_id = " . $ilDB->quote($a_usr_id,
"integer")
370 while($rec = $ilDB->fetchAssoc($set))
372 $ilDB->manipulate(
"UPDATE frm_thread_access SET " .
373 " access_old_ts = " . $ilDB->quote(date(
'Y-m-d H:i:s', $rec[
"access_old"]),
"timestamp") .
374 " WHERE usr_id = " . $ilDB->quote($rec[
"usr_id"],
"integer") .
375 " AND obj_id = " . $ilDB->quote($rec[
"obj_id"],
"integer") .
376 " AND thread_id = " . $ilDB->quote($rec[
"thread_id"],
"integer")
380 $new_deadline = time() - 60 * 60 * 24 * 7 * ($ilias->getSetting(
'frm_store_new') ?
381 $ilias->getSetting(
'frm_store_new') :
385 DELETE FROM frm_thread_access WHERE access_last < %s',
386 array(
'integer'), array($new_deadline));
389 function _deleteUser($a_usr_id)
396 $data = array($a_usr_id);
398 $res = $ilDB->manipulateF(
'
399 DELETE FROM frm_user_read WHERE usr_id = %s',
400 array(
'integer'),
$data
403 $res = $ilDB->manipulateF(
'
404 DELETE FROM frm_thread_access WHERE usr_id = %s',
405 array(
'integer'),
$data
410 DELETE FROM frm_notification WHERE user_id = %s',
411 array(
'integer'),
$data);
417 function _deleteReadEntries($a_post_id)
424 $statement = $ilDB->manipulateF(
'
425 DELETE FROM frm_user_read WHERE post_id = %s',
426 array(
'integer'), array($a_post_id));
431 function _deleteAccessEntries($a_thread_id)
438 $statement = $ilDB->manipulateF(
'
439 DELETE FROM frm_thread_access WHERE thread_id = %s',
440 array(
'integer'), array($a_thread_id));
459 $statement = $ilDB->manipulateF(
'
462 top_description = %s,
465 WHERE top_frm_fk =%s',
466 array(
'text',
'text',
'timestamp',
'integer',
'integer'),
487 public function cloneObject($a_target_id, $a_copy_id = 0)
495 $this->cloneAutoGeneratedRoles($new_obj);
498 $this->Forum->setMDB2WhereCondition(
'top_frm_fk = %s ', array(
'integer'), array($this->
getId()));
500 $topData = $this->Forum->getOneTopic();
502 $nextId = $ilDB->nextId(
'frm_data');
504 $statement = $ilDB->insert(
'frm_data', array(
505 'top_pk' => array(
'integer', $nextId),
506 'top_frm_fk' => array(
'integer', $new_obj->getId()),
507 'top_name' => array(
'text', $topData[
'top_name']),
508 'top_description' => array(
'text', $topData[
'top_description']),
509 'top_num_posts' => array(
'integer', $topData[
'top_num_posts']),
510 'top_num_threads' => array(
'integer', $topData[
'top_num_threads']),
511 'top_last_post' => array(
'text', $topData[
'top_last_post']),
512 'top_mods' => array(
'integer', !is_numeric($topData[
'top_mods']) ? 0 : $topData[
'top_mods']),
513 'top_date' => array(
'timestamp', $topData[
'top_date']),
514 'visits' => array(
'integer', $topData[
'visits']),
515 'top_update' => array(
'timestamp', $topData[
'top_update']),
516 'update_user' => array(
'integer', $topData[
'update_user']),
517 'top_usr_id' => array(
'integer', $topData[
'top_usr_id'])
521 include_once(
'Services/CopyWizard/classes/class.ilCopyWizardOptions.php');
524 $options = $cwo->getOptions($this->
getRefId());
526 $options[
'threads'] = $this->Forum->_getThreads($this->
getId());
529 include_once(
'Modules/Forum/classes/class.ilFileDataForum.php');
531 $new_frm = $new_obj->Forum;
532 $new_frm->setMDB2WhereCondition(
'top_frm_fk = %s ', array(
'integer'), array($new_obj->getId()));
534 $new_frm->setForumId($new_obj->getId());
535 $new_frm->setForumRefId($new_obj->getRefId());
537 $new_topic = $new_frm->getOneTopic();
538 foreach($options[
'threads'] as $thread_id=> $thread_subject)
540 $this->Forum->setMDB2WhereCondition(
'thr_pk = %s ', array(
'integer'), array($thread_id));
542 $old_thread = $this->Forum->getOneThread();
544 $old_post_id = $this->Forum->getFirstPostByThread($old_thread[
'thr_pk']);
545 $old_post = $this->Forum->getOnePost($old_post_id);
548 $new_post = $new_frm->generateThread($new_topic[
'top_pk'],
549 $old_thread[
'thr_usr_id'],
550 $old_thread[
'thr_subject'],
554 $old_thread[
'thr_usr_alias'],
555 $old_thread[
'thr_date']);
558 $old_forum_files->ilClone($new_obj->getId(), $new_post);
570 public function cloneAutoGeneratedRoles($new_obj)
576 global
$ilLog, $rbacadmin, $rbacreview;
578 $moderator = ilObjForum::_lookupModeratorRole($this->
getRefId());
579 $new_moderator = ilObjForum::_lookupModeratorRole($new_obj->getRefId());
580 $source_rolf = $rbacreview->getRoleFolderIdOfObject($this->
getRefId());
581 $target_rolf = $rbacreview->getRoleFolderIdOfObject($new_obj->getRefId());
583 if(!$moderator || !$new_moderator || !$source_rolf || !$target_rolf)
585 $ilLog->write(__METHOD__ .
' : Error cloning auto generated role: il_frm_moderator');
587 $rbacadmin->copyRolePermissions($moderator, $source_rolf, $target_rolf, $new_moderator,
true);
588 $ilLog->write(__METHOD__ .
' : Finished copying of role il_frm_moderator.');
590 include_once
'./Modules/Forum/classes/class.ilForumModerators.php';
594 $old_mods = $obj_mods->getCurrentModerators();
596 foreach($old_mods as $user_id)
598 $rbacadmin->assignUser($new_moderator, $user_id);
607 public function delete()
615 if(!parent::delete())
622 $tmp_file_obj->delete();
623 unset($tmp_file_obj);
625 $this->Forum->setMDB2WhereCondition(
'top_frm_fk = %s ', array(
'integer'), array($this->
getId()));
627 $topData = $this->Forum->getOneTopic();
629 $threads = $this->Forum->getAllThreads($topData[
'top_pk']);
630 foreach($threads[
'items'] as $thread)
632 $data = array($thread->getId());
635 $statement = $ilDB->manipulateF(
'
636 DELETE FROM frm_posts_tree WHERE thr_fk = %s',
637 array(
'integer'),
$data);
640 $statement = $ilDB->manipulateF(
'
641 DELETE FROM frm_posts WHERE pos_thr_fk = %s',
642 array(
'integer'),
$data);
645 $statement = $ilDB->manipulateF(
'
646 DELETE FROM frm_threads WHERE thr_pk = %s',
647 array(
'integer'),
$data);
653 $statement = $ilDB->manipulateF(
'
654 DELETE FROM frm_data WHERE top_frm_fk = %s',
655 array(
'integer'),
$data);
658 $statement = $ilDB->manipulateF(
'
659 DELETE FROM frm_settings WHERE obj_id = %s',
660 array(
'integer'),
$data);
663 $statement = $ilDB->manipulateF(
'
664 DELETE FROM frm_user_read WHERE obj_id = %s',
665 array(
'integer'),
$data);
668 $statement = $ilDB->manipulateF(
'
669 DELETE FROM frm_thread_access WHERE obj_id = %s',
670 array(
'integer'),
$data);
674 DELETE FROM frm_notification WHERE frm_id = %s',
675 array(
'integer'),
$data);
692 global $rbacadmin, $rbacreview, $ilDB;
698 $role_obj = $rolf_obj->createRole(
"il_frm_moderator_" . $this->
getRefId(),
"Moderator of forum obj_no." . $this->
getId());
699 $roles[] = $role_obj->getId();
702 $statement = $ilDB->queryf(
'
703 SELECT obj_id FROM object_data
706 array(
'text',
'text'),
707 array(
'rolt',
'il_frm_moderator'));
709 $res = $ilDB->fetchObject($statement);
711 $rbacadmin->copyRoleTemplatePermissions(
$res->obj_id, ROLE_FOLDER_ID, $rolf_obj->getRefId(), $role_obj->getId());
714 $ops = $rbacreview->getOperationsOfRole($role_obj->getId(),
"frm", $rolf_obj->getRefId());
715 $rbacadmin->grantPermission($role_obj->getId(), $ops, $this->
getRefId());
717 return $roles ? $roles : array();
727 public static function _lookupModeratorRole($a_ref_id)
734 $mod_title =
'il_frm_moderator_' . $a_ref_id;
736 $res = $ilDB->queryf(
'
737 SELECT * FROM object_data WHERE title = %s',
738 array(
'text'), array($mod_title));
740 while(
$row = $ilDB->fetchObject(
$res))
751 include_once(
"./Services/News/classes/class.ilNewsItem.php");
753 if($default_visibility ==
"public")
761 public function saveData($a_roles = array())
769 $nextId = $ilDB->nextId(
'frm_data');
772 'top_frm_fk' => $this->
getId(),
775 'top_num_posts' => 0,
776 'top_num_threads' => 0,
777 'top_last_post' => NULL,
778 'top_mods' => !is_numeric($a_roles[0]) ? 0 : $a_roles[0],
779 'top_usr_id' => $ilUser->getId(),
783 $statement = $ilDB->manipulateF(
'
797 VALUES(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)',
798 array(
'integer',
'integer',
'text',
'text',
'integer',
'integer',
'text',
'integer',
'timestamp',
'integer'),
801 $top_data[
'top_frm_fk'],
802 $top_data[
'top_name'],
803 $top_data[
'top_description'],
804 $top_data[
'top_num_posts'],
805 $top_data[
'top_num_threads'],
806 $top_data[
'top_last_post'],
807 $top_data[
'top_mods'],
808 $top_data[
'top_date'],
809 $top_data[
'top_usr_id']
820 if(array_key_exists($obj_id, self::$obj_id_to_forum_id_cache))
822 return (
int)self::$obj_id_to_forum_id_cache[$obj_id];
825 self::preloadForumIdsByObjIds(array($obj_id));
827 return (
int)self::$obj_id_to_forum_id_cache[$obj_id];
837 if(array_key_exists(
$ref_id, self::$ref_id_to_forum_id_cache))
839 return (
int)self::$ref_id_to_forum_id_cache[
$ref_id];
842 self::preloadForumIdsByRefIds(array(
$ref_id));
844 return (
int)self::$ref_id_to_forum_id_cache[
$ref_id];
851 public static function preloadForumIdsByObjIds(array $obj_ids)
858 if(count($obj_ids) == 1)
860 $in =
" objr.obj_id = " . $ilDB->quote(current($obj_ids),
'integer') .
" ";
864 $in = $ilDB->in(
'objr.obj_id', $obj_ids,
false,
'integer');
867 SELECT frmd.top_pk, objr.ref_id, objr.obj_id
868 FROM object_reference objr
869 INNER JOIN frm_data frmd ON frmd.top_frm_fk = objr.obj_id
875 foreach($obj_ids as $obj_id)
877 self::$obj_id_to_forum_id_cache[$obj_id] = null;
880 while(
$row = $ilDB->fetchAssoc(
$res))
882 self::$obj_id_to_forum_id_cache[
$row[
'obj_id']] = $row[
'top_pk'];
883 self::$ref_id_to_forum_id_cache[$row[
'ref_id']] = $row[
'top_pk'];
891 public static function preloadForumIdsByRefIds(array $ref_ids)
898 if(count($ref_ids) == 1)
900 $in =
" objr.ref_id = " . $ilDB->quote(current($ref_ids),
'integer') .
" ";
904 $in = $ilDB->in(
'objr.ref_id', $ref_ids,
false,
'integer');
907 SELECT frmd.top_pk, objr.ref_id, objr.obj_id
908 FROM object_reference objr
909 INNER JOIN frm_data frmd ON frmd.top_frm_fk = objr.obj_id
917 self::$ref_id_to_forum_id_cache[
$ref_id] = null;
920 while(
$row = $ilDB->fetchAssoc(
$res))
922 self::$obj_id_to_forum_id_cache[
$row[
'obj_id']] = $row[
'top_pk'];
923 self::$ref_id_to_forum_id_cache[$row[
'ref_id']] = $row[
'top_pk'];
932 public static function lookupStatisticsByRefId($ref_id)
942 if(isset(self::$forum_statistics_cache[$ref_id]))
944 return self::$forum_statistics_cache[
$ref_id];
949 'num_unread_posts' => 0,
956 self::$forum_statistics_cache[
$ref_id] = $statistics;
957 return self::$forum_statistics_cache[
$ref_id];
961 if(!$ilAccess->checkAccess(
'moderate_frm',
'', $ref_id))
963 $act_clause .=
" AND (frm_posts.pos_status = " . $ilDB->quote(1,
"integer") .
" OR frm_posts.pos_usr_id = " . $ilDB->quote($ilUser->getId(),
"integer") .
") ";
966 $new_deadline = date(
'Y-m-d H:i:s', time() - 60 * 60 * 24 * 7 * ($ilSetting->get(
'frm_store_new') ? $ilSetting->get(
'frm_store_new') : 8));
968 if(!$ilUser->isAnonymous())
971 (SELECT COUNT(frm_posts.pos_pk) cnt
973 INNER JOIN frm_threads ON frm_posts.pos_thr_fk = frm_threads.thr_pk
974 WHERE frm_threads.thr_top_fk = %s $act_clause)
978 (SELECT COUNT(DISTINCT(frm_user_read.post_id)) cnt
980 INNER JOIN frm_posts ON frm_user_read.post_id = frm_posts.pos_pk
981 INNER JOIN frm_threads ON frm_threads.thr_pk = frm_posts.pos_thr_fk
982 WHERE frm_user_read.usr_id = %s AND frm_posts.pos_top_fk = %s $act_clause)
986 (SELECT COUNT(frm_posts.pos_pk) cnt
988 LEFT JOIN frm_user_read ON (post_id = frm_posts.pos_pk AND frm_user_read.usr_id = %s)
989 LEFT JOIN frm_thread_access ON (frm_thread_access.thread_id = frm_posts.pos_thr_fk AND frm_thread_access.usr_id = %s)
990 WHERE frm_posts.pos_top_fk = %s
991 AND ((frm_posts.pos_date > frm_thread_access.access_old_ts OR frm_posts.pos_update > frm_thread_access.access_old_ts)
992 OR (frm_thread_access.access_old IS NULL AND (frm_posts.pos_date > %s OR frm_posts.pos_update > %s)))
993 AND frm_posts.pos_usr_id != %s
994 AND frm_user_read.usr_id IS NULL $act_clause)
996 $types = array(
'integer',
'integer',
'integer',
'integer',
'integer',
'integer',
'timestamp',
'timestamp',
'integer');
997 $values = array($forumId, $ilUser->getId(), $forumId, $ilUser->getId(), $ilUser->getId(), $forumId, $new_deadline, $new_deadline, $ilUser->getId());
998 $mapping = array_keys($statistics);
999 $res = $ilDB->queryF(
1004 for($i = 0; $i <= 2; $i++)
1008 $statistics[$mapping[$i]] = (int)
$row[
'cnt'];
1013 $statistics[$mapping[$i]] = $statistics[$mapping[$i - 1]] - $statistics[$mapping[$i]];
1020 SELECT COUNT(frm_posts.pos_pk) cnt
1022 INNER JOIN frm_threads ON frm_posts.pos_thr_fk = frm_threads.thr_pk
1023 WHERE frm_threads.thr_top_fk = %s $act_clause
1025 $types = array(
'integer');
1026 $values = array($forumId);
1027 $res = $ilDB->queryF(
1034 $statistics = array(
1035 'num_posts' =>
$row[
'cnt'],
1036 'num_unread_posts' =>
$row[
'cnt'],
1037 'num_new_posts' =>
$row[
'cnt']
1041 self::$forum_statistics_cache[
$ref_id] = $statistics;
1043 return self::$forum_statistics_cache[
$ref_id];
1051 public static function lookupLastPostByRefId($ref_id)
1058 global $ilAccess,
$ilUser, $ilDB;
1060 if(isset(self::$forum_last_post_cache[$ref_id]))
1062 return self::$forum_last_post_cache[
$ref_id];
1068 self::$forum_last_post_cache[
$ref_id] = array();
1069 return self::$forum_last_post_cache[
$ref_id];
1073 if(!$ilAccess->checkAccess(
'moderate_frm',
'', $ref_id))
1075 $act_clause .=
" AND (frm_posts.pos_status = " . $ilDB->quote(1,
"integer") .
" OR frm_posts.pos_usr_id = " . $ilDB->quote($ilUser->getId(),
"integer") .
") ";
1078 $ilDB->setLimit(1, 0);
1082 WHERE pos_top_fk = %s $act_clause
1083 ORDER BY pos_date DESC
1085 $res = $ilDB->queryF(
1095 return self::$forum_last_post_cache[
$ref_id];
1104 public static function getUserIdsOfLastPostsByRefIdAndThreadIds($ref_id, array $thread_ids)
1111 global
$ilUser, $ilAccess, $ilDB;
1114 $act_inner_clause =
'';
1115 if(!$ilAccess->checkAccess(
'moderate_frm',
'', $ref_id))
1117 $act_clause .=
" AND (t1.pos_status = " . $ilDB->quote(1,
"integer") .
" OR t1.pos_usr_id = " . $ilDB->quote($ilUser->getId(),
"integer") .
") ";
1118 $act_inner_clause .=
" AND (t3.pos_status = " . $ilDB->quote(1,
"integer") .
" OR t3.pos_usr_id = " . $ilDB->quote($ilUser->getId(),
"integer") .
") ";
1121 $in = $ilDB->in(
"t1.pos_thr_fk", $thread_ids,
false,
'integer');
1122 $inner_in = $ilDB->in(
"t3.pos_thr_fk", $thread_ids,
false,
'integer');
1125 SELECT t1.pos_usr_id, t1.update_user
1128 SELECT t3.pos_thr_fk, MAX(t3.pos_date) pos_date
1130 WHERE $inner_in $act_inner_clause
1131 GROUP BY t3.pos_thr_fk
1132 ) t2 ON t2.pos_thr_fk = t1.pos_thr_fk AND t2.pos_date = t1.pos_date
1133 WHERE $in $act_clause
1139 while(
$row = $ilDB->fetchAssoc(
$res))
1141 if((
int)
$row[
'pos_usr_id'])
1143 $usr_ids[] = (int)
$row[
'pos_usr_id'];
1145 if((
int)
$row[
'update_user'])
1147 $usr_ids[] = (int)
$row[
'update_user'];
1151 return array_unique($usr_ids);