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