ILIAS  release_7 Revision v7.30-3-g800a261c036
All Data Structures Namespaces Files Functions Variables Modules Pages
class.ilForum.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 ilForum
14 {
15  const SORT_TITLE = 1;
16  const SORT_DATE = 2;
17 
18  const DEFAULT_PAGE_HITS = 30;
19 
23  protected static $moderators_by_ref_id_map = array();
24 
25  public $lng;
26  public $error;
27  public $db;
28  public $user;
29  public $settings;
30 
37  private $dbTable;
38 
44  private $className = "ilForum";
45 
52  private $orderField;
53 
54  private $mdb2Query;
55  private $mdb2DataValue;
56  private $mdb2DataType;
57 
58  private $txtQuote1 = "[quote]";
59  private $txtQuote2 = "[/quote]";
60  private $replQuote1 = '<blockquote class="ilForumQuote">';
61  private $replQuote2 = '</blockquote>';
62 
63  // max. datasets per page
64  private $pageHits = self::DEFAULT_PAGE_HITS;
65 
66  // object id
67  private $id;
68 
73  public function __construct()
74  {
75  global $DIC;
76 
77  $this->error = $DIC['ilErr'];
78  $this->lng = $DIC->language();
79  $this->db = $DIC->database();
80  $this->user = $DIC->user();
81  $this->settings = $DIC->settings();
82  }
83 
84  // no usage?
85  public function setLanguage($lng)
86  {
87  $this->lng = $lng;
88  }
89 
100  public static function _getLanguageInstanceByUsrId($usr_id)
101  {
102  static $lngCache = array();
103 
104  $languageShorthandle = ilObjUser::_lookupLanguage($usr_id);
105 
106  // lookup in cache array
107  if (!isset($lngCache[$languageShorthandle])) {
108  $lngCache[$languageShorthandle] = new ilLanguage($languageShorthandle);
109  $lngCache[$languageShorthandle]->loadLanguageModule('forum');
110  }
111 
112  return $lngCache[$languageShorthandle];
113  }
114 
120  public function setForumId($a_obj_id)
121  {
122  if (!isset($a_obj_id)) {
123  $message = get_class($this) . "::setForumId(): No obj_id given!";
124  $this->error->raiseError($message, $this->error->WARNING);
125  }
126 
127  $this->id = $a_obj_id;
128  }
129 
135  public function setForumRefId($a_ref_id)
136  {
137  if (!isset($a_ref_id)) {
138  $message = get_class($this) . "::setForumRefId(): No ref_id given!";
139  $this->error->raiseError($message, $this->error->WARNING);
140  }
141 
142  $this->ref_id = $a_ref_id;
143  }
144 
150  public function getForumId()
151  {
152  return $this->id;
153  }
154 
160  public function getForumRefId()
161  {
162  return $this->ref_id;
163  }
164 
171  private function setOrderField($orderField)
172  {
173  if ($orderField == "") {
174  die($this->className . "::setOrderField(): No orderField given.");
175  } else {
176  $this->orderField = $orderField;
177  }
178  }
179 
186  public function getOrderField()
187  {
188  return $this->orderField;
189  }
190 
197  public function setDbTable($dbTable)
198  {
199  if ($dbTable == "") {
200  die($this->className . "::setDbTable(): No database table given.");
201  } else {
202  $this->dbTable = $dbTable;
203  }
204  }
205 
212  public function getDbTable()
213  {
214  return $this->dbTable;
215  }
216 
225  public function setMDB2WhereCondition($query_string, $data_type, $data_value)
226  {
227  $this->mdb2Query = $query_string;
228  $this->mdb2DataValue = $data_value;
229  $this->mdb2DataType = $data_type;
230 
231  return true;
232  }
233 
238  public function getMDB2Query()
239  {
240  if ($this->mdb2Query != '') {
241  return $this->mdb2Query;
242  }
243  }
244 
249  public function getMDB2DataValue()
250  {
251  if ($this->mdb2DataValue != '') {
252  return $this->mdb2DataValue;
253  }
254  }
255 
260  public function getMDB2DataType()
261  {
262  if ($this->mdb2DataType != '') {
263  return $this->mdb2DataType;
264  }
265  }
266 
271  public function setPageHits($pageHits)
272  {
273  if ($pageHits < 1 || !is_numeric($pageHits)) {
274  $pageHits = 1;
275  }
276 
277  $this->pageHits = (int) $pageHits;
278  return true;
279  }
280 
287  public function getPageHits()
288  {
289  return $this->pageHits;
290  }
291 
297  public function getOneTopic()
298  {
299  $data_type = array();
300  $data_value = array();
301 
302  $query = 'SELECT * FROM frm_data WHERE ';
303 
304  if ($this->getMDB2Query() != '' && $this->getMDB2DataType() != '' && $this->getMDB2DataValue() != '') {
305  $query .= '' . $this->getMDB2Query() . '';
306  $data_type = $data_type + $this->getMDB2DataType();
307  $data_value = $data_value + $this->getMDB2DataValue();
308 
309  $res = $this->db->queryf($query, $data_type, $data_value);
310  $row = $this->db->fetchAssoc($res);
311 
312  if (is_null($row)) {
313  return null;
314  }
315 
316  $row["top_name"] = trim($row["top_name"]);
317  $row["top_description"] = nl2br($row["top_description"]);
318 
319  return $row;
320  } else {
321  $query .= '1 = 1';
322 
323  $res = $this->db->query($query);
324  $row = $this->db->fetchAssoc($res);
325 
326  if (!is_array($row) || !count($row)) {
327  return null;
328  }
329 
330  $row['top_name'] = trim($row['top_name']);
331  $row['top_description'] = nl2br($row['top_description']);
332 
333  return $row;
334  }
335  }
336 
342  public function getOneThread()
343  {
344  $data_type = array();
345  $data_value = array();
346 
347  $query = 'SELECT * FROM frm_threads WHERE ';
348 
349  if ($this->getMDB2Query() != '' && $this->getMDB2DataType() != '' && $this->getMDB2DataValue() != '') {
350  $query .= $this->getMDB2Query();
351  $data_type = $data_type + $this->getMDB2DataType();
352  $data_value = $data_value + $this->getMDB2DataValue();
353 
354  $sql_res = $this->db->queryf($query, $data_type, $data_value);
355  $result = $this->db->fetchAssoc($sql_res);
356  $result["thr_subject"] = trim($result["thr_subject"]);
357  }
358 
359  return $result;
360  }
361 
368  public function getOnePost($post)
369  {
370  $res = $this->db->queryf(
371  '
372  SELECT frm_posts.*, usr_data.lastname FROM frm_posts, usr_data
373  WHERE pos_pk = %s
374  AND pos_display_user_id = usr_id',
375  array('integer'),
376  array($post)
377  );
378 
379  $row = $this->db->fetchAssoc($res);
380 
381  $row["pos_date"] = $this->convertDate($row["pos_date"]);
382  $row["pos_message"] = nl2br($row["pos_message"]);
383 
384  return $row;
385  }
386 
387  public static function _lookupPostMessage($a_id)
388  {
389  global $DIC;
390  $ilDB = $DIC->database();
391 
392  $res = $ilDB->queryf(
393  '
394  SELECT * FROM frm_posts WHERE pos_pk = %s',
395  array('integer'),
396  array($a_id)
397  );
398 
399  while ($row = $ilDB->fetchObject($res)) {
400  return $row->pos_message;
401  }
402  return '';
403  }
404 
421  public function generatePost($forum_id, $thread_id, $author_id, $display_user_id, $message, $parent_pos, $notify, $subject = '', $alias = '', $date = '', $status = 1, $send_activation_mail = 0)
422  {
423  $objNewPost = new ilForumPost();
424  $objNewPost->setForumId($forum_id);
425  $objNewPost->setThreadId($thread_id);
426  $objNewPost->setSubject($subject);
427  $objNewPost->setMessage($message);
428  $objNewPost->setDisplayUserId($display_user_id);
429  $objNewPost->setUserAlias($alias);
430  $objNewPost->setPosAuthorId($author_id);
431 
432  $frm_settings = ilForumProperties::getInstance($this->getForumId());
433 
434  if ($frm_settings->getMarkModeratorPosts() == 1) {
435  self::_isModerator($this->getForumRefId(), $author_id) ? $is_moderator = true : $is_moderator = false;
436  } else {
437  $is_moderator = false;
438  }
439  $objNewPost->setIsAuthorModerator($is_moderator);
440 
441  if ($date == "") {
442  $objNewPost->setCreateDate(date("Y-m-d H:i:s"));
443  } else {
444  if (strpos($date, "-") > 0) { // in mysql format
445  $objNewPost->setCreateDate($date);
446  } else { // a timestamp
447  $objNewPost->setCreateDate(date("Y-m-d H:i:s", $date));
448  }
449  }
450  if ($status == 1) {
451  $objNewPost->setPostActivationDate($objNewPost->getCreateDate());
452  }
453 
454  $objNewPost->setImportName($this->getImportName());
455  $objNewPost->setNotification($notify);
456  $objNewPost->setStatus($status);
457  $objNewPost->insert();
458 
459  // entry in tree-table
460  if ($parent_pos == 0) {
461  $this->addPostTree($objNewPost->getThreadId(), $objNewPost->getId(), $objNewPost->getCreateDate());
462  } else {
463  $this->insertPostNode($objNewPost->getId(), $parent_pos, $objNewPost->getThreadId(), $objNewPost->getCreateDate());
464  }
465 
466  // string last post
467  $lastPost = $objNewPost->getForumId() . "#" . $objNewPost->getThreadId() . "#" . $objNewPost->getId();
468 
469  // update thread
470  $this->db->manipulateF(
471  '
472  UPDATE frm_threads
473  SET thr_num_posts = thr_num_posts + 1,
474  thr_last_post = %s
475  WHERE thr_pk = %s',
476  array('text', 'integer'),
477  array($lastPost, $objNewPost->getThreadId())
478  );
479 
480  // update forum
481  $this->db->manipulateF(
482  '
483  UPDATE frm_data
484  SET top_num_posts = top_num_posts + 1,
485  top_last_post = %s
486  WHERE top_pk = %s',
487  array('text', 'integer'),
488  array($lastPost, $objNewPost->getForumId())
489  );
490 
491  // MARK READ
492  $forum_obj = ilObjectFactory::getInstanceByRefId($this->getForumRefId());
493  $forum_obj->markPostRead($objNewPost->getPosAuthorId(), $objNewPost->getThreadId(), $objNewPost->getId());
494 
495  // Add Notification to news
496  if ($status && $parent_pos > 0) {
497  $news_item = new ilNewsItem();
498  $news_item->setContext($forum_obj->getId(), 'frm', $objNewPost->getId(), 'pos');
499  $news_item->setPriority(NEWS_NOTICE);
500  $news_item->setTitle($objNewPost->getSubject());
501  $news_item->setContent(ilRTE::_replaceMediaObjectImageSrc($this->prepareText($objNewPost->getMessage(), 0), 1));
502  if ($objNewPost->getMessage() != strip_tags($objNewPost->getMessage())) {
503  $news_item->setContentHtml(true);
504  }
505 
506  $news_item->setUserId($display_user_id);
507  $news_item->setVisibility(NEWS_USERS);
508  $news_item->create();
509  }
510 
511  return $objNewPost->getId();
512  }
513 
523  public function generateThread(
524  ilForumTopic $thread,
525  $message,
526  $notify,
527  $notify_posts,
528  $status = 1,
529  bool $withFirstVisibleEntry = true
530  ) {
531  if (!$thread->getCreateDate()) {
532  $thread->setCreateDate(date('Y-m-d H:i:s'));
533  }
534 
535  $thread->setImportName($this->getImportName());
536  $thread->insert();
537 
538  if ($notify_posts == 1) {
539  $thread->enableNotification($thread->getThrAuthorId());
540  }
541 
542  $this->db->manipulateF(
543  '
544  UPDATE frm_data
545  SET top_num_threads = top_num_threads + 1
546  WHERE top_pk = %s',
547  array('integer'),
548  array($thread->getForumId())
549  );
550 
551  $rootNodeId = $this->generatePost(
552  $thread->getForumId(),
553  $thread->getId(),
554  $thread->getThrAuthorId(),
555  $thread->getDisplayUserId(),
556  '',
557  0,
558  0,
559  $thread->getSubject(),
560  $thread->getUserAlias(),
561  $thread->getCreateDate(),
562  1,
563  0
564  );
565 
566  if (!$withFirstVisibleEntry) {
567  return $rootNodeId;
568  }
569 
570  return $this->generatePost(
571  $thread->getForumId(),
572  $thread->getId(),
573  $thread->getThrAuthorId(),
574  $thread->getDisplayUserId(),
575  $message,
576  $rootNodeId,
577  $notify,
578  $thread->getSubject(),
579  $thread->getUserAlias(),
580  $thread->getCreateDate(),
581  $status,
582  0
583  );
584  }
585 
595  public function moveThreads($thread_ids = array(), $src_ref_id = 0, $dest_top_frm_fk = 0)
596  {
597  $src_top_frm_fk = ilObject::_lookupObjectId($src_ref_id);
598 
599  $errorMessages = array();
600 
601  if (is_numeric($src_top_frm_fk) && $src_top_frm_fk > 0 && is_numeric($dest_top_frm_fk) && $dest_top_frm_fk > 0) {
602  $this->setMDB2WhereCondition('top_frm_fk = %s ', array('integer'), array($src_top_frm_fk));
603 
604  $oldFrmData = $this->getOneTopic();
605 
606  $this->setMDB2WhereCondition('top_frm_fk = %s ', array('integer'), array($dest_top_frm_fk));
607 
608  $newFrmData = $this->getOneTopic();
609 
610  if ($oldFrmData['top_pk'] && $newFrmData['top_pk']) {
611  $moved_posts = 0;
612  $moved_threads = 0;
613  $visits = 0;
614 
615  foreach ($thread_ids as $id) {
616  $objTmpThread = new ilForumTopic($id);
617 
618  try {
619  $numPosts = $objTmpThread->movePosts(
620  $src_top_frm_fk,
621  $oldFrmData['top_pk'],
622  $dest_top_frm_fk,
623  $newFrmData['top_pk']
624  );
625 
626  if (($last_post_string = $objTmpThread->getLastPostString()) != '') {
627  $last_post_string = explode('#', $last_post_string);
628  $last_post_string[0] = $newFrmData['top_pk'];
629  $last_post_string = implode('#', $last_post_string);
630  $objTmpThread->setLastPostString($last_post_string);
631  }
632 
633  $visits += $objTmpThread->getVisits();
634 
635  $moved_posts += $numPosts;
636  ++$moved_threads;
637 
638  $objTmpThread->setForumId($newFrmData['top_pk']);
639  $objTmpThread->update();
640 
641  unset($objTmpThread);
642  } catch (\ilFileUtilsException $exception) {
643  $errorMessages[] = sprintf($this->lng->txt('frm_move_invalid_file_type'), $objTmpThread->getSubject());
644  continue;
645  }
646  }
647 
648  if ($moved_threads > 0 || $moved_posts > 0 || $visits > 0) {
649  // update frm_data source forum
650  $this->db->setLimit(1);
651  $res = $this->db->queryf(
652  '
653  SELECT pos_thr_fk, pos_pk
654  FROM frm_posts
655  WHERE pos_top_fk = %s
656  ORDER BY pos_date DESC',
657  array('integer'),
658  array($oldFrmData['top_pk'])
659  );
660 
661  $row = $this->db->fetchObject($res);
662  $last_post_src = $oldFrmData['top_pk'] . '#' . $row->pos_thr_fk . '#' . $row->pos_pk;
663 
664  $this->db->manipulateF(
665  '
666  UPDATE frm_data
667  SET top_num_posts = top_num_posts - %s,
668  top_num_threads = top_num_threads - %s,
669  visits = visits - %s,
670  top_last_post = %s
671  WHERE top_pk = %s',
672  array('integer', 'integer', 'integer', 'text', 'integer'),
673  array( $moved_posts,
674  $moved_threads,
675  $visits,
676  $last_post_src,
677  $oldFrmData['top_pk'])
678  );
679 
680  // update frm_data destination forum
681  $this->db->setLimit(1);
682  $res = $this->db->queryf(
683  '
684  SELECT pos_thr_fk, pos_pk
685  FROM frm_posts
686  WHERE pos_top_fk = %s
687  ORDER BY pos_date DESC',
688  array('integer'),
689  array($newFrmData['top_kp'])
690  );
691 
692  $row = $this->db->fetchObject($res);
693  $last_post_dest = $newFrmData['top_pk'] . '#' . $row->pos_thr_fk . '#' . $row->pos_pk;
694 
695  $this->db->manipulateF(
696  '
697  UPDATE frm_data
698  SET top_num_posts = top_num_posts + %s,
699  top_num_threads = top_num_threads + %s,
700  visits = visits + %s,
701  top_last_post = %s
702  WHERE top_pk = %s',
703  array('integer', 'integer', 'integer', 'text', 'integer'),
704  array($moved_posts, $moved_threads, $visits, $last_post_dest, $newFrmData['top_pk'])
705  );
706  }
707  }
708 
709  return $errorMessages;
710  }
711  }
712 
713 
721  public function postCensorship($message, $pos_pk, $cens = 0)
722  {
723  $cens_date = date("Y-m-d H:i:s");
724 
725  $this->db->manipulateF(
726  '
727  UPDATE frm_posts
728  SET pos_cens_com = %s,
729  pos_cens_date = %s,
730  pos_cens = %s,
731  update_user = %s
732  WHERE pos_pk = %s',
733  array('text', 'timestamp', 'integer', 'integer', 'integer'),
734  array($message, $cens_date, $cens, $GLOBALS['DIC']['ilUser']->getId(), $pos_pk)
735  );
736 
737  // Change news item accordingly
739  $this->id,
740  "frm",
741  $pos_pk,
742  "pos"
743  );
744  if ($news_id > 0) {
745  if ($cens > 0) { // censor
746  $news_item = new ilNewsItem($news_id);
747  //$news_item->setTitle($subject);
748  $news_item->setContent(nl2br($this->prepareText($message, 0)));
749  if ($message != strip_tags($message)) {
750  $news_item->setContentHtml(true);
751  } else {
752  $news_item->setContentHtml(false);
753  }
754 
755  $news_item->update();
756  } else { // revoke censorship
757  // get original message
758  $res = $this->db->queryf(
759  '
760  SELECT * FROM frm_posts
761  WHERE pos_pk = %s',
762  array('integer'),
763  array($pos_pk)
764  );
765 
766  $rec = $this->db->fetchAssoc($res);
767 
768  $news_item = new ilNewsItem($news_id);
769  //$news_item->setTitle($subject);
770  $news_item->setContent(nl2br($this->prepareText($rec["pos_message"], 0)));
771  if ($rec["pos_message"] != strip_tags($rec["pos_message"])) {
772  $news_item->setContentHtml(true);
773  } else {
774  $news_item->setContentHtml(false);
775  }
776 
777  $news_item->update();
778  }
779  }
780 
781  $GLOBALS['ilAppEventHandler']->raise(
782  'Modules/Forum',
783  'censoredPost',
784  array(
785  'ref_id' => $this->getForumRefId(),
786  'post' => new ilForumPost($pos_pk)
787  )
788  );
789 
790  return true;
791  }
792 
799  public function deletePost($postIdOrArray, $raiseEvents = true)
800  {
801  if (is_numeric($postIdOrArray)) {
802  $p_node = $this->getPostNode($postIdOrArray);
803  } else {
804  $p_node = $postIdOrArray;
805  }
806 
807  if ($raiseEvents) {
808  $is_deleted_thread = ($p_node["parent"] == 0) ? true : false;
809  $num_visible_active_posts = 0;
810  if ($is_deleted_thread) {
811  $query = '
812  SELECT COUNT(*) AS cnt
813  FROM frm_posts
814  INNER JOIN frm_posts_tree ON pos_pk = pos_fk
815  WHERE frm_posts_tree.parent_pos != 0
816  AND pos_thr_fk = ' . $this->db->quote($p_node['pos_thr_fk'], 'integer') . '
817  AND pos_status = ' . $this->db->quote(1, 'integer');
818  $res = $this->db->query($query);
819  $row = $this->db->fetchAssoc($res);
820  $num_visible_active_posts = (int) ($row['cnt'] ?? 0);
821  }
822 
823  $GLOBALS['ilAppEventHandler']->raise(
824  'Modules/Forum',
825  'deletedPost',
826  [
827  'ref_id' => $this->getForumRefId(),
828  'post' => new ilForumPost($p_node['pos_pk']),
829  'thread_deleted' => $is_deleted_thread,
830  'num_visible_active_posts' => $num_visible_active_posts
831  ]
832  );
833  }
834 
835  // delete tree and get id's of all posts to delete
836  $del_id = $this->deletePostTree($p_node);
837 
838  // delete drafts_history
839  $obj_history = new ilForumDraftsHistory();
840  $obj_history->deleteHistoryByPostIds($del_id);
841  // delete all drafts
842  $obj_draft = new ilForumPostDraft();
843  $obj_draft->deleteDraftsByPostIds($del_id);
844 
845  // Delete User read entries
846  foreach ($del_id as $post_id) {
848  }
849 
850  // DELETE ATTACHMENTS ASSIGNED TO POST
851  $this->__deletePostFiles($del_id);
852 
853  $dead_pos = count($del_id);
854  $dead_thr = 0;
855 
856  // if deletePost is thread opener ...
857  if ($p_node["parent"] == 0) {
858  // delete thread access data
859  ilObjForum::_deleteAccessEntries($p_node['tree']);
860 
861  // delete thread
862  $dead_thr = $p_node["tree"];
863 
864  $this->db->manipulateF(
865  '
866  DELETE FROM frm_threads
867  WHERE thr_pk = %s',
868  array('integer'),
869  array($p_node['tree'])
870  );
871 
872  // update num_threads
873  $this->db->manipulateF(
874  '
875  UPDATE frm_data
876  SET top_num_threads = top_num_threads - 1
877  WHERE top_frm_fk = %s',
878  array('integer'),
879  array($this->id)
880  );
881 
882  // delete all related news
883  $posset = $this->db->queryf(
884  '
885  SELECT * FROM frm_posts
886  WHERE pos_thr_fk = %s',
887  array('integer'),
888  array($p_node['tree'])
889  );
890 
891  while ($posrec = $this->db->fetchAssoc($posset)) {
893  $this->id,
894  "frm",
895  $posrec["pos_pk"],
896  "pos"
897  );
898  if ($news_id > 0) {
899  $news_item = new ilNewsItem($news_id);
900  $news_item->delete();
901  }
902 
903  try {
904  $mobs = ilObjMediaObject::_getMobsOfObject('frm:html', $posrec['pos_pk']);
905  foreach ($mobs as $mob) {
906  if (ilObjMediaObject::_exists($mob)) {
907  ilObjMediaObject::_removeUsage($mob, 'frm:html', $posrec['pos_pk']);
908  $mob_obj = new ilObjMediaObject($mob);
909  $mob_obj->delete();
910  }
911  }
912  } catch (Exception $e) {
913  }
914  }
915 
916  // delete all posts of this thread
917  $this->db->manipulateF(
918  '
919  DELETE FROM frm_posts
920  WHERE pos_thr_fk = %s',
921  array('integer'),
922  array($p_node['tree'])
923  );
924  } else {
925  // delete this post and its sub-posts
926  for ($i = 0; $i < $dead_pos; $i++) {
927  $this->db->manipulateF(
928  '
929  DELETE FROM frm_posts
930  WHERE pos_pk = %s',
931  array('integer'),
932  array($del_id[$i])
933  );
934 
935  // delete related news item
937  $this->id,
938  "frm",
939  $del_id[$i],
940  "pos"
941  );
942  if ($news_id > 0) {
943  $news_item = new ilNewsItem($news_id);
944  $news_item->delete();
945  }
946 
947  try {
948  $mobs = ilObjMediaObject::_getMobsOfObject('frm:html', $del_id[$i]);
949  foreach ($mobs as $mob) {
950  if (ilObjMediaObject::_exists($mob)) {
951  ilObjMediaObject::_removeUsage($mob, 'frm:html', $del_id[$i]);
952  $mob_obj = new ilObjMediaObject($mob);
953  $mob_obj->delete();
954  }
955  }
956  } catch (Exception $e) {
957  }
958  }
959 
960  // update num_posts in frm_threads
961  $this->db->manipulateF(
962  '
963  UPDATE frm_threads
964  SET thr_num_posts = thr_num_posts - %s
965  WHERE thr_pk = %s',
966  array('integer', 'integer'),
967  array($dead_pos, $p_node['tree'])
968  );
969 
970  // get latest post of thread and update last_post
971  $res1 = $this->db->queryf(
972  '
973  SELECT * FROM frm_posts
974  WHERE pos_thr_fk = %s
975  ORDER BY pos_date DESC',
976  array('integer'),
977  array($p_node['tree'])
978  );
979 
980  if ($res1->numRows() == 0) {
981  $lastPost_thr = "";
982  } else {
983  $z = 0;
984 
985  while ($selData = $this->db->fetchAssoc($res1)) {
986  if ($z > 0) {
987  break;
988  }
989 
990  $lastPost_thr = $selData["pos_top_fk"] . "#" . $selData["pos_thr_fk"] . "#" . $selData["pos_pk"];
991  $z++;
992  }
993  }
994 
995  $this->db->manipulateF(
996  '
997  UPDATE frm_threads
998  SET thr_last_post = %s
999  WHERE thr_pk = %s',
1000  array('text', 'integer'),
1001  array($lastPost_thr, $p_node['tree'])
1002  );
1003  }
1004 
1005  // update num_posts in frm_data
1006  $this->db->manipulateF(
1007  '
1008  UPDATE frm_data
1009  SET top_num_posts = top_num_posts - %s
1010  WHERE top_frm_fk = %s',
1011  array('integer', 'integer'),
1012  array($dead_pos, $this->id)
1013  );
1014 
1015  // get latest post of forum and update last_post
1016  $res2 = $this->db->queryf(
1017  '
1018  SELECT * FROM frm_posts, frm_data
1019  WHERE pos_top_fk = top_pk
1020  AND top_frm_fk = %s
1021  ORDER BY pos_date DESC',
1022  array('integer'),
1023  array($this->id)
1024  );
1025 
1026  if ($res2->numRows() == 0) {
1027  $lastPost_top = "";
1028  } else {
1029  $z = 0;
1030 
1031  while ($selData = $this->db->fetchAssoc($res2)) {
1032  if ($z > 0) {
1033  break;
1034  }
1035 
1036  $lastPost_top = $selData["pos_top_fk"] . "#" . $selData["pos_thr_fk"] . "#" . $selData["pos_pk"];
1037  $z++;
1038  }
1039  }
1040 
1041  $this->db->manipulateF(
1042  '
1043  UPDATE frm_data
1044  SET top_last_post = %s
1045  WHERE top_frm_fk = %s',
1046  array('text', 'integer'),
1047  array($lastPost_top, $this->id)
1048  );
1049 
1050  return $dead_thr;
1051  }
1052 
1060  public function getAllThreads($a_topic_id, array $params = array(), $limit = 0, $offset = 0)
1061  {
1062  $frm_overview_setting = (int) $this->settings->get('forum_overview');
1063  $frm_props = ilForumProperties::getInstance($this->getForumId());
1064  $is_post_activation_enabled = $frm_props->isPostActivationEnabled();
1065 
1066  $user_id = $this->user->getId();
1067 
1068  $excluded_ids_condition = '';
1069  if (isset($params['excluded_ids']) && is_array($params['excluded_ids']) && $params['excluded_ids']) {
1070  $excluded_ids_condition = ' AND ' . $this->db->in('thr_pk', $params['excluded_ids'], true, 'integer') . ' ';
1071  }
1072 
1073  if (!in_array(strtolower($params['order_column']), array('lp_date', 'rating', 'thr_subject', 'num_posts', 'num_visit'))) {
1074  $params['order_column'] = 'post_date';
1075  }
1076  if (!in_array(strtolower($params['order_direction']), array('asc', 'desc'))) {
1077  $params['order_direction'] = 'desc';
1078  }
1079 
1080  $cnt_active_pos_query = '';
1081  $cnt_join_type = 'LEFT';
1082  if ($is_post_activation_enabled && !$params['is_moderator']) {
1083  $cnt_active_pos_query = " AND (pos_status = {$this->db->quote(1, 'integer')} OR pos_author_id = {$this->db->quote($user_id, 'integer')}) ";
1084  $cnt_join_type = "INNER";
1085  }
1086  $query =
1087  "SELECT COUNT(DISTINCT(thr_pk)) cnt
1088  FROM frm_threads
1089  {$cnt_join_type} JOIN frm_posts
1090  ON pos_thr_fk = thr_pk {$cnt_active_pos_query}
1091  WHERE thr_top_fk = %s {$excluded_ids_condition}
1092  ";
1093  $res = $this->db->queryF($query, array('integer'), array($a_topic_id));
1094  $cntData = $this->db->fetchAssoc($res);
1095  $cnt = (int) $cntData['cnt'];
1096 
1097  $active_query = '';
1098  $active_inner_query = '';
1099  $having = '';
1100  if ($is_post_activation_enabled && !$params['is_moderator']) {
1101  $active_query = ' AND (pos_status = %s OR pos_author_id = %s) ';
1102  $active_inner_query = ' AND (ipos.pos_status = %s OR ipos.pos_author_id = %s) ';
1103  $having = ' HAVING num_posts > 0';
1104  }
1105 
1106  $threads = array();
1107  $data = array();
1108  $data_types = array();
1109 
1110  $optional_fields = '';
1111  if ($frm_props->isIsThreadRatingEnabled()) {
1112  $optional_fields = ',avg_rating';
1113  }
1114  if ($frm_props->getThreadSorting() == 1) {
1115  $optional_fields = ',thread_sorting';
1116  }
1117 
1118  $additional_sort = '';
1119  if ($frm_props->getThreadSorting()) {
1120  $additional_sort .= ' , thread_sorting ASC ';
1121  }
1122 
1123  if ($params['order_column'] == 'thr_subject') {
1124  $dynamic_columns = array(', thr_subject ' . $params['order_direction']);
1125  } elseif ($params['order_column'] == 'num_posts') {
1126  $dynamic_columns = array(', thr_num_posts ' . $params['order_direction']);
1127  } elseif ($params['order_column'] == 'num_visit') {
1128  $dynamic_columns = array(', visits ' . $params['order_direction']);
1129  } else {
1130  $dynamic_columns = array(', post_date ' . $params['order_direction']);
1131  }
1132 
1133  if ($frm_props->isIsThreadRatingEnabled()) {
1134  $dynamic_columns[] = ' ,avg_rating ' . $params['order_direction'];
1135  }
1136  if ('rating' == strtolower($params['order_column'])) {
1137  $dynamic_columns = array_reverse($dynamic_columns);
1138  }
1139  $additional_sort .= implode(' ', $dynamic_columns);
1140 
1141  if (!$this->user->isAnonymous()) {
1142  $query = "SELECT
1143  (CASE WHEN COUNT(DISTINCT(notification_id)) > 0 THEN 1 ELSE 0 END) usr_notification_is_enabled,
1144  MAX(pos_date) post_date,
1145  SUM(tree1.parent_pos != 0) num_posts,
1146  SUM(tree1.parent_pos != 0) - SUM(tree1.parent_pos != 0 AND postread.post_id IS NOT NULL) num_unread_posts, ";
1147 
1148  // new posts query
1149  if ($frm_overview_setting == ilForumProperties::FORUM_OVERVIEW_WITH_NEW_POSTS) {
1150  $query .= "
1151  (SELECT COUNT(DISTINCT(ipos.pos_pk))
1152  FROM frm_posts ipos
1153  INNER JOIN frm_posts_tree treenew
1154  ON treenew.pos_fk = ipos.pos_pk
1155  LEFT JOIN frm_user_read iread ON iread.post_id = ipos.pos_pk AND iread.usr_id = %s
1156  LEFT JOIN frm_thread_access iacc ON (iacc.thread_id = ipos.pos_thr_fk AND iacc.usr_id = %s)
1157  WHERE ipos.pos_thr_fk = thr_pk
1158  AND treenew.parent_pos != 0
1159  AND (ipos.pos_update > iacc.access_old_ts
1160  OR
1161  (iacc.access_old IS NULL AND (ipos.pos_update > " . $this->db->quote(date('Y-m-d H:i:s', NEW_DEADLINE), 'timestamp') . "))
1162  )
1163 
1164  AND ipos.pos_author_id != %s
1165  AND iread.usr_id IS NULL $active_inner_query
1166  ) num_new_posts, ";
1167  }
1168 
1169  $query .= " thr_pk, thr_top_fk, thr_subject, thr_author_id, thr_display_user_id, thr_usr_alias, thr_num_posts, thr_last_post, thr_date, thr_update, visits, frm_threads.import_name, is_sticky, is_closed
1170  {$optional_fields}
1171  FROM frm_threads
1172 
1173  LEFT JOIN frm_notification
1174  ON frm_notification.thread_id = thr_pk
1175  AND frm_notification.user_id = %s
1176 
1177  LEFT JOIN frm_posts
1178  ON pos_thr_fk = thr_pk $active_query
1179  LEFT JOIN frm_posts_tree tree1
1180  ON tree1.pos_fk = frm_posts.pos_pk
1181  LEFT JOIN frm_user_read postread
1182  ON postread.post_id = pos_pk
1183  AND postread.usr_id = %s";
1184 
1185  $query .= " WHERE thr_top_fk = %s
1186  {$excluded_ids_condition}
1187  GROUP BY thr_pk, thr_top_fk, thr_subject, thr_author_id, thr_display_user_id, thr_usr_alias, thr_num_posts, thr_last_post, thr_date, thr_update, visits, frm_threads.import_name, is_sticky, is_closed
1188  {$optional_fields}
1189  {$having}
1190  ORDER BY is_sticky DESC {$additional_sort}, thr_date DESC";
1191 
1192 
1193  // data_types for new posts query and $active_inner_query
1194  if ($frm_overview_setting == ilForumProperties::FORUM_OVERVIEW_WITH_NEW_POSTS) {
1195  $data_types[] = 'integer';
1196  $data_types[] = 'integer';
1197  $data_types[] = 'integer';
1198  if ($is_post_activation_enabled && !$params['is_moderator']) {
1199  array_push($data_types, 'integer', 'integer');
1200  }
1201  }
1202  $data_types[] = 'integer';
1203  if ($is_post_activation_enabled && !$params['is_moderator']) {
1204  array_push($data_types, 'integer', 'integer');
1205  }
1206  $data_types[] = 'integer';
1207  $data_types[] = 'integer';
1208 
1209  // data_values for new posts query and $active_inner_query
1210  if ($frm_overview_setting == ilForumProperties::FORUM_OVERVIEW_WITH_NEW_POSTS) {
1211  $data[] = $user_id;
1212  $data[] = $user_id;
1213  $data[] = $user_id;
1214  if ($is_post_activation_enabled && !$params['is_moderator']) {
1215  array_push($data, '1', $user_id);
1216  }
1217  }
1218  $data[] = $user_id;
1219  if ($is_post_activation_enabled && !$params['is_moderator']) {
1220  array_push($data, '1', $user_id);
1221  }
1222  $data[] = $user_id;
1223  $data[] = $a_topic_id;
1224  } else {
1225  $query = "SELECT
1226  0 usr_notification_is_enabled,
1227  MAX(pos_date) post_date,
1228  COUNT(DISTINCT(tree1.pos_fk)) num_posts,
1229  COUNT(DISTINCT(tree1.pos_fk)) num_unread_posts,
1230  COUNT(DISTINCT(tree1.pos_fk)) num_new_posts,
1231  thr_pk, thr_top_fk, thr_subject, thr_author_id, thr_display_user_id, thr_usr_alias, thr_num_posts, thr_last_post, thr_date, thr_update, visits, frm_threads.import_name, is_sticky, is_closed
1232  {$optional_fields}
1233  FROM frm_threads
1234 
1235  LEFT JOIN frm_posts
1236  ON pos_thr_fk = thr_pk $active_query
1237  LEFT JOIN frm_posts_tree tree1
1238  ON tree1.pos_fk = frm_posts.pos_pk AND tree1.parent_pos != 0
1239  ";
1240 
1241  $query .= " WHERE thr_top_fk = %s
1242  {$excluded_ids_condition}
1243  GROUP BY thr_pk, thr_top_fk, thr_subject, thr_author_id, thr_display_user_id, thr_usr_alias, thr_num_posts, thr_last_post, thr_date, thr_update, visits, frm_threads.import_name, is_sticky, is_closed
1244  {$optional_fields}
1245  {$having}
1246  ORDER BY is_sticky DESC {$additional_sort}, thr_date DESC";
1247 
1248  if ($is_post_activation_enabled && !$params['is_moderator']) {
1249  array_push($data_types, 'integer', 'integer');
1250  }
1251  $data_types[] = 'integer';
1252  if ($is_post_activation_enabled && !$params['is_moderator']) {
1253  array_push($data, '1', $user_id);
1254  }
1255  $data[] = $a_topic_id;
1256  }
1257 
1258  if ($limit || $offset) {
1259  $this->db->setLimit($limit, $offset);
1260  }
1261  $res = $this->db->queryF($query, $data_types, $data);
1262 
1263  $threadIds = [];
1264  while ($row = $this->db->fetchAssoc($res)) {
1265  $thread = new ilForumTopic($row['thr_pk'], $params['is_moderator'], true);
1266  $thread->assignData($row);
1267  $threads[$row['thr_pk']] = $thread;
1268  $threadIds[] = $row['thr_pk'];
1269  }
1270 
1271  $inner_last_active_post_condition = "";
1272  if ($is_post_activation_enabled && !$params['is_moderator']) {
1273  $inner_last_active_post_condition = sprintf(
1274  " AND (iposts.pos_status = %s OR (iposts.pos_status = %s AND iposts.pos_author_id = %s)) ",
1275  $this->db->quote(1, 'integer'),
1276  $this->db->quote(0, 'integer'),
1277  $this->db->quote($this->user->getId(), 'integer')
1278  );
1279  }
1280 
1281  $post_res = $this->db->query(
1282  '
1283  SELECT frm_posts.*
1284  FROM frm_posts
1285  INNER JOIN (
1286  SELECT pos_thr_fk, MAX(iposts.pos_date) i_pos_date
1287  FROM frm_posts iposts
1288  WHERE ' . $this->db->in('iposts.pos_thr_fk', $threadIds, false, 'integer') . '
1289  ' . $inner_last_active_post_condition . '
1290  GROUP BY pos_thr_fk
1291  ) opost ON frm_posts.pos_thr_fk = opost.pos_thr_fk AND frm_posts.pos_date = opost.i_pos_date'
1292  );
1293 
1294  while ($post_row = $this->db->fetchAssoc($post_res)) {
1295  $tmp_obj = new ilForumPost($post_row['pos_pk'], $params['is_moderator'], true);
1296 
1297  $tmp_obj->setPosAuthorId($post_row['pos_author_id']);
1298  $tmp_obj->setDisplayUserId($post_row['pos_display_user_id']);
1299  $tmp_obj->setUserAlias($post_row['pos_usr_alias']);
1300  $tmp_obj->setImportName($post_row['import_name']);
1301  $tmp_obj->setId($post_row['pos_pk']);
1302  $tmp_obj->setCreateDate($post_row['pos_date']);
1303 
1304  $threads[$post_row['pos_thr_fk']]->setLastPostForThreadOverview($tmp_obj);
1305  }
1306 
1307  return array(
1308  'items' => $threads,
1309  'cnt' => $cnt
1310  );
1311  }
1312 
1317  public function getUserStatistic($is_moderator = false)
1318  {
1319  $statistic = array();
1320 
1321  $data_types = array();
1322  $data = array();
1323 
1324  $query = "SELECT COUNT(f.pos_display_user_id) ranking, u.login, p.value, u.lastname, u.firstname
1325  FROM frm_posts f
1326  INNER JOIN frm_posts_tree t
1327  ON f.pos_pk = t.pos_fk
1328  INNER JOIN frm_threads th
1329  ON t.thr_fk = th.thr_pk
1330  INNER JOIN usr_data u
1331  ON u.usr_id = f.pos_display_user_id
1332  INNER JOIN frm_data d
1333  ON d.top_pk = f.pos_top_fk
1334  LEFT JOIN usr_pref p
1335  ON p.usr_id = u.usr_id AND p.keyword = %s
1336  WHERE 1 = 1 AND t.parent_pos != 0";
1337 
1338  array_push($data_types, 'text');
1339  array_push($data, 'public_profile');
1340 
1341  if (!$is_moderator) {
1342  $query .= ' AND (pos_status = %s
1343  OR (pos_status = %s
1344  AND pos_author_id = %s ))';
1345 
1346  array_push($data_types, 'integer', 'integer', 'integer');
1347  array_push($data, '1', '0', $this->user->getId());
1348  }
1349 
1350  $query .= ' AND d.top_frm_fk = %s
1351  GROUP BY pos_display_user_id, u.login, p.value,u.lastname, u.firstname';
1352 
1353  array_push($data_types, 'integer');
1354  array_push($data, $this->getForumId());
1355 
1356  $res = $this->db->queryf($query, $data_types, $data);
1357 
1358  $counter = 0;
1359  while ($row = $this->db->fetchAssoc($res)) {
1360  $statistic[$counter][] = $row['ranking'];
1361  $statistic[$counter][] = $row['login'];
1362 
1363  $lastname = '';
1364  $firstname = '';
1365  if (!$this->user->isAnonymous() && in_array($row['value'], array('y', 'g')) ||
1366  $this->user->isAnonymous() && 'g' == $row['value']) {
1367  $lastname = $row['lastname'];
1368  $firstname = $row['firstname'];
1369  }
1370 
1371  $statistic[$counter][] = $lastname;
1372  $statistic[$counter][] = $firstname;
1373 
1374  ++$counter;
1375  }
1376 
1377  return is_array($statistic) ? $statistic : array();
1378  }
1379 
1387  public function getFirstPostByThread($a_thread_id)
1388  {
1389  $res = $this->db->queryf(
1390  '
1391  SELECT * FROM frm_posts_tree
1392  WHERE thr_fk = %s
1393  AND parent_pos = %s',
1394  array('integer', 'integer'),
1395  array($a_thread_id, '0')
1396  );
1397 
1398  $row = $this->db->fetchObject($res);
1399 
1400  return $row->pos_fk ? $row->pos_fk : 0;
1401  }
1402 
1409  public function getModerators()
1410  {
1411  return self::_getModerators($this->getForumRefId());
1412  }
1413 
1421  public static function _getModerators($a_ref_id)
1422  {
1423  global $DIC;
1424  $rbacreview = $DIC->rbac()->review();
1425 
1426  $role_arr = $rbacreview->getRolesOfRoleFolder($a_ref_id);
1427  foreach ($role_arr as $role_id) {
1428  if (ilObject::_lookupTitle($role_id) == 'il_frm_moderator_' . $a_ref_id) {
1429  return $rbacreview->assignedUsers($role_id);
1430  }
1431  }
1432 
1433  return array();
1434  }
1435 
1444  public static function _isModerator($a_ref_id, $a_usr_id)
1445  {
1446  if (!self::$moderators_by_ref_id_map[$a_ref_id]) {
1447  self::$moderators_by_ref_id_map[$a_ref_id] = self::_getModerators($a_ref_id);
1448  }
1449  return in_array($a_usr_id, self::$moderators_by_ref_id_map[$a_ref_id]);
1450  }
1451 
1459  public function countUserArticles($a_user_id)
1460  {
1461  $res = $this->db->queryf(
1462  '
1463  SELECT * FROM frm_data
1464  INNER JOIN frm_posts ON pos_top_fk = top_pk
1465  INNER JOIN frm_posts_tree tree1
1466  ON tree1.pos_fk = frm_posts.pos_pk
1467  AND tree1.parent_pos != 0
1468  WHERE top_frm_fk = %s
1469  AND pos_author_id = %s',
1470  array('integer', 'integer'),
1471  array($this->getForumId(), $a_user_id)
1472  );
1473 
1474  return $res->numRows();
1475  }
1476 
1477  public function countActiveUserArticles($a_user_id)
1478  {
1479  $res = $this->db->queryf(
1480  '
1481  SELECT * FROM frm_data
1482  INNER JOIN frm_posts ON pos_top_fk = top_pk
1483  INNER JOIN frm_posts_tree tree1
1484  ON tree1.pos_fk = frm_posts.pos_pk
1485  AND tree1.parent_pos != 0
1486  WHERE top_frm_fk = %s
1487  AND (pos_status = %s
1488  OR (pos_status = %s
1489  AND pos_author_id = %s
1490  )
1491  )
1492  AND pos_author_id = %s',
1493  array('integer', 'integer', 'integer', 'integer', 'integer'),
1494  array($this->getForumId(),'1', '0', $this->user->getId(), $a_user_id)
1495  );
1496 
1497  return $res->numRows();
1498  }
1499 
1506  public function convertDate($date)
1507  {
1509  }
1510 
1518  public function addPostTree($a_tree_id, $a_node_id = -1, $a_date = '')
1519  {
1520  $a_date = $a_date ? $a_date : date("Y-m-d H:i:s");
1521 
1522  if ($a_node_id <= 0) {
1523  $a_node_id = $a_tree_id;
1524  }
1525 
1526  $nextId = $this->db->nextId('frm_posts_tree');
1527 
1528  $this->db->manipulateF(
1529  '
1530  INSERT INTO frm_posts_tree
1531  ( fpt_pk,
1532  thr_fk,
1533  pos_fk,
1534  parent_pos,
1535  lft,
1536  rgt,
1537  depth,
1538  fpt_date
1539  )
1540  VALUES(%s, %s, %s, %s, %s, %s, %s, %s )',
1541  array('integer','integer', 'integer', 'integer', 'integer', 'integer', 'integer', 'timestamp'),
1542  array($nextId, $a_tree_id, $a_node_id, '0', '1', '2', '1', $a_date)
1543  );
1544 
1545  return true;
1546  }
1547 
1555  public function insertPostNode($a_node_id, $a_parent_id, $tree_id, $a_date = '')
1556  {
1557  $a_date = $a_date ? $a_date : date("Y-m-d H:i:s");
1558 
1559  // get left value
1560  $sql_res = $this->db->queryf(
1561  '
1562  SELECT * FROM frm_posts_tree
1563  WHERE pos_fk = %s
1564  AND thr_fk = %s',
1565  array('integer', 'integer'),
1566  array($a_parent_id, $tree_id)
1567  );
1568 
1569  $res = $this->db->fetchObject($sql_res);
1570 
1571  $left = $res->lft;
1572 
1573  $lft = $left + 1;
1574  $rgt = $left + 2;
1575 
1576  // spread tree
1577  $this->db->manipulateF(
1578  '
1579  UPDATE frm_posts_tree
1580  SET lft = CASE
1581  WHEN lft > %s
1582  THEN lft + 2
1583  ELSE lft
1584  END,
1585  rgt = CASE
1586  WHEN rgt > %s
1587  THEN rgt + 2
1588  ELSE rgt
1589  END
1590  WHERE thr_fk = %s',
1591  array('integer', 'integer', 'integer'),
1592  array($left, $left, $tree_id)
1593  );
1594 
1595  $depth = $this->getPostDepth($a_parent_id, $tree_id) + 1;
1596 
1597  // insert node
1598  $nextId = $this->db->nextId('frm_posts_tree');
1599  $this->db->manipulateF(
1600  '
1601  INSERT INTO frm_posts_tree
1602  ( fpt_pk,
1603  thr_fk,
1604  pos_fk,
1605  parent_pos,
1606  lft,
1607  rgt,
1608  depth,
1609  fpt_date
1610  )
1611  VALUES(%s,%s,%s, %s, %s, %s,%s, %s)',
1612  array('integer','integer', 'integer', 'integer', 'integer', 'integer', 'integer', 'timestamp'),
1613  array( $nextId,
1614  $tree_id,
1615  $a_node_id,
1616  $a_parent_id,
1617  $lft,
1618  $rgt,
1619  $depth,
1620  $a_date)
1621  );
1622  }
1623 
1631  public function getPostDepth($a_node_id, $tree_id)
1632  {
1633  if ($tree_id) {
1634  $sql_res = $this->db->queryf(
1635  '
1636  SELECT depth FROM frm_posts_tree
1637  WHERE pos_fk = %s
1638  AND thr_fk = %s',
1639  array('integer', 'integer'),
1640  array($a_node_id, $tree_id)
1641  );
1642 
1643  $res = $this->db->fetchObject($sql_res);
1644 
1645  return $res->depth;
1646  } else {
1647  return 0;
1648  }
1649  }
1650 
1657  public function getFirstPostNode($tree_id)
1658  {
1659  $res = $this->db->queryf(
1660  '
1661  SELECT * FROM frm_posts, frm_posts_tree
1662  WHERE pos_pk = pos_fk
1663  AND parent_pos = %s
1664  AND thr_fk = %s',
1665  array('integer', 'integer'),
1666  array('0', $tree_id)
1667  );
1668 
1669  $row = $this->db->fetchObject($res);
1670 
1671  return $this->fetchPostNodeData($row);
1672  }
1673 
1680  public function getPostNode($post_id)
1681  {
1682  $res = $this->db->queryf(
1683  '
1684  SELECT * FROM frm_posts, frm_posts_tree
1685  WHERE pos_pk = pos_fk
1686  AND pos_pk = %s',
1687  array('integer'),
1688  array($post_id)
1689  );
1690 
1691  $row = $this->db->fetchObject($res);
1692 
1693  return $this->fetchPostNodeData($row);
1694  }
1695 
1702  public function fetchPostNodeData($a_row)
1703  {
1704  if (ilObject::_exists($a_row->pos_display_user_id)) {
1705  $tmp_user = new ilObjUser($a_row->pos_display_user_id);
1706  $fullname = $tmp_user->getFullname();
1707  $loginname = $tmp_user->getLogin();
1708  }
1709 
1710  $fullname = $fullname ? $fullname : ($a_row->import_name ? $a_row->import_name : $this->lng->txt("unknown"));
1711 
1712  $data = array(
1713  "pos_pk" => $a_row->pos_pk,
1714  'pos_thr_fk' => (int) $a_row->pos_thr_fk,
1715  "child" => $a_row->pos_pk,
1716  "author" => $a_row->pos_display_user_id,
1717  "alias" => $a_row->pos_usr_alias,
1718  "title" => $fullname,
1719  "loginname" => $loginname,
1720  "type" => "post",
1721  "message" => $a_row->pos_message,
1722  "subject" => $a_row->pos_subject,
1723  "pos_cens_com" => $a_row->pos_cens_com,
1724  "pos_cens" => $a_row->pos_cens,
1725  // "date" => $a_row->date,
1726  "date" => $a_row->fpt_date,
1727  "create_date" => $a_row->pos_date,
1728  "update" => $a_row->pos_update,
1729  "update_user" => $a_row->update_user,
1730  "tree" => $a_row->thr_fk,
1731  "parent" => $a_row->parent_pos,
1732  "lft" => $a_row->lft,
1733  "rgt" => $a_row->rgt,
1734  "depth" => $a_row->depth,
1735  "id" => $a_row->fpt_pk,
1736  "notify" => $a_row->notify,
1737  "import_name" => $a_row->import_name,
1738  "pos_status" => $a_row->pos_status
1739  );
1740 
1741  return $data ? $data : array();
1742  }
1743 
1750  public function deletePostTree($a_node)
1751  {
1752  // GET LEFT AND RIGHT VALUES
1753  $res = $this->db->queryf(
1754  '
1755  SELECT * FROM frm_posts_tree
1756  WHERE thr_fk = %s
1757  AND pos_fk = %s
1758  AND parent_pos = %s',
1759  array('integer', 'integer', 'integer'),
1760  array($a_node['tree'], $a_node['pos_pk'], $a_node['parent'])
1761  );
1762 
1763  while ($row = $this->db->fetchObject($res)) {
1764  $a_node["lft"] = $row->lft;
1765  $a_node["rgt"] = $row->rgt;
1766  }
1767 
1768  $diff = $a_node["rgt"] - $a_node["lft"] + 1;
1769 
1770  // get data of posts
1771  $result = $this->db->queryf(
1772  '
1773  SELECT * FROM frm_posts_tree
1774  WHERE lft BETWEEN %s AND %s
1775  AND thr_fk = %s',
1776  array('integer', 'integer', 'integer'),
1777  array($a_node['lft'], $a_node['rgt'], $a_node['tree'])
1778  );
1779 
1780  $del_id = array();
1781 
1782  while ($treeData = $this->db->fetchAssoc($result)) {
1783  $del_id[] = $treeData["pos_fk"];
1784  }
1785 
1786  // delete subtree
1787  $this->db->manipulateF(
1788  '
1789  DELETE FROM frm_posts_tree
1790  WHERE lft BETWEEN %s AND %s
1791  AND thr_fk = %s',
1792  array('integer', 'integer', 'integer'),
1793  array($a_node['lft'], $a_node['rgt'], $a_node['tree'])
1794  );
1795 
1796  // close gaps
1797  $this->db->manipulateF(
1798  '
1799  UPDATE frm_posts_tree
1800  SET lft = CASE
1801  WHEN lft > %s
1802  THEN lft - %s
1803  ELSE lft
1804  END,
1805  rgt = CASE
1806  WHEN rgt > %s
1807  THEN rgt - %s
1808  ELSE rgt
1809  END
1810  WHERE thr_fk = %s',
1811  array('integer', 'integer', 'integer', 'integer', 'integer'),
1812  array($a_node['lft'], $diff, $a_node['lft'], $diff, $a_node['tree'])
1813  );
1814 
1815  return $del_id;
1816  }
1817 
1823  public function updateVisits($ID)
1824  {
1825  $checkTime = time() - (60 * 60);
1826 
1827  if ($_SESSION["frm_visit_" . $this->dbTable . "_" . $ID] < $checkTime) {
1828  $_SESSION["frm_visit_" . $this->dbTable . "_" . $ID] = time();
1829  $query = 'UPDATE ' . $this->dbTable . ' SET visits = visits + 1 WHERE ';
1830 
1831  $data_type = array();
1832  $data_value = array();
1833 
1834  if ($this->getMDB2Query() != '' && $this->getMDB2DataType() != '' && $this->getMDB2DataValue() != '') {
1835  $query .= $this->getMDB2Query();
1836  $data_type = $data_type + $this->getMDB2DataType();
1837  $data_value = $data_value + $this->getMDB2DataValue();
1838 
1839  $res = $this->db->queryf($query, $data_type, $data_value);
1840  }
1841  }
1842  }
1843 
1851  public function prepareText($text, $edit = 0, $quote_user = '', $type = '')
1852  {
1853  if ($type == 'export') {
1854  $this->replQuote1 = "<blockquote class=\"quote\"><hr size=\"1\" color=\"#000000\">";
1855  $this->replQuote2 = "<hr size=\"1\" color=\"#000000\"/></blockquote>";
1856  }
1857 
1858  if ($edit == 1) {
1859  // add login name of quoted users
1860  $lname = ($quote_user != "")
1861  ? '="' . $quote_user . '"'
1862  : "";
1863 
1864  $text = "[quote$lname]" . $text . "[/quote]";
1865  } else {
1866  // check for quotation
1867  $startZ = substr_count($text, "[quote"); // also count [quote="..."]
1868  $endZ = substr_count($text, "[/quote]");
1869 
1870  if ($startZ > 0 || $endZ > 0) {
1871  // add missing opening and closing tags
1872  if ($startZ > $endZ) {
1873  $diff = $startZ - $endZ;
1874 
1875  for ($i = 0; $i < $diff; $i++) {
1876  if ($type == 'export') {
1877  $text .= $this->txtQuote2;
1878  } else {
1879  $text .= "[/quote]";
1880  }
1881  }
1882  } elseif ($startZ < $endZ) {
1883  $diff = $endZ - $startZ;
1884 
1885  for ($i = 0; $i < $diff; $i++) {
1886  if ($type == 'export') {
1887  $text = $this->txtQuote1 . $text;
1888  } else {
1889  $text = "[quote]" . $text;
1890  }
1891  }
1892  }
1893 
1894  if ($edit == 0) {
1895  $text = preg_replace(
1896  '@\[(quote\s*?=\s*?"([^"]*?)"\s*?)\]@i',
1897  $this->replQuote1 . '<div class="ilForumQuoteHead">' . $this->lng->txt('quote') . ' ($2)</div>',
1898  $text
1899  );
1900 
1901  $text = str_replace(
1902  "[quote]",
1903  $this->replQuote1 . '<div class="ilForumQuoteHead">' . $this->lng->txt("quote") . '</div>',
1904  $text
1905  );
1906 
1907  $text = str_replace("[/quote]", $this->replQuote2, $text);
1908  }
1909  }
1910  }
1911 
1912  if ($type != 'export') {
1913  if ($edit == 0) {
1914  $text = ilMathJax::getInstance()->insertLatexImages($text, "<span class\=\"latex\">", "<\/span>");
1915  $text = ilMathJax::getInstance()->insertLatexImages($text, "\[tex\]", "\[\/tex\]");
1916  }
1917 
1918  // workaround for preventing template engine
1919  // from hiding text that is enclosed
1920  // in curly brackets (e.g. "{a}")
1921  $text = str_replace("{", "&#123;", $text);
1922  $text = str_replace("}", "&#125;", $text);
1923  }
1924 
1925  return $text;
1926  }
1927 
1928  public function __deletePostFiles($a_ids)
1929  {
1930  if (!is_array($a_ids)) {
1931  return false;
1932  }
1933 
1934  $tmp_file_obj = new ilFileDataForum($this->getForumId());
1935  foreach ($a_ids as $pos_id) {
1936  $tmp_file_obj->setPosId($pos_id);
1937  $files = $tmp_file_obj->getFilesOfPost();
1938  foreach ($files as $file) {
1939  $tmp_file_obj->unlinkFile($file["name"]);
1940  }
1941  }
1942  unset($tmp_file_obj);
1943  return true;
1944  }
1945 
1946  public function getImportName()
1947  {
1948  return $this->import_name;
1949  }
1950  public function setImportName($a_import_name)
1951  {
1952  $this->import_name = $a_import_name;
1953  }
1954 
1961  public function enableForumNotification($user_id)
1962  {
1963  if (!$this->isForumNotificationEnabled($user_id)) {
1964  /* Remove all notifications of threads that belong to the forum */
1965 
1966  $res = $this->db->queryf(
1967  '
1968  SELECT frm_notification.thread_id FROM frm_data, frm_notification, frm_threads
1969  WHERE frm_notification.user_id = %s
1970  AND frm_notification.thread_id = frm_threads.thr_pk
1971  AND frm_threads.thr_top_fk = frm_data.top_pk
1972  AND frm_data.top_frm_fk = %s
1973  GROUP BY frm_notification.thread_id',
1974  array('integer', 'integer'),
1975  array($user_id, $this->id)
1976  );
1977 
1978  if (is_object($res) && $res->numRows() > 0) {
1979  $thread_data = array();
1980  $thread_data_types = array();
1981 
1982  $query = ' DELETE FROM frm_notification
1983  WHERE user_id = %s
1984  AND thread_id IN (';
1985 
1986  array_push($thread_data, $user_id);
1987  array_push($thread_data_types, 'integer');
1988 
1989  $counter = 1;
1990 
1991  while ($row = $this->db->fetchAssoc($res)) {
1992  if ($counter < $res->numRows()) {
1993  $query .= '%s, ';
1994  array_push($thread_data, $row['thread_id']);
1995  array_push($thread_data_types, 'integer');
1996  }
1997 
1998  if ($counter == $res->numRows()) {
1999  $query .= '%s)';
2000  array_push($thread_data, $row['thread_id']);
2001  array_push($thread_data_types, 'integer');
2002  }
2003  $counter++;
2004  }
2005 
2006  $this->db->manipulateF($query, $thread_data_types, $thread_data);
2007  }
2008 
2009  /* Insert forum notification */
2010 
2011  $nextId = $this->db->nextId('frm_notification');
2012 
2013  $this->db->manipulateF(
2014  '
2015  INSERT INTO frm_notification
2016  ( notification_id,
2017  user_id,
2018  frm_id
2019  )
2020  VALUES(%s, %s, %s)',
2021  array('integer','integer', 'integer'),
2022  array($nextId, $user_id, $this->id)
2023  );
2024  }
2025  return true;
2026  }
2027 
2034  public function disableForumNotification($user_id)
2035  {
2036  $this->db->manipulateF(
2037  '
2038  DELETE FROM frm_notification
2039  WHERE user_id = %s
2040  AND frm_id = %s',
2041  array('integer', 'integer'),
2042  array($user_id, $this->id)
2043  );
2044 
2045  return true;
2046  }
2047 
2053  public function isForumNotificationEnabled($user_id)
2054  {
2055  $result = $this->db->queryf(
2056  'SELECT COUNT(*) cnt FROM frm_notification WHERE user_id = %s AND frm_id = %s',
2057  array('integer', 'integer'),
2058  array($user_id, $this->id)
2059  );
2060 
2061  while ($record = $this->db->fetchAssoc($result)) {
2062  return (bool) $record['cnt'];
2063  }
2064 
2065  return false;
2066  }
2067 
2078  public function enableThreadNotification($user_id, $thread_id)
2079  {
2080  if (!$this->isThreadNotificationEnabled($user_id, $thread_id)) {
2081  $nextId = $this->db->nextId('frm_notification');
2082  $this->db->manipulateF(
2083  '
2084  INSERT INTO frm_notification
2085  ( notification_id,
2086  user_id,
2087  thread_id
2088  )
2089  VALUES (%s, %s, %s)',
2090  array('integer', 'integer', 'integer'),
2091  array($nextId, $user_id, $thread_id)
2092  );
2093  }
2094 
2095  return true;
2096  }
2097 
2104  public function isThreadNotificationEnabled($user_id, $thread_id)
2105  {
2106  $result = $this->db->queryf(
2107  '
2108  SELECT COUNT(*) cnt FROM frm_notification
2109  WHERE user_id = %s
2110  AND thread_id = %s',
2111  array('integer', 'integer'),
2112  array($user_id, $thread_id)
2113  );
2114 
2115 
2116  while ($record = $this->db->fetchAssoc($result)) {
2117  return (bool) $record['cnt'];
2118  }
2119 
2120  return false;
2121  }
2122 
2129  public static function _getThreads($a_obj_id, $a_sort_mode = self::SORT_DATE)
2130  {
2131  global $DIC;
2132  $ilDB = $DIC->database();
2133 
2134  switch ($a_sort_mode) {
2135  case self::SORT_DATE:
2136  $sort = 'thr_date';
2137  break;
2138 
2139  case self::SORT_TITLE:
2140  default:
2141  $sort = 'thr_subject';
2142  break;
2143  }
2144 
2145  $res = $ilDB->queryf(
2146  '
2147  SELECT * FROM frm_threads
2148  JOIN frm_data ON top_pk = thr_top_fk
2149  WHERE top_frm_fk = %s
2150  ORDER BY %s',
2151  array('integer', 'text'),
2152  array($a_obj_id, $sort)
2153  );
2154 
2155  while ($row = $ilDB->fetchObject($res)) {
2156  $threads[$row->thr_pk] = $row->thr_subject;
2157  }
2158  return $threads ? $threads : array();
2159  }
2160 
2161  public static function _lookupObjIdForForumId($a_for_id)
2162  {
2163  global $DIC;
2164  $ilDB = $DIC->database();
2165 
2166  $res = $ilDB->queryf(
2167  '
2168  SELECT top_frm_fk FROM frm_data
2169  WHERE top_pk = %s',
2170  array('integer'),
2171  array($a_for_id)
2172  );
2173 
2174  if ($fdata = $ilDB->fetchAssoc($res)) {
2175  return $fdata["top_frm_fk"];
2176  }
2177  return false;
2178  }
2179 
2180  public static function updateLastPostByObjId($a_obj_id)
2181  {
2182  global $DIC;
2183  $ilDB = $DIC->database();
2184  // get latest post of forum and update last_post
2185  $ilDB->setLimit(1);
2186  $res2 = $ilDB->queryf(
2187  '
2188  SELECT pos_top_fk, pos_thr_fk, pos_pk FROM frm_posts, frm_data
2189  WHERE pos_top_fk = top_pk
2190  AND top_frm_fk = %s
2191  ORDER BY pos_date DESC',
2192  array('integer'),
2193  array($a_obj_id)
2194  );
2195 
2196  if ($res2->numRows() == 0) {
2197  $lastPost_top = "";
2198  } else {
2199  $z = 0;
2200 
2201  while ($selData = $ilDB->fetchAssoc($res2)) {
2202  if ($z > 0) {
2203  break;
2204  }
2205 
2206  $lastPost_top = $selData["pos_top_fk"] . "#" . $selData["pos_thr_fk"] . "#" . $selData["pos_pk"];
2207  $z++;
2208  }
2209  }
2210 
2211  $ilDB->update(
2212  'frm_data',
2213  array('top_last_post' => array('text', $lastPost_top)),
2214  array('top_frm_fk' => array('integer', $a_obj_id))
2215  );
2216  }
2217 
2223  public function mergeThreads($source_id, $target_id)
2224  {
2225  // selected source and target objects
2226  $sourceThread = new \ilForumTopic((int) $source_id);
2227  $targetThread = new \ilForumTopic((int) $target_id);
2228 
2229  if ($sourceThread->getForumId() != $targetThread->getForumId()) {
2230  throw new \ilException('not_allowed_to_merge_into_another_forum');
2231  }
2232 
2233  // use the "older" thread as target
2234  if ($sourceThread->getCreateDate() > $targetThread->getCreateDate()) {
2235  $sourceThreadForMerge = $sourceThread;
2236  $targetThreadForMerge = $targetThread;
2237  } else {
2238  $sourceThreadForMerge = $targetThread;
2239  $targetThreadForMerge = $sourceThread;
2240  }
2241 
2242  $threadSubject = $targetThreadForMerge->getSubject();
2243 
2244  $targetWasClosedBeforeMerge = (bool) $targetThreadForMerge->isClosed();
2245  $sourceThreadForMerge->close();
2246 
2247  if (false === $targetWasClosedBeforeMerge) {
2248  $targetThreadForMerge->close();
2249  }
2250 
2251  $allSourcePostings = $sourceThreadForMerge->getAllPosts();
2252  $sourceThreadRootNode = $sourceThreadForMerge->getFirstPostNode();
2253  $targetThreadRootNode = $targetThreadForMerge->getFirstPostNode();
2254 
2255  $sourceThreadRootArray = $this->getPostNode($sourceThreadRootNode->getId());
2256 
2257  $ilAtomQuery = $this->db->buildAtomQuery();
2258  $ilAtomQuery->addTableLock('frm_posts');
2259  $ilAtomQuery->addTableLock('frm_posts_tree');
2260  $ilAtomQuery->addTableLock('frm_threads');
2261  $ilAtomQuery->addTableLock('frm_data');
2262 
2263  $ilAtomQuery->addQueryCallable(static function (ilDBInterface $ilDB) use (
2264  $targetThreadForMerge,
2265  $sourceThreadForMerge,
2266  $targetThreadRootNode,
2267  $sourceThreadRootNode,
2268  $allSourcePostings
2269  ) {
2270  $targetRootNodeRgt = $targetThreadRootNode->getRgt();
2271  $targetRootNodeId = $targetThreadRootNode->getId();
2272 
2273  // update target root node rgt: Ignore the root node itself from the source (= -2)
2275  $targetThreadRootNode->getId(),
2276  ($targetThreadRootNode->getRgt() + $sourceThreadRootNode->getRgt() - 2)
2277  );
2278 
2279  // get source post tree and update posts tree
2280  foreach ($allSourcePostings as $post) {
2281  $post_obj = new ilForumPost($post->pos_pk);
2282 
2283  if ((int) $post_obj->getId() === (int) $sourceThreadRootNode->getId()) {
2284  // Ignore the source root node (MUST be deleted later)
2285  continue;
2286  }
2287 
2288  $tree = new \ilForumPostsTree();
2289  $tree->setPosFk($post->pos_pk);
2290 
2291  if ((int) $post_obj->getParentId() === (int) $sourceThreadRootNode->getId()) {
2292  $tree->setParentPos($targetRootNodeId);
2293  } else {
2294  $tree->setParentPos($post_obj->getParentId());
2295  }
2296 
2297  $tree->setLft(($post_obj->getLft() + $targetRootNodeRgt) - 2);
2298  $tree->setRgt(($post_obj->getRgt() + $targetRootNodeRgt) - 2);
2299 
2300  $tree->setDepth($post_obj->getDepth());
2301  $tree->setTargetThreadId($targetThreadForMerge->getId());
2302  $tree->setSourceThreadId($sourceThreadForMerge->getId());
2303 
2304  $tree->merge();
2305  }
2306 
2307  // update frm_posts pos_thr_fk = target_thr_id
2309  (int) $sourceThreadForMerge->getId(),
2310  (int) $targetThreadForMerge->getId(),
2311  [(int) $sourceThreadRootNode->getId(),]
2312  );
2313  });
2314  $ilAtomQuery->run();
2315 
2316  // check notifications
2317  \ilForumNotification::mergeThreadNotificiations($sourceThreadForMerge->getId(), $targetThreadForMerge->getId());
2318 
2319  // delete frm_thread_access entries
2320  \ilObjForum::_deleteAccessEntries($sourceThreadForMerge->getId());
2321 
2322  // update frm_user_read
2323  \ilObjForum::mergeForumUserRead($sourceThreadForMerge->getId(), $targetThreadForMerge->getId());
2324 
2325  // update visits, thr_num_posts, last_post, subject
2326  $lastPostString = $targetThreadForMerge->getLastPostString();
2327  $exp = explode('#', $lastPostString);
2328  if (array_key_exists(2, $exp)) {
2329  $exp[2] = $targetThreadForMerge->getLastPost()->getId();
2330  $lastPostString = implode('#', $exp);
2331  }
2332 
2333  $frm_topic_obj = new \ilForumTopic(0, false, true);
2334  $frm_topic_obj->setNumPosts((int) $sourceThreadForMerge->getNumPosts() + (int) $targetThreadForMerge->getNumPosts());
2335  $frm_topic_obj->setVisits((int) $sourceThreadForMerge->getVisits() + (int) $targetThreadForMerge->getVisits());
2336  $frm_topic_obj->setLastPostString($lastPostString);
2337  $frm_topic_obj->setSubject($threadSubject);
2338  $frm_topic_obj->setId($targetThreadForMerge->getId());
2339  $frm_topic_obj->updateMergedThread();
2340 
2341  if (!$targetWasClosedBeforeMerge) {
2342  $targetThreadForMerge->reopen();
2343  }
2344 
2345  // raise event for updating existing drafts
2346  $GLOBALS['ilAppEventHandler']->raise(
2347  'Modules/Forum',
2348  'mergedThreads',
2349  [
2350  'source_thread_id' => $sourceThreadForMerge->getId(),
2351  'target_thread_id' => $targetThreadForMerge->getId()
2352  ]
2353  );
2354 
2355  $this->deletePost($sourceThreadRootArray, false);
2356  }
2357 }
getAllThreads($a_topic_id, array $params=array(), $limit=0, $offset=0)
Class ilForumPostDraft.
insert()
Inserts the object data into database.
static _isModerator($a_ref_id, $a_usr_id)
checks whether a user is moderator of a given forum object
static mergeForumUserRead($merge_source_thread_id, $merge_target_thread_id)
setForumId($a_obj_id)
set object id which refers to ILIAS obj_id
static _getMobsOfObject($a_type, $a_id, $a_usage_hist_nr=0, $a_lang="-")
get mobs of object
const SORT_TITLE
static _lookupObjIdForForumId($a_for_id)
Class Forum core functions for forum.
settings()
Definition: settings.php:2
getOnePost($post)
get one post-dataset
deletePost($postIdOrArray, $raiseEvents=true)
Delete post and sub-posts.
static _lookupPostMessage($a_id)
$data
Definition: storeScorm.php:23
const IL_CAL_DATETIME
$_SESSION["AccountId"]
$result
$mobs
Definition: imgupload.php:54
const DEFAULT_PAGE_HITS
$type
static _exists($a_id, $a_reference=false, $a_type=null)
checks if an object exists in object_data
countUserArticles($a_user_id)
get number of articles from given user-ID
getForumRefId()
get forum ref_id public
disableForumNotification($user_id)
Disable a user&#39;s notification about new posts in this forum.
postCensorship($message, $pos_pk, $cens=0)
update dataset in frm_posts with censorship info
getMDB2DataType()
get content of additional condition
getPostDepth($a_node_id, $tree_id)
Return depth of an object private.
$target_id
Definition: goto.php:51
insertPostNode($a_node_id, $a_parent_id, $tree_id, $a_date='')
insert node under parent node public
static mergePosts(int $sourceThreadId, int $targetThreadId, array $excludedPostIds=[])
static _lookupTitle($a_id)
lookup object title
static updateTargetRootRgt($root_node_id, $rgt)
getFirstPostByThread($a_thread_id)
Get first post of thread.
mergeThreads($source_id, $target_id)
updateVisits($ID)
update page hits of given forum- or thread-ID public
getUserStatistic($is_moderator=false)
static _removeUsage($a_mob_id, $a_type, $a_id, $a_usage_hist_nr=0, $a_lang="-")
Remove usage of mob in another container.
getFirstPostNode($tree_id)
get data of the first node from frm_posts_tree and frm_posts public
static _replaceMediaObjectImageSrc($a_text, $a_direction=0, $nic=IL_INST_ID)
Replaces image source from mob image urls with the mob id or replaces mob id with the correct image s...
fetchPostNodeData($a_row)
get data of parent node from frm_posts_tree and frm_posts private
static formatDate(ilDateTime $date, $a_skip_day=false, $a_include_wd=false, $include_seconds=false)
Format a date public.
user()
Definition: user.php:4
enableForumNotification($user_id)
Enable a user&#39;s notification about new posts in this forum.
static mergeThreadNotificiations($merge_source_thread_id, $merge_target_thread_id)
Class ilForumDraftHistory.
setCreateDate($a_createdate)
static _lookupObjectId($a_ref_id)
lookup object id
setImportName($a_import_name)
setDbTable($dbTable)
set database table
static _deleteReadEntries($a_post_id)
__deletePostFiles($a_ids)
static getInstance($a_obj_id=0)
generatePost($forum_id, $thread_id, $author_id, $display_user_id, $message, $parent_pos, $notify, $subject='', $alias='', $date='', $status=1, $send_activation_mail=0)
generate new dataset in frm_posts
setMDB2WhereCondition($query_string, $data_type, $data_value)
set content for additional condition
foreach($_POST as $key=> $value) $res
getOneThread()
get one thread-dataset by WhereCondition
prepareText($text, $edit=0, $quote_user='', $type='')
prepares given string public
generateThread(ilForumTopic $thread, $message, $notify, $notify_posts, $status=1, bool $withFirstVisibleEntry=true)
enableThreadNotification($user_id, $thread_id)
no usage? ..delete .
static updateLastPostByObjId($a_obj_id)
const NEWS_NOTICE
getOrderField()
get name of orderField
global $DIC
Definition: goto.php:24
if(!defined('PATH_SEPARATOR')) $GLOBALS['_PEAR_default_error_mode']
Definition: PEAR.php:64
getModerators()
get all users assigned to local role il_frm_moderator_<frm_ref_id>
deletePostTree($a_node)
delete node and the whole subtree under this node public
Class ilObjMediaObject.
$query
const SORT_DATE
getForumId()
get forum id public
isForumNotificationEnabled($user_id)
Check whether a user&#39;s notification about new posts in this forum is enabled (result > 0) or not (res...
convertDate($date)
converts the date format
static _getThreads($a_obj_id, $a_sort_mode=self::SORT_DATE)
Get thread infos of object.
getOneTopic()
get one topic-dataset by WhereCondition
countActiveUserArticles($a_user_id)
getMDB2Query()
get content of additional condition
addPostTree($a_tree_id, $a_node_id=-1, $a_date='')
create a new post-tree
static _deleteAccessEntries($a_thread_id)
isThreadNotificationEnabled($user_id, $thread_id)
Check whether a user&#39;s notification about new posts in a thread is enabled (result > 0) or not (resul...
static getFirstNewsIdForContext( $a_context_obj_id, $a_context_obj_type, $a_context_sub_obj_id="", $a_context_sub_obj_type="")
Get first new id of news set related to a certain context.
moveThreads($thread_ids=array(), $src_ref_id=0, $dest_top_frm_fk=0)
Moves all chosen threads and their posts to a new forum.
static _lookupLanguage($a_usr_id)
static getInstance()
Singleton: get instance.
setPageHits($pageHits)
This class handles all operations on files for the forum object.
global $ilDB
static $moderators_by_ref_id_map
static getInstanceByRefId($a_ref_id, $stop_on_error=true)
get an instance of an Ilias object by reference id
getDbTable()
get name of database table
$message
Definition: xapiexit.php:14
static _getModerators($a_ref_id)
get all users assigned to local role il_frm_moderator_<frm_ref_id> (static)
const NEWS_USERS
static _getLanguageInstanceByUsrId($usr_id)
Get the ilLanguage instance for the passed user id.
static _exists($a_id, $a_reference=false, $a_type=null)
checks wether a lm content object with specified id exists or not
getMDB2DataValue()
get content of additional condition
getPageHits()
get number of max.
enableNotification($a_user_id)
Enable a user&#39;s notification about new posts in a thread.
setForumRefId($a_ref_id)
set reference id which refers to ILIAS obj_id
setLanguage($lng)
setImportName($a_import_name)
setOrderField($orderField)
set database field for sorting results
$i
Definition: metadata.php:24
Class to report exception.
__construct()
Constructor public.
getPostNode($post_id)
get data of given node from frm_posts_tree and frm_posts public