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 
13 class 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 
879  self::preloadForumIdsByRefIds(array($ref_id));
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 
973  $forumId = self::lookupForumIdByRefId($ref_id);
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 
1104  $forumId = self::lookupForumIdByRefId($ref_id);
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 }
static $forum_last_post_cache
markAllThreadsRead($a_usr_id)
Class ilForumPostDraft.
static mergeForumUserRead($merge_source_thread_id, $merge_target_thread_id)
Class Forum core functions for forum.
settings()
Definition: settings.php:2
static _write($a_type, $a_setting, $a_value, $a_user=0, $a_block_id=0)
Write setting to database.
update($a_update_user_id=0)
update forum data public
static _lookupPostMessage($a_id)
setThreadSorting($a_thr_pk, $a_sorting_value)
static lookupForumIdByObjId($obj_id)
global $DIC
Definition: saml.php:7
$_GET["client_id"]
static lookupForumIdByRefId($ref_id)
static $obj_id_to_forum_id_cache
initDefaultRoles()
init default roles settings public
deleteDraftsByForumId($forum_id)
markPostRead($a_usr_id, $a_thread_id, $a_post_id)
markThreadRead($a_usr_id, $a_thread_id)
static preloadForumIdsByObjIds(array $obj_ids)
setPermissions($a_ref_id)
getOwner()
get object owner
static now()
Return current timestamp in Y-m-d H:i:s format.
user()
Definition: user.php:4
static createDefaultRole($a_title, $a_description, $a_tpl_name, $a_ref_id)
Class ilForumDraftHistory.
markPostUnread($a_user_id, $a_post_id)
saveData($a_roles=array())
static _lookupObjectId($a_ref_id)
lookup object id
updateLastAccess($a_usr_id, $a_thread_id)
static _deleteReadEntries($a_post_id)
static getInstance($a_obj_id=0)
static _getInstance($a_copy_id)
Get instance of copy wizard options.
updateModeratorRole($role_id)
static _lookupThreadSubject($a_thread_id)
foreach($_POST as $key=> $value) $res
getId()
get object id public
static _lookupDiskUsage($a_obj_id)
Returns the number of bytes used on the harddisk by the specified forum.
static _lookupModeratorRole($a_ref_id)
Lookup moderator role public.
$values
getTitle()
get object title public
getDescription()
get object description
$ilUser
Definition: imgupload.php:18
$query
static _updateOldAccess($a_usr_id)
$row
if(php_sapi_name() !='cli') $in
Definition: Utf8Test.php:37
update($pash, $contents, Config $config)
static _deleteAccessEntries($a_thread_id)
static $forum_statistics_cache
static _deleteUser($a_usr_id)
isRead($a_usr_id, $a_post_id)
global $ilSetting
Definition: privfeed.php:17
This class handles all operations on files for the forum object.
global $ilDB
static _getDefaultVisibilityForRefId($a_ref_id)
Get default visibility for reference id.
$i
Definition: disco.tpl.php:19
getRefId()
get reference id public
static lookupStatisticsByRefId($ref_id)
__construct($a_id=0, $a_call_by_reference=true)
Constructor public.
static $ref_id_to_forum_id_cache
getCountUnread($a_usr_id, $a_thread_id=0, $ignoreRoot=false)
Class ilObjForum.
cloneAutoGeneratedRoles($new_obj)
Clone forum moderator role public.
static getUserIdsOfLastPostsByRefIdAndThreadIds($ref_id, array $thread_ids)
Class ilForumModerators.
static preloadForumIdsByRefIds(array $ref_ids)
getDiskUsage()
Gets the disk usage of the object in bytes.
static lookupLastPostByRefId($ref_id)
$data
Definition: bench.php:6