ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
class.ilObjForum.php
Go to the documentation of this file.
1<?php
2/* Copyright (c) 1998-2012 ILIAS open source, Extended GPL, see docs/LICENSE */
3
13class ilObjForum extends ilObject
14{
20 public $Forum;
21
22 // private $objProperties = null;
23
28 protected static $obj_id_to_forum_id_cache = array();
29
34 protected static $ref_id_to_forum_id_cache = array();
35
40 protected static $forum_statistics_cache = array();
41
46 protected static $forum_last_post_cache = array();
47
48 private $settings;
49 private $rbac;
50 private $ilBench;
51 private $user;
52 private $logger;
53
60 public function __construct($a_id = 0, $a_call_by_reference = true)
61 {
62 global $DIC;
63 $this->settings = $DIC->settings();
64 $this->rbac = $DIC->rbac();
65 $this->db = $DIC->database();
66 $this->ilBench = $DIC['ilBench'];
67 $this->user = $DIC->user();
68 $this->logger = $DIC->logger()->root();
69
70 $this->type = 'frm';
71 parent::__construct($a_id, $a_call_by_reference);
72
73 /*
74 * this constant is used for the information if a single post is marked as new
75 * All threads/posts created before this date are never marked as new
76 * Default is 8 weeks
77 *
78 */
79 $new_deadline = time() - 60 * 60 * 24 * 7 * ($this->settings->get('frm_store_new') ?
80 $this->settings->get('frm_store_new') :
81 8);
82 define('NEW_DEADLINE', $new_deadline);
83
84 // TODO: needs to rewrite scripts that are using Forum outside this class
85 $this->Forum = new ilForum();
86 }
87
91 public function create()
92 {
93 $id = parent::create();
94
95 $properties = ilForumProperties::getInstance($this->getId());
96 $properties->setDefaultView(1);
97 $properties->setAnonymisation(0);
98 $properties->setStatisticsStatus(0);
99 $properties->setPostActivation(0);
100 $properties->setThreadSorting(0);
101 $properties->insert();
102
103 $this->createSettings();
104
105 $this->saveData();
106
107 return $id;
108 }
109
113 public function setPermissions($a_ref_id)
114 {
115 parent::setPermissions($a_ref_id);
116
117 // ...finally assign moderator role to creator of forum object
118 $roles = array(ilObjForum::_lookupModeratorRole($this->getRefId()));
119 $this->rbac->admin()->assignUser($roles[0], $this->getOwner(), 'n');
120 $this->updateModeratorRole($roles[0]);
121 }
122
126 public function updateModeratorRole($role_id)
127 {
128 $this->db->manipulate('UPDATE frm_data SET top_mods = ' . $this->db->quote($role_id, 'integer') . ' WHERE top_frm_fk = ' . $this->db->quote($this->getId(), 'integer'));
129 }
130
136 public function getDiskUsage()
137 {
138 return ilObjForumAccess::_lookupDiskUsage($this->id);
139 }
140
141 public static function _lookupThreadSubject($a_thread_id)
142 {
143 global $DIC;
144 $ilDB = $DIC->database();
145
146 $res = $ilDB->queryf(
147 '
148 SELECT thr_subject FROM frm_threads WHERE thr_pk = %s',
149 array('integer'),
150 array($a_thread_id)
151 );
152
153 while ($row = $ilDB->fetchObject($res)) {
154 return $row->thr_subject;
155 }
156 return '';
157 }
158
159 // METHODS FOR UN-READ STATUS
160 public function getCountUnread($a_usr_id, $a_thread_id = 0, $ignoreRoot = false)
161 {
162 $a_frm_id = $this->getId();
163
164 $this->ilBench->start("Forum", 'getCountRead');
165 if (!$a_thread_id) {
166 // Get topic_id
167 $res = $this->db->queryf(
168 '
169 SELECT top_pk FROM frm_data WHERE top_frm_fk = %s',
170 array('integer'),
171 array($a_frm_id)
172 );
173
174
175 while ($row = $this->db->fetchObject($res)) {
176 $topic_id = $row->top_pk;
177 }
178
179 // Get number of posts
180 $res = $this->db->queryf(
181 '
182 SELECT COUNT(pos_pk) num_posts
183 FROM frm_posts
184 LEFT JOIN frm_posts_tree ON frm_posts_tree.pos_fk = pos_pk
185 WHERE pos_top_fk = %s' . ($ignoreRoot ? ' AND parent_pos != 0 ' : ''),
186 array('integer'),
187 array($topic_id)
188 );
189
190 while ($row = $this->db->fetchObject($res)) {
191 $num_posts = $row->num_posts;
192 }
193
194 $res = $this->db->queryf(
195 '
196 SELECT COUNT(post_id) count_read FROM frm_user_read
197 WHERE obj_id = %s
198 AND usr_id = %s',
199 array('integer', 'integer'),
200 array($a_frm_id, $a_usr_id)
201 );
202
203 while ($row = $this->db->fetchObject($res)) {
204 $count_read = $row->count_read;
205 }
206 $unread = $num_posts - $count_read;
207
208 $this->ilBench->stop("Forum", 'getCountRead');
209 return $unread > 0 ? $unread : 0;
210 } else {
211 $res = $this->db->queryf(
212 '
213 SELECT COUNT(pos_pk) num_posts FROM frm_posts
214 LEFT JOIN frm_posts_tree ON frm_posts_tree.pos_fk = pos_pk
215 WHERE pos_thr_fk = %s' . ($ignoreRoot ? ' AND parent_pos != 0 ' : ''),
216 array('integer'),
217 array($a_thread_id)
218 );
219
220 $row = $this->db->fetchObject($res);
221 $num_posts = $row->num_posts;
222
223 $res = $this->db->queryf(
224 '
225 SELECT COUNT(post_id) count_read FROM frm_user_read
226 WHERE obj_id = %s
227 AND usr_id = %s
228 AND thread_id = %s',
229 array('integer', 'integer', 'integer'),
230 array($a_frm_id, $a_frm_id, $a_thread_id)
231 );
232
233 $row = $this->db->fetchObject($res);
234 $count_read = $row->count_read;
235
236 $unread = $num_posts - $count_read;
237
238 $this->ilBench->stop("Forum", 'getCountRead');
239 return $unread > 0 ? $unread : 0;
240 }
241 $this->ilBench->stop("Forum", 'getCountRead');
242 return false;
243 }
244
245
246 public function markThreadRead($a_usr_id, $a_thread_id)
247 {
248 // Get all post ids
249 $res = $this->db->queryf(
250 '
251 SELECT * FROM frm_posts WHERE pos_thr_fk = %s',
252 array('integer'),
253 array($a_thread_id)
254 );
255
256 while ($row = $this->db->fetchObject($res)) {
257 $this->markPostRead($a_usr_id, $a_thread_id, $row->pos_pk);
258 }
259 return true;
260 }
261
262 public function markAllThreadsRead($a_usr_id)
263 {
264 $res = $this->db->queryf(
265 '
266 SELECT * FROM frm_data, frm_threads
267 WHERE top_frm_fk = %s
268 AND top_pk = thr_top_fk',
269 array('integer'),
270 array($this->getId())
271 );
272
273 while ($row = $this->db->fetchObject($res)) {
274 $this->markThreadRead($a_usr_id, $row->thr_pk);
275 }
276
277 return true;
278 }
279
280
281 public function markPostRead($a_usr_id, $a_thread_id, $a_post_id)
282 {
283 // CHECK IF ENTRY EXISTS
284 $res = $this->db->queryf(
285 '
286 SELECT * FROM frm_user_read
287 WHERE usr_id = %s
288 AND obj_id = %s
289 AND thread_id = %s
290 AND post_id = %s',
291 array('integer', 'integer', 'integer', 'integer'),
292 array($a_usr_id, $this->getId(), $a_thread_id, $a_post_id)
293 );
294
295 if ($this->db->numRows($res)) {
296 return true;
297 }
298
299 $this->db->manipulateF(
300 '
301 INSERT INTO frm_user_read
302 ( usr_id,
303 obj_id,
304 thread_id,
305 post_id
306 )
307 VALUES (%s,%s,%s,%s)',
308 array('integer', 'integer', 'integer', 'integer'),
309 array($a_usr_id, $this->getId(), $a_thread_id, $a_post_id)
310 );
311
312 return true;
313 }
314
315 public function markPostUnread($a_user_id, $a_post_id)
316 {
317 $this->db->manipulateF(
318 '
319 DELETE FROM frm_user_read
320 WHERE usr_id = %s
321 AND post_id = %s',
322 array('integer', 'integer'),
323 array($a_user_id, $a_post_id)
324 );
325 }
326
327 public function isRead($a_usr_id, $a_post_id)
328 {
329 $res = $this->db->queryf(
330 '
331 SELECT * FROM frm_user_read
332 WHERE usr_id = %s
333 AND post_id = %s',
334 array('integer', 'integer'),
335 array($a_usr_id, $a_post_id)
336 );
337
338 return $this->db->numRows($res) ? true : false;
339 }
340
341 public function updateLastAccess($a_usr_id, $a_thread_id)
342 {
343 $res = $this->db->queryf(
344 '
345 SELECT * FROM frm_thread_access
346 WHERE usr_id = %s
347 AND obj_id = %s
348 AND thread_id = %s',
349 array('integer', 'integer', 'integer'),
350 array($a_usr_id, $this->getId(), $a_thread_id)
351 );
352 $data = $this->db->fetchAssoc($res);
353
354 $this->db->replace(
355 'frm_thread_access',
356 array(
357 'usr_id' => array('integer', $a_usr_id),
358 'obj_id' => array('integer', $this->getId()),
359 'thread_id' => array('integer', $a_thread_id)
360 ),
361 array(
362 'access_last' => array('integer', time()),
363 'access_old' => array('integer', isset($data['access_old']) ? $data['access_old'] : 0),
364 'access_old_ts' => array('timestamp', $data['access_old_ts'])
365 )
366 );
367
368 return true;
369 }
370
375 public static function _updateOldAccess($a_usr_id)
376 {
377 global $DIC;
378 $ilDB = $DIC->database();
379
380 $ilDB->manipulateF(
381 '
382 UPDATE frm_thread_access
383 SET access_old = access_last
384 WHERE usr_id = %s',
385 array('integer'),
386 array($a_usr_id)
387 );
388
389 $set = $ilDB->query(
390 "SELECT * FROM frm_thread_access " .
391 " WHERE usr_id = " . $ilDB->quote($a_usr_id, "integer")
392 );
393 while ($rec = $ilDB->fetchAssoc($set)) {
394 $ilDB->manipulate(
395 "UPDATE frm_thread_access SET " .
396 " access_old_ts = " . $ilDB->quote(date('Y-m-d H:i:s', $rec["access_old"]), "timestamp") .
397 " WHERE usr_id = " . $ilDB->quote($rec["usr_id"], "integer") .
398 " AND obj_id = " . $ilDB->quote($rec["obj_id"], "integer") .
399 " AND thread_id = " . $ilDB->quote($rec["thread_id"], "integer")
400 );
401 }
402
403 $new_deadline = time() - 60 * 60 * 24 * 7 * ($DIC->settings()->get('frm_store_new') ?
404 $DIC->settings()->get('frm_store_new') :
405 8);
406
407 $ilDB->manipulateF(
408 '
409 DELETE FROM frm_thread_access WHERE access_last < %s',
410 array('integer'),
411 array($new_deadline)
412 );
413 }
414
415 public static function _deleteUser($a_usr_id)
416 {
417 global $DIC;
418 $ilDB = $DIC->database();
419
420 $data = array($a_usr_id);
421
422 $ilDB->manipulateF(
423 '
424 DELETE FROM frm_user_read WHERE usr_id = %s',
425 array('integer'),
426 $data
427 );
428
429 $ilDB->manipulateF(
430 '
431 DELETE FROM frm_thread_access WHERE usr_id = %s',
432 array('integer'),
433 $data
434 );
435
436 // delete notifications of deleted user
437 $ilDB->manipulateF(
438 '
439 DELETE FROM frm_notification WHERE user_id = %s',
440 array('integer'),
441 $data
442 );
443
444 return true;
445 }
446
447
448 public static function _deleteReadEntries($a_post_id)
449 {
450 global $DIC;
451 $ilDB = $DIC->database();
452
453 $ilDB->manipulateF(
454 '
455 DELETE FROM frm_user_read WHERE post_id = %s',
456 array('integer'),
457 array($a_post_id)
458 );
459
460 return true;
461 }
462
463 public static function _deleteAccessEntries($a_thread_id)
464 {
465 global $DIC;
466 $ilDB = $DIC->database();
467 $ilDB->manipulateF(
468 '
469 DELETE FROM frm_thread_access WHERE thread_id = %s',
470 array('integer'),
471 array($a_thread_id)
472 );
473
474 return true;
475 }
476
481 public function update($a_update_user_id = 0)
482 {
483 if (!$a_update_user_id) {
484 $a_update_user_id = $this->user->getId();
485 }
486
487 if (parent::update()) {
488 $this->db->manipulateF(
489 '
490 UPDATE frm_data
491 SET top_name = %s,
492 top_description = %s,
493 top_update = %s,
494 update_user = %s
495 WHERE top_frm_fk =%s',
496 array('text', 'text', 'timestamp', 'integer', 'integer'),
497 array(
498 $this->getTitle(),
499 $this->getDescription(),
500 date("Y-m-d H:i:s"),
501 (int) $a_update_user_id,
502 (int) $this->getId()
503 )
504 );
505
506 return true;
507 }
508
509 return false;
510 }
511
518 public function cloneObject($a_target_id, $a_copy_id = 0, $a_omit_tree = false)
519 {
521 $new_obj = parent::cloneObject($a_target_id, $a_copy_id, $a_omit_tree);
522 $this->cloneAutoGeneratedRoles($new_obj);
523
524 ilForumProperties::getInstance($this->getId())->copy($new_obj->getId());
525 $this->Forum->setMDB2WhereCondition('top_frm_fk = %s ', array('integer'), array($this->getId()));
526 $topData = $this->Forum->getOneTopic();
527
528 $this->db->update('frm_data', array(
529 'top_name' => array('text', $topData['top_name']),
530 'top_description' => array('text', $topData['top_description']),
531 'top_num_posts' => array('integer', $topData['top_num_posts']),
532 'top_num_threads' => array('integer', $topData['top_num_threads']),
533 'top_last_post' => array('text', $topData['top_last_post']),
534 'top_date' => array('timestamp', $topData['top_date']),
535 'visits' => array('integer', $topData['visits']),
536 'top_update' => array('timestamp', $topData['top_update']),
537 'update_user' => array('integer', $topData['update_user']),
538 'top_usr_id' => array('integer', $topData['top_usr_id'])
539 ), array(
540 'top_frm_fk' => array('integer', $new_obj->getId())
541 ));
542
543 // read options
544 $cwo = ilCopyWizardOptions::_getInstance($a_copy_id);
545 $options = $cwo->getOptions($this->getRefId());
546
547 $options['threads'] = $this->Forum->_getThreads($this->getId());
548
549 // Generate starting threads
550 $new_frm = $new_obj->Forum;
551 $new_frm->setMDB2WhereCondition('top_frm_fk = %s ', array('integer'), array($new_obj->getId()));
552
553 $new_frm->setForumId($new_obj->getId());
554 $new_frm->setForumRefId($new_obj->getRefId());
555
556 $new_topic = $new_frm->getOneTopic();
557 foreach ($options['threads'] as $thread_id => $thread_subject) {
558 $this->Forum->setMDB2WhereCondition('thr_pk = %s ', array('integer'), array($thread_id));
559
560 $old_thread = $this->Forum->getOneThread();
561
562 $old_post_id = $this->Forum->getFirstPostByThread($old_thread['thr_pk']);
563 $old_post = $this->Forum->getOnePost($old_post_id);
564
565 $newThread = new ilForumTopic(0, true, true);
566 $newThread->setSticky($old_thread['is_sticky']);
567 $newThread->setForumId($new_topic['top_pk']);
568 $newThread->setThrAuthorId($old_thread['thr_author_id']);
569 $newThread->setDisplayUserId($old_thread['thr_display_user_id']);
570 $newThread->setSubject($old_thread['thr_subject']);
571 $newThread->setUserAlias($old_thread['thr_usr_alias']);
572 $newThread->setCreateDate($old_thread['thr_date']);
573
574 $newPostId = $new_frm->generateThread(
575 $newThread,
576 ilForum::_lookupPostMessage($old_post_id),
577 $old_post['notify'],
578 0,
579 1,
580 false
581 );
582
583 $old_forum_files = new ilFileDataForum($this->getId(), $old_post_id);
584 $old_forum_files->ilClone($new_obj->getId(), $newPostId);
585 }
586
587 $sourceRefId = $this->getRefId();
588 $targetRefId = $new_obj->getRefId();
589
590 if (
591 $sourceRefId > 0 && $targetRefId > 0 &&
592 $this->tree->getParentId($sourceRefId) === $this->tree->getParentId($targetRefId)
593 ) {
594 $grpRefId = $this->tree->checkForParentType($targetRefId, 'grp');
595 $crsRefId = $this->tree->checkForParentType($targetRefId, 'crs');
596
597 if ($grpRefId > 0 || $crsRefId > 0) {
598 $notifications = new \ilForumNotification($targetRefId);
599 $notifications->cloneFromSource((int) $sourceRefId);
600 }
601 }
602
603 return $new_obj;
604 }
605
612 public function cloneAutoGeneratedRoles($new_obj)
613 {
614 $moderator = ilObjForum::_lookupModeratorRole($this->getRefId());
615 $new_moderator = ilObjForum::_lookupModeratorRole($new_obj->getRefId());
616
617 if (!$moderator || !$new_moderator || !$this->getRefId() || !$new_obj->getRefId()) {
618 $this->logger->write(__METHOD__ . ' : Error cloning auto generated role: il_frm_moderator');
619 }
620 $this->rbac->admin()->copyRolePermissions($moderator, $this->getRefId(), $new_obj->getRefId(), $new_moderator, true);
621 $this->logger->write(__METHOD__ . ' : Finished copying of role il_frm_moderator.');
622
623 $obj_mods = new ilForumModerators($this->getRefId());
624
625 $old_mods = $obj_mods->getCurrentModerators();
626 foreach ($old_mods as $user_id) {
627 // The object owner is already member of the moderator role when this method is called
628 // Since the new static caches are introduced with ILIAS 5.0, a database error occurs if we try to assign the user here.
629 if ($this->getOwner() != $user_id) {
630 $this->rbac->admin()->assignUser($new_moderator, $user_id);
631 }
632 }
633 }
634
640 public function delete()
641 {
642 // always call parent delete function first!!
643 if (!parent::delete()) {
644 return false;
645 }
646
647 // delete attachments
648 $tmp_file_obj = new ilFileDataForum($this->getId());
649 $tmp_file_obj->delete();
650 unset($tmp_file_obj);
651
652 $this->Forum->setMDB2WhereCondition('top_frm_fk = %s ', array('integer'), array($this->getId()));
653
654 $topData = $this->Forum->getOneTopic();
655
656 $threads = $this->Forum->getAllThreads($topData['top_pk']);
657 foreach ($threads['items'] as $thread) {
658 $thread_ids_to_delete[$thread->getId()] = $thread->getId();
659 }
660
661 // delete tree
662 $this->db->manipulate('DELETE FROM frm_posts_tree WHERE ' . $this->db->in('thr_fk', $thread_ids_to_delete, false, 'integer'));
663
664 // delete posts
665 $this->db->manipulate('DELETE FROM frm_posts WHERE ' . $this->db->in('pos_thr_fk', $thread_ids_to_delete, false, 'integer'));
666
667 // delete threads
668 $this->db->manipulate('DELETE FROM frm_threads WHERE ' . $this->db->in('thr_pk', $thread_ids_to_delete, false, 'integer'));
669
670 $obj_id = array($this->getId());
671 // delete forum
672 $this->db->manipulateF(
673 'DELETE FROM frm_data WHERE top_frm_fk = %s',
674 array('integer'),
675 $obj_id
676 );
677
678 // delete settings
679 $this->db->manipulateF(
680 'DELETE FROM frm_settings WHERE obj_id = %s',
681 array('integer'),
682 $obj_id
683 );
684
685 // delete read infos
686 $this->db->manipulateF(
687 'DELETE FROM frm_user_read WHERE obj_id = %s',
688 array('integer'),
689 $obj_id
690 );
691
692 // delete thread access entries
693 $this->db->manipulateF(
694 'DELETE FROM frm_thread_access WHERE obj_id = %s',
695 array('integer'),
696 $obj_id
697 );
698
699 //delete thread notifications
700 $this->db->manipulate('DELETE FROM frm_notification WHERE ' . $this->db->in('thread_id', $thread_ids_to_delete, false, 'integer'));
701
702 //delete forum notifications
703 $this->db->manipulateF('DELETE FROM frm_notification WHERE frm_id = %s', array('integer'), $obj_id);
704
705 // delete posts_deleted entries
706 $this->db->manipulateF('DELETE FROM frm_posts_deleted WHERE obj_id = %s', array('integer'), $obj_id);
707
708 //delete drafts
709 $this->deleteDraftsByForumId((int) $topData['top_pk']);
710
711 return true;
712 }
713
717 private function deleteDraftsByForumId($forum_id)
718 {
719 $res = $this->db->queryF(
720 'SELECT draft_id FROM frm_posts_drafts WHERE forum_id = %s',
721 array('integer'),
722 array((int) $forum_id)
723 );
724
725 $draft_ids = array();
726 while ($row = $this->db->fetchAssoc($res)) {
727 $draft_ids[] = $row['draft_id'];
728 }
729
730 if (count($draft_ids) > 0) {
731 $historyObj = new ilForumDraftsHistory();
732 $historyObj->deleteHistoryByDraftIds($draft_ids);
733
734 $draftObj = new ilForumPostDraft();
735 $draftObj->deleteDraftsByDraftIds($draft_ids);
736 }
737 }
738
744 public function initDefaultRoles()
745 {
747 'il_frm_moderator_' . $this->getRefId(),
748 "Moderator of forum obj_no." . $this->getId(),
749 'il_frm_moderator',
750 $this->getRefId()
751 );
752 return array();
753 }
754
762 public static function _lookupModeratorRole($a_ref_id)
763 {
764 global $DIC;
765 $ilDB = $DIC->database();
766
767 $mod_title = 'il_frm_moderator_' . $a_ref_id;
768
769 $res = $ilDB->queryf(
770 '
771 SELECT * FROM object_data WHERE title = %s',
772 array('text'),
773 array($mod_title)
774 );
775
776 while ($row = $ilDB->fetchObject($res)) {
777 return $row->obj_id;
778 }
779 return 0;
780 }
781
782
783 public function createSettings()
784 {
785 // news settings (public notifications yes/no)
786 $default_visibility = ilNewsItem::_getDefaultVisibilityForRefId($_GET["ref_id"]);
787 if ($default_visibility == "public") {
788 ilBlockSetting::_write("news", "public_notifications", 1, 0, $this->getId());
789 }
790
791 return true;
792 }
793
794 public function saveData($a_roles = array())
795 {
796 $nextId = $this->db->nextId('frm_data');
797
798 $top_data = array(
799 'top_frm_fk' => $this->getId(),
800 'top_name' => $this->getTitle(),
801 'top_description' => $this->getDescription(),
802 'top_num_posts' => 0,
803 'top_num_threads' => 0,
804 'top_last_post' => null,
805 'top_mods' => !is_numeric($a_roles[0]) ? 0 : $a_roles[0],
806 'top_usr_id' => $this->user->getId(),
807 'top_date' => ilUtil::now()
808 );
809
810 $this->db->manipulateF(
811 '
812 INSERT INTO frm_data
813 (
814 top_pk,
815 top_frm_fk,
816 top_name,
817 top_description,
818 top_num_posts,
819 top_num_threads,
820 top_last_post,
821 top_mods,
822 top_date,
823 top_usr_id
824 )
825 VALUES(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)',
826 array('integer', 'integer', 'text', 'text', 'integer', 'integer', 'text', 'integer', 'timestamp', 'integer'),
827 array(
828 $nextId,
829 $top_data['top_frm_fk'],
830 $top_data['top_name'],
831 $top_data['top_description'],
832 $top_data['top_num_posts'],
833 $top_data['top_num_threads'],
834 $top_data['top_last_post'],
835 $top_data['top_mods'],
836 $top_data['top_date'],
837 $top_data['top_usr_id']
838 )
839 );
840 }
841
842 public function setThreadSorting($a_thr_pk, $a_sorting_value)
843 {
844 $this->db->update(
845 'frm_threads',
846 array('thread_sorting' => array('integer',$a_sorting_value)),
847 array('thr_pk' => array('integer', $a_thr_pk))
848 );
849 }
850
851
857 public static function lookupForumIdByObjId($obj_id)
858 {
859 if (array_key_exists($obj_id, self::$obj_id_to_forum_id_cache)) {
860 return (int) self::$obj_id_to_forum_id_cache[$obj_id];
861 }
862
863 self::preloadForumIdsByObjIds(array($obj_id));
864
865 return (int) self::$obj_id_to_forum_id_cache[$obj_id];
866 }
867
873 public static function lookupForumIdByRefId($ref_id)
874 {
875 if (array_key_exists($ref_id, self::$ref_id_to_forum_id_cache)) {
876 return (int) self::$ref_id_to_forum_id_cache[$ref_id];
877 }
878
880
881 return (int) self::$ref_id_to_forum_id_cache[$ref_id];
882 }
883
888 public static function preloadForumIdsByObjIds(array $obj_ids)
889 {
890 global $DIC;
891 $ilDB = $DIC->database();
892
893 if (count($obj_ids) == 1) {
894 $in = " objr.obj_id = " . $ilDB->quote(current($obj_ids), 'integer') . " ";
895 } else {
896 $in = $ilDB->in('objr.obj_id', $obj_ids, false, 'integer');
897 }
898 $query = "
899 SELECT frmd.top_pk, objr.ref_id, objr.obj_id
900 FROM object_reference objr
901 INNER JOIN frm_data frmd ON frmd.top_frm_fk = objr.obj_id
902 WHERE $in
903 ";
904 $res = $ilDB->query($query);
905
906 // Prepare cache array
907 foreach ($obj_ids as $obj_id) {
908 self::$obj_id_to_forum_id_cache[$obj_id] = null;
909 }
910
911 while ($row = $ilDB->fetchAssoc($res)) {
912 self::$obj_id_to_forum_id_cache[$row['obj_id']] = $row['top_pk'];
913 self::$ref_id_to_forum_id_cache[$row['ref_id']] = $row['top_pk'];
914 }
915 }
916
921 public static function preloadForumIdsByRefIds(array $ref_ids)
922 {
923 global $DIC;
924 $ilDB = $DIC->database();
925
926 if (count($ref_ids) == 1) {
927 $in = " objr.ref_id = " . $ilDB->quote(current($ref_ids), 'integer') . " ";
928 } else {
929 $in = $ilDB->in('objr.ref_id', $ref_ids, false, 'integer');
930 }
931 $query = "
932 SELECT frmd.top_pk, objr.ref_id, objr.obj_id
933 FROM object_reference objr
934 INNER JOIN frm_data frmd ON frmd.top_frm_fk = objr.obj_id
935 WHERE $in
936 ";
937 $res = $ilDB->query($query);
938
939 // Prepare cache array
940 foreach ($ref_ids as $ref_id) {
941 self::$ref_id_to_forum_id_cache[$ref_id] = null;
942 }
943
944 while ($row = $ilDB->fetchAssoc($res)) {
945 self::$obj_id_to_forum_id_cache[$row['obj_id']] = $row['top_pk'];
946 self::$ref_id_to_forum_id_cache[$row['ref_id']] = $row['top_pk'];
947 }
948 }
949
955 public static function lookupStatisticsByRefId($ref_id)
956 {
957 global $DIC;
958 $ilAccess = $DIC->access();
959 $ilUser = $DIC->user();
960 $ilDB = $DIC->database();
961 $ilSetting = $DIC->settings();
962
963 if (isset(self::$forum_statistics_cache[$ref_id])) {
964 return self::$forum_statistics_cache[$ref_id];
965 }
966
967 $statistics = array(
968 'num_posts' => 0,
969 'num_unread_posts' => 0,
970 'num_new_posts' => 0
971 );
972
974 if (!$forumId) {
975 self::$forum_statistics_cache[$ref_id] = $statistics;
976 return self::$forum_statistics_cache[$ref_id];
977 }
978
980 $is_post_activation_enabled = $objProperties->isPostActivationEnabled();
981
982 $act_clause = '';
983
984 if ($is_post_activation_enabled && !$ilAccess->checkAccess('moderate_frm', '', $ref_id)) {
985 $act_clause .= " AND (frm_posts.pos_status = " . $ilDB->quote(1, "integer") . " OR frm_posts.pos_author_id = " . $ilDB->quote($ilUser->getId(), "integer") . ") ";
986 }
987
988 $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));
989
990 if (!$ilUser->isAnonymous()) {
991 $query = "
992 (SELECT COUNT(frm_posts.pos_pk) cnt
993 FROM frm_posts
994 INNER JOIN frm_posts_tree tree1
995 ON tree1.pos_fk = frm_posts.pos_pk
996 AND tree1.parent_pos != 0
997 INNER JOIN frm_threads ON frm_posts.pos_thr_fk = frm_threads.thr_pk
998 WHERE frm_threads.thr_top_fk = %s $act_clause)
999
1000 UNION ALL
1001
1002 (SELECT COUNT(DISTINCT(frm_user_read.post_id)) cnt
1003 FROM frm_user_read
1004 INNER JOIN frm_posts ON frm_user_read.post_id = frm_posts.pos_pk
1005 INNER JOIN frm_posts_tree tree1
1006 ON tree1.pos_fk = frm_posts.pos_pk
1007 AND tree1.parent_pos != 0
1008 INNER JOIN frm_threads ON frm_threads.thr_pk = frm_posts.pos_thr_fk
1009 WHERE frm_user_read.usr_id = %s AND frm_posts.pos_top_fk = %s $act_clause)
1010 ";
1011
1012 $types = array('integer', 'integer', 'integer');
1013 $values = array($forumId, $ilUser->getId(), $forumId);
1014
1015 $forum_overview_setting = (int) $ilSetting::_lookupValue('frma', 'forum_overview');
1016 if ($forum_overview_setting == ilForumProperties::FORUM_OVERVIEW_WITH_NEW_POSTS) {
1017 $news_types = array('integer', 'integer', 'integer', 'timestamp', 'integer');
1018 $news_values = array($ilUser->getId(), $ilUser->getId(), $forumId, $new_deadline, $ilUser->getId());
1019
1020 $query .= "
1021 UNION ALL
1022
1023 (SELECT COUNT(frm_posts.pos_pk) cnt
1024 FROM frm_posts
1025 INNER JOIN frm_posts_tree tree1
1026 ON tree1.pos_fk = frm_posts.pos_pk
1027 AND tree1.parent_pos != 0
1028 LEFT JOIN frm_user_read ON (post_id = frm_posts.pos_pk AND frm_user_read.usr_id = %s)
1029 LEFT JOIN frm_thread_access ON (frm_thread_access.thread_id = frm_posts.pos_thr_fk AND frm_thread_access.usr_id = %s)
1030 WHERE frm_posts.pos_top_fk = %s
1031 AND ( (frm_posts.pos_update > frm_thread_access.access_old_ts)
1032 OR (frm_thread_access.access_old IS NULL AND frm_posts.pos_update > %s)
1033 )
1034 AND frm_posts.pos_author_id != %s
1035 AND frm_user_read.usr_id IS NULL $act_clause)";
1036
1037 $types = array_merge($types, $news_types);
1038 $values = array_merge($values, $news_values);
1039 }
1040
1041 $mapping = array_keys($statistics);
1042 $res = $ilDB->queryF(
1043 $query,
1044 $types,
1045 $values
1046 );
1047 for ($i = 0; $i <= 2; $i++) {
1048 $row = $ilDB->fetchAssoc($res);
1049
1050 $statistics[$mapping[$i]] = (int) $row['cnt'];
1051
1052 if ($i == 1) {
1053 // unread = all - read
1054 $statistics[$mapping[$i]] = $statistics[$mapping[$i - 1]] - $statistics[$mapping[$i]];
1055 }
1056 }
1057 } else {
1058 $query = "
1059 SELECT COUNT(frm_posts.pos_pk) cnt
1060 FROM frm_posts
1061 INNER JOIN frm_posts_tree tree1
1062 ON tree1.pos_fk = frm_posts.pos_pk
1063 AND tree1.parent_pos != 0
1064 INNER JOIN frm_threads ON frm_posts.pos_thr_fk = frm_threads.thr_pk
1065 WHERE frm_threads.thr_top_fk = %s $act_clause
1066 ";
1067 $types = array('integer');
1068 $values = array($forumId);
1069 $res = $ilDB->queryF(
1070 $query,
1071 $types,
1072 $values
1073 );
1074 $row = $ilDB->fetchAssoc($res);
1075
1076 $statistics = array(
1077 'num_posts' => $row['cnt'],
1078 'num_unread_posts' => $row['cnt'],
1079 'num_new_posts' => $row['cnt']
1080 );
1081 }
1082
1083 self::$forum_statistics_cache[$ref_id] = $statistics;
1084
1085 return self::$forum_statistics_cache[$ref_id];
1086 }
1087
1093 public static function lookupLastPostByRefId($ref_id)
1094 {
1095 global $DIC;
1096 $ilAccess = $DIC->access();
1097 $ilUser = $DIC->user();
1098 $ilDB = $DIC->database();
1099
1100 if (isset(self::$forum_last_post_cache[$ref_id])) {
1101 return self::$forum_last_post_cache[$ref_id];
1102 }
1103
1105 if (!$forumId) {
1106 self::$forum_last_post_cache[$ref_id] = array();
1107 return self::$forum_last_post_cache[$ref_id];
1108 }
1109
1110 $act_clause = '';
1111 if (!$ilAccess->checkAccess('moderate_frm', '', $ref_id)) {
1112 $act_clause .= " AND (frm_posts.pos_status = " . $ilDB->quote(1, "integer") . " OR frm_posts.pos_author_id = " . $ilDB->quote($ilUser->getId(), "integer") . ") ";
1113 }
1114
1115 $ilDB->setLimit(1, 0);
1116 $query = "
1117 SELECT *
1118 FROM frm_posts
1119 INNER JOIN frm_posts_tree tree1
1120 ON tree1.pos_fk = frm_posts.pos_pk
1121 AND tree1.parent_pos != 0
1122 WHERE pos_top_fk = %s $act_clause
1123 ORDER BY pos_date DESC
1124 ";
1125 $res = $ilDB->queryF(
1126 $query,
1127 array('integer'),
1128 array($forumId)
1129 );
1130
1131 $data = $ilDB->fetchAssoc($res);
1132
1133 self::$forum_last_post_cache[$ref_id] = is_array($data) ? $data : array();
1134
1135 return self::$forum_last_post_cache[$ref_id];
1136 }
1137
1144 public static function getUserIdsOfLastPostsByRefIdAndThreadIds($ref_id, array $thread_ids)
1145 {
1146 global $DIC;
1147 $ilAccess = $DIC->access();
1148 $ilUser = $DIC->user();
1149 $ilDB = $DIC->database();
1150
1151 $act_clause = '';
1152 $act_inner_clause = '';
1153 if (!$ilAccess->checkAccess('moderate_frm', '', $ref_id)) {
1154 $act_clause .= " AND (t1.pos_status = " . $ilDB->quote(1, "integer") . " OR t1.pos_author_id = " . $ilDB->quote($ilUser->getId(), "integer") . ") ";
1155 $act_inner_clause .= " AND (t3.pos_status = " . $ilDB->quote(1, "integer") . " OR t3.pos_author_id = " . $ilDB->quote($ilUser->getId(), "integer") . ") ";
1156 }
1157
1158 $in = $ilDB->in("t1.pos_thr_fk", $thread_ids, false, 'integer');
1159 $inner_in = $ilDB->in("t3.pos_thr_fk", $thread_ids, false, 'integer');
1160
1161 $query = "
1162 SELECT t1.pos_display_user_id, t1.update_user
1163 FROM frm_posts t1
1164 INNER JOIN frm_posts_tree tree1 ON tree1.pos_fk = t1.pos_pk AND tree1.parent_pos != 0
1165 INNER JOIN (
1166 SELECT t3.pos_thr_fk, MAX(t3.pos_date) pos_date
1167 FROM frm_posts t3
1168 INNER JOIN frm_posts_tree tree2 ON tree2.pos_fk = t3.pos_pk AND tree2.parent_pos != 0
1169 WHERE $inner_in $act_inner_clause
1170 GROUP BY t3.pos_thr_fk
1171 ) t2 ON t2.pos_thr_fk = t1.pos_thr_fk AND t2.pos_date = t1.pos_date
1172 WHERE $in $act_clause
1173 GROUP BY t1.pos_thr_fk, t1.pos_display_user_id, t1.update_user
1174 ";
1176 $usr_ids = array();
1177
1178 $res = $ilDB->query($query);
1179 while ($row = $ilDB->fetchAssoc($res)) {
1180 if ((int) $row['pos_display_user_id']) {
1181 $usr_ids[] = (int) $row['pos_display_user_id'];
1182 }
1183 if ((int) $row['update_user']) {
1184 $usr_ids[] = (int) $row['update_user'];
1185 }
1186 }
1187
1188 return array_unique($usr_ids);
1189 }
1190
1191 public static function mergeForumUserRead($merge_source_thread_id, $merge_target_thread_id)
1192 {
1193 global $DIC;
1194 $ilDB = $DIC->database();
1195
1196 $ilDB->update(
1197 'frm_user_read',
1198 array('thread_id' => array('integer', $merge_target_thread_id)),
1199 array('thread_id' => array('integer',$merge_source_thread_id))
1200 );
1201 }
1202}
user()
Definition: user.php:4
if(php_sapi_name() !='cli') $in
Definition: Utf8Test.php:37
$_GET["client_id"]
An exception for terminatinating execution or to throw for unit testing.
static _write($a_type, $a_setting, $a_value, $a_user=0, $a_block_id=0)
Write setting to database.
static _getInstance($a_copy_id)
Get instance of copy wizard options.
This class handles all operations on files for the forum object.
Class ilForumDraftHistory.
Class ilForumModerators.
Class ilForumPostDraft.
static getInstance($a_obj_id=0)
Class Forum core functions for forum.
static _lookupPostMessage($a_id)
static _getDefaultVisibilityForRefId($a_ref_id)
Get default visibility for reference id.
static _lookupDiskUsage($a_obj_id)
Returns the number of bytes used on the harddisk by the specified forum.
Class ilObjForum.
static $obj_id_to_forum_id_cache
markPostRead($a_usr_id, $a_thread_id, $a_post_id)
__construct($a_id=0, $a_call_by_reference=true)
Constructor @access public.
static _lookupThreadSubject($a_thread_id)
getCountUnread($a_usr_id, $a_thread_id=0, $ignoreRoot=false)
markAllThreadsRead($a_usr_id)
update($a_update_user_id=0)
update forum data @access public
deleteDraftsByForumId($forum_id)
static $forum_last_post_cache
initDefaultRoles()
init default roles settings @access public
saveData($a_roles=array())
setPermissions($a_ref_id)
updateModeratorRole($role_id)
static _deleteReadEntries($a_post_id)
static $forum_statistics_cache
static preloadForumIdsByRefIds(array $ref_ids)
static lookupStatisticsByRefId($ref_id)
updateLastAccess($a_usr_id, $a_thread_id)
setThreadSorting($a_thr_pk, $a_sorting_value)
getDiskUsage()
Gets the disk usage of the object in bytes.
static lookupForumIdByRefId($ref_id)
isRead($a_usr_id, $a_post_id)
static _deleteUser($a_usr_id)
static _deleteAccessEntries($a_thread_id)
markPostUnread($a_user_id, $a_post_id)
static lookupLastPostByRefId($ref_id)
markThreadRead($a_usr_id, $a_thread_id)
cloneAutoGeneratedRoles($new_obj)
Clone forum moderator role @access public.
static getUserIdsOfLastPostsByRefIdAndThreadIds($ref_id, array $thread_ids)
static $ref_id_to_forum_id_cache
static preloadForumIdsByObjIds(array $obj_ids)
static _lookupModeratorRole($a_ref_id)
Lookup moderator role @access public.
static _updateOldAccess($a_usr_id)
static mergeForumUserRead($merge_source_thread_id, $merge_target_thread_id)
static lookupForumIdByObjId($obj_id)
static createDefaultRole($a_title, $a_description, $a_tpl_name, $a_ref_id)
Class ilObject Basic functions for all objects.
getOwner()
get object owner
static _lookupObjectId($a_ref_id)
lookup object id
getRefId()
get reference id @access public
getDescription()
get object description
getId()
get object id @access public
getTitle()
get object title @access public
static now()
Return current timestamp in Y-m-d H:i:s format.
$i
Definition: disco.tpl.php:19
$row
update($pash, $contents, Config $config)
global $ilSetting
Definition: privfeed.php:17
$query
global $DIC
Definition: saml.php:7
foreach($_POST as $key=> $value) $res
settings()
Definition: settings.php:2
global $ilDB
$values
$ilUser
Definition: imgupload.php:18
$data
Definition: bench.php:6