ILIAS  release_4-3 Revision
 All Data Structures Namespaces Files Functions Variables Groups Pages
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 
4 require_once 'Services/Object/classes/class.ilObject.php';
5 require_once 'Modules/Forum/classes/class.ilForum.php';
6 require_once 'Modules/Forum/classes/class.ilFileDataForum.php';
7 require_once 'Modules/Forum/classes/class.ilForumProperties.php';
8 
18 class ilObjForum extends ilObject
19 {
25  public $Forum;
26 
27 // private $objProperties = null;
28 
33  protected static $obj_id_to_forum_id_cache = array();
34 
39  protected static $ref_id_to_forum_id_cache = array();
40 
45  protected static $forum_statistics_cache = array();
46 
51  protected static $forum_last_post_cache = array();
52 
59  public function __construct($a_id = 0, $a_call_by_reference = true)
60  {
61  $this->type = 'frm';
62  parent::__construct($a_id, $a_call_by_reference);
63 
64  /*
65  * this constant is used for the information if a single post is marked as new
66  * All threads/posts created before this date are never marked as new
67  * Default is 8 weeks
68  *
69  */
70  $new_deadline = time() - 60 * 60 * 24 * 7 * ($this->ilias->getSetting('frm_store_new') ?
71  $this->ilias->getSetting('frm_store_new') :
72  8);
73  define('NEW_DEADLINE', $new_deadline);
74 
75  // TODO: needs to rewrite scripts that are using Forum outside this class
76  $this->Forum = new ilForum();
77  }
78 
84  function getDiskUsage()
85  {
86  require_once("./Modules/File/classes/class.ilObjFileAccess.php");
87  return ilObjForumAccess::_lookupDiskUsage($this->id);
88  }
89 
90  public static function _lookupThreadSubject($a_thread_id)
91  {
96  global $ilDB;
97 
98  $res = $ilDB->queryf('
99  SELECT thr_subject FROM frm_threads WHERE thr_pk = %s',
100  array('integer'), array($a_thread_id));
101 
102  while($row = $ilDB->fetchObject($res))
103  {
104  return $row->thr_subject;
105  }
106  return '';
107  }
108 
109  // METHODS FOR UN-READ STATUS
110  public function getCountUnread($a_usr_id, $a_thread_id = 0)
111  {
112 // return $this->_getCountUnread($this->getId(),$a_usr_id,$a_thread_id);
113 // }
114 //
115 // function _getCountUnread($a_frm_id, $a_usr_id,$a_thread_id = 0)
116 // {
117 
118  $a_frm_id = $this->getId();
119 
123  global $ilBench, $ilDB;
124 
125  $ilBench->start("Forum", 'getCountRead');
126  if(!$a_thread_id)
127  {
128  // Get topic_id
129  $res = $ilDB->queryf('
130  SELECT top_pk FROM frm_data WHERE top_frm_fk = %s',
131  array('integer'), array($a_frm_id));
132 
133 
134  while($row = $ilDB->fetchObject($res))
135  {
136  $topic_id = $row->top_pk;
137  }
138 
139  // Get number of posts
140  $res = $ilDB->queryf('
141  SELECT COUNT(pos_pk) num_posts FROM frm_posts
142  WHERE pos_top_fk = %s',
143  array('integer'), array($topic_id));
144 
145  while($row = $ilDB->fetchObject($res))
146  {
147  $num_posts = $row->num_posts;
148  }
149 
150  $res = $ilDB->queryf('
151  SELECT COUNT(post_id) count_read FROM frm_user_read
152  WHERE obj_id = %s
153  AND usr_id = %s',
154  array('integer', 'integer'), array($a_frm_id, $a_usr_id));
155 
156  while($row = $ilDB->fetchObject($res))
157  {
158  $count_read = $row->count_read;
159  }
160  $unread = $num_posts - $count_read;
161 
162  $ilBench->stop("Forum", 'getCountRead');
163  return $unread > 0 ? $unread : 0;
164  }
165  else
166  {
167  $res = $ilDB->queryf('
168  SELECT COUNT(pos_pk) num_posts FROM frm_posts
169  WHERE pos_thr_fk = %s',
170  array('integer'), array($a_thread_id));
171 
172  $row = $ilDB->fetchObject($res);
173  $num_posts = $row->num_posts;
174 
175  $res = $ilDB->queryf('
176  SELECT COUNT(post_id) count_read FROM frm_user_read
177  WHERE obj_id = %s
178  AND usr_id = %s
179  AND thread_id = %s',
180  array('integer', 'integer', 'integer'), array($a_frm_id, $a_frm_id, $a_thread_id));
181 
182  $row = $ilDB->fetchObject($res);
183  $count_read = $row->count_read;
184 
185  $unread = $num_posts - $count_read;
186 
187  $ilBench->stop("Forum", 'getCountRead');
188  return $unread > 0 ? $unread : 0;
189  }
190  $ilBench->stop("Forum", 'getCountRead');
191  return false;
192  }
193 
194 
195  public function markThreadRead($a_usr_id, $a_thread_id)
196  {
200  global $ilDB;
201 
202  // Get all post ids
203  $res = $ilDB->queryf('
204  SELECT * FROM frm_posts WHERE pos_thr_fk = %s',
205  array('integer'), array($a_thread_id));
206 
207  while($row = $ilDB->fetchObject($res))
208  {
209  $this->markPostRead($a_usr_id, $a_thread_id, $row->pos_pk);
210  }
211  return true;
212  }
213 
214  public function markAllThreadsRead($a_usr_id)
215  {
219  global $ilDB;
220 
221  $res = $ilDB->queryf('
222  SELECT * FROM frm_data, frm_threads
223  WHERE top_frm_fk = %s
224  AND top_pk = thr_top_fk',
225  array('integer'), array($this->getId()));
226 
227  while($row = $ilDB->fetchObject($res))
228  {
229  $this->markThreadRead($a_usr_id, $row->thr_pk);
230  }
231 
232  return true;
233  }
234 
235 
236  public function markPostRead($a_usr_id, $a_thread_id, $a_post_id)
237  {
241  global $ilDB;
242 
243  // CHECK IF ENTRY EXISTS
244  $res = $ilDB->queryf('
245  SELECT * FROM frm_user_read
246  WHERE usr_id = %s
247  AND obj_id = %s
248  AND thread_id = %s
249  AND post_id = %s',
250  array('integer', 'integer', 'integer', 'integer'),
251  array($a_usr_id, $this->getId(), $a_thread_id, $a_post_id));
252 
253  if($ilDB->numRows($res))
254  {
255  return true;
256  }
257 
258  $res = $ilDB->manipulateF('
259  INSERT INTO frm_user_read
260  ( usr_id,
261  obj_id,
262  thread_id,
263  post_id
264  )
265  VALUES (%s,%s,%s,%s)',
266  array('integer', 'integer', 'integer', 'integer'),
267  array($a_usr_id, $this->getId(), $a_thread_id, $a_post_id));
268 
269  return true;
270  }
271 
272  public function markPostUnread($a_user_id, $a_post_id)
273  {
277  global $ilDB;
278 
279  $res = $ilDB->manipulateF('
280  DELETE FROM frm_user_read
281  WHERE usr_id = %s
282  AND post_id = %s',
283  array('integer', 'integer'),
284  array($a_user_id, $a_post_id));
285  }
286 
287  public function isRead($a_usr_id, $a_post_id)
288  {
292  global $ilDB;
293 
294  $res = $ilDB->queryf('
295  SELECT * FROM frm_user_read
296  WHERE usr_id = %s
297  AND post_id = %s',
298  array('integer', 'integer'),
299  array($a_usr_id, $a_post_id));
300 
301  return $ilDB->numRows($res) ? true : false;
302  }
303 
304  public function updateLastAccess($a_usr_id, $a_thread_id)
305  {
309  global $ilDB;
310 
311  $res = $ilDB->queryf('
312  SELECT * FROM frm_thread_access
313  WHERE usr_id = %s
314  AND obj_id = %s
315  AND thread_id = %s',
316  array('integer', 'integer', 'integer'),
317  array($a_usr_id, $this->getId(), $a_thread_id));
318 
319  if($ilDB->numRows($res))
320  {
321  $ilDB->manipulateF('
322  UPDATE frm_thread_access
323  SET access_last = %s
324  WHERE usr_id = %s
325  AND obj_id = %s
326  AND thread_id = %s',
327  array('integer', 'integer', 'integer', 'integer'),
328  array(time(), $a_usr_id, $this->getId(), $a_thread_id));
329 
330  }
331  else
332  {
333  $ilDB->manipulateF('
334  INSERT INTO frm_thread_access
335  ( access_last,
336  access_old,
337  usr_id,
338  obj_id,
339  thread_id)
340  VALUES (%s,%s,%s,%s,%s)',
341  array('integer', 'integer', 'integer', 'integer', 'integer'),
342  array(time(), '0', $a_usr_id, $this->getId(), $a_thread_id));
343 
344  }
345 
346  return true;
347  }
348 
353  public static function _updateOldAccess($a_usr_id)
354  {
359  global $ilDB, $ilias;
360 
361  $ilDB->manipulateF('
362  UPDATE frm_thread_access
363  SET access_old = access_last
364  WHERE usr_id = %s',
365  array('integer'), array($a_usr_id));
366 
367  $set = $ilDB->query("SELECT * FROM frm_thread_access " .
368  " WHERE usr_id = " . $ilDB->quote($a_usr_id, "integer")
369  );
370  while($rec = $ilDB->fetchAssoc($set))
371  {
372  $ilDB->manipulate("UPDATE frm_thread_access SET " .
373  " access_old_ts = " . $ilDB->quote(date('Y-m-d H:i:s', $rec["access_old"]), "timestamp") .
374  " WHERE usr_id = " . $ilDB->quote($rec["usr_id"], "integer") .
375  " AND obj_id = " . $ilDB->quote($rec["obj_id"], "integer") .
376  " AND thread_id = " . $ilDB->quote($rec["thread_id"], "integer")
377  );
378  }
379 
380  $new_deadline = time() - 60 * 60 * 24 * 7 * ($ilias->getSetting('frm_store_new') ?
381  $ilias->getSetting('frm_store_new') :
382  8);
383 
384  $ilDB->manipulateF('
385  DELETE FROM frm_thread_access WHERE access_last < %s',
386  array('integer'), array($new_deadline));
387  }
388 
389  function _deleteUser($a_usr_id)
390  {
394  global $ilDB;
395 
396  $data = array($a_usr_id);
397 
398  $res = $ilDB->manipulateF('
399  DELETE FROM frm_user_read WHERE usr_id = %s',
400  array('integer'), $data
401  );
402 
403  $res = $ilDB->manipulateF('
404  DELETE FROM frm_thread_access WHERE usr_id = %s',
405  array('integer'), $data
406  );
407 
408  // delete notifications of deleted user
409  $ilDB->manipulateF('
410  DELETE FROM frm_notification WHERE user_id = %s',
411  array('integer'), $data);
412 
413  return true;
414  }
415 
416 
417  function _deleteReadEntries($a_post_id)
418  {
422  global $ilDB;
423 
424  $statement = $ilDB->manipulateF('
425  DELETE FROM frm_user_read WHERE post_id = %s',
426  array('integer'), array($a_post_id));
427 
428  return true;
429  }
430 
431  function _deleteAccessEntries($a_thread_id)
432  {
436  global $ilDB;
437 
438  $statement = $ilDB->manipulateF('
439  DELETE FROM frm_thread_access WHERE thread_id = %s',
440  array('integer'), array($a_thread_id));
441 
442  return true;
443  }
444 
449  function update()
450  {
454  global $ilDB;
455 
456  if(parent::update())
457  {
458 
459  $statement = $ilDB->manipulateF('
460  UPDATE frm_data
461  SET top_name = %s,
462  top_description = %s,
463  top_update = %s,
464  update_user = %s
465  WHERE top_frm_fk =%s',
466  array('text', 'text', 'timestamp', 'integer', 'integer'),
467  array(
468  $this->getTitle(),
469  $this->getDescription(),
470  date("Y-m-d H:i:s"),
471  (int)$_SESSION["AccountId"],
472  (int)$this->getId()
473  ));
474 
475  return true;
476  }
477 
478  return false;
479  }
480 
487  public function cloneObject($a_target_id, $a_copy_id = 0)
488  {
492  global $ilDB;
493 
494  $new_obj = parent::cloneObject($a_target_id, $a_copy_id);
495  $this->cloneAutoGeneratedRoles($new_obj);
496 
497  ilForumProperties::getInstance($this->getId())->copy($new_obj->getId());
498  $this->Forum->setMDB2WhereCondition('top_frm_fk = %s ', array('integer'), array($this->getId()));
499 
500  $topData = $this->Forum->getOneTopic();
501 
502  $nextId = $ilDB->nextId('frm_data');
503 
504  $statement = $ilDB->insert('frm_data', array(
505  'top_pk' => array('integer', $nextId),
506  'top_frm_fk' => array('integer', $new_obj->getId()),
507  'top_name' => array('text', $topData['top_name']),
508  'top_description' => array('text', $topData['top_description']),
509  'top_num_posts' => array('integer', $topData['top_num_posts']),
510  'top_num_threads' => array('integer', $topData['top_num_threads']),
511  'top_last_post' => array('text', $topData['top_last_post']),
512  'top_mods' => array('integer', !is_numeric($topData['top_mods']) ? 0 : $topData['top_mods']),
513  'top_date' => array('timestamp', $topData['top_date']),
514  'visits' => array('integer', $topData['visits']),
515  'top_update' => array('timestamp', $topData['top_update']),
516  'update_user' => array('integer', $topData['update_user']),
517  'top_usr_id' => array('integer', $topData['top_usr_id'])
518  ));
519 
520  // read options
521  include_once('Services/CopyWizard/classes/class.ilCopyWizardOptions.php');
522 
523  $cwo = ilCopyWizardOptions::_getInstance($a_copy_id);
524  $options = $cwo->getOptions($this->getRefId());
525 
526  $options['threads'] = $this->Forum->_getThreads($this->getId());
527 
528  // Generate starting threads
529  include_once('Modules/Forum/classes/class.ilFileDataForum.php');
530 
531  $new_frm = $new_obj->Forum;
532  $new_frm->setMDB2WhereCondition('top_frm_fk = %s ', array('integer'), array($new_obj->getId()));
533 
534  $new_frm->setForumId($new_obj->getId());
535  $new_frm->setForumRefId($new_obj->getRefId());
536 
537  $new_topic = $new_frm->getOneTopic();
538  foreach($options['threads'] as $thread_id=> $thread_subject)
539  {
540  $this->Forum->setMDB2WhereCondition('thr_pk = %s ', array('integer'), array($thread_id));
541 
542  $old_thread = $this->Forum->getOneThread();
543 
544  $old_post_id = $this->Forum->getFirstPostByThread($old_thread['thr_pk']);
545  $old_post = $this->Forum->getOnePost($old_post_id);
546 
547  // Now create new thread and first post
548  $new_post = $new_frm->generateThread($new_topic['top_pk'],
549  $old_thread['thr_usr_id'],
550  $old_thread['thr_subject'],
551  ilForum::_lookupPostMessage($old_post_id),
552  $old_post['notify'],
553  0,
554  $old_thread['thr_usr_alias'],
555  $old_thread['thr_date']);
556  // Copy attachments
557  $old_forum_files = new ilFileDataForum($this->getId(), $old_post_id);
558  $old_forum_files->ilClone($new_obj->getId(), $new_post);
559  }
560 
561  return $new_obj;
562  }
563 
570  public function cloneAutoGeneratedRoles($new_obj)
571  {
576  global $ilLog, $rbacadmin, $rbacreview;
577 
578  $moderator = ilObjForum::_lookupModeratorRole($this->getRefId());
579  $new_moderator = ilObjForum::_lookupModeratorRole($new_obj->getRefId());
580  $source_rolf = $rbacreview->getRoleFolderIdOfObject($this->getRefId());
581  $target_rolf = $rbacreview->getRoleFolderIdOfObject($new_obj->getRefId());
582 
583  if(!$moderator || !$new_moderator || !$source_rolf || !$target_rolf)
584  {
585  $ilLog->write(__METHOD__ . ' : Error cloning auto generated role: il_frm_moderator');
586  }
587  $rbacadmin->copyRolePermissions($moderator, $source_rolf, $target_rolf, $new_moderator, true);
588  $ilLog->write(__METHOD__ . ' : Finished copying of role il_frm_moderator.');
589 
590  include_once './Modules/Forum/classes/class.ilForumModerators.php';
591  $obj_mods = new ilForumModerators($this->getRefId());
592 
593  $old_mods = array();
594  $old_mods = $obj_mods->getCurrentModerators();
595 
596  foreach($old_mods as $user_id)
597  {
598  $rbacadmin->assignUser($new_moderator, $user_id);
599  }
600  }
601 
607  public function delete()
608  {
612  global $ilDB;
613 
614  // always call parent delete function first!!
615  if(!parent::delete())
616  {
617  return false;
618  }
619 
620  // delete attachments
621  $tmp_file_obj =& new ilFileDataForum($this->getId());
622  $tmp_file_obj->delete();
623  unset($tmp_file_obj);
624 
625  $this->Forum->setMDB2WhereCondition('top_frm_fk = %s ', array('integer'), array($this->getId()));
626 
627  $topData = $this->Forum->getOneTopic();
628 
629  $threads = $this->Forum->getAllThreads($topData['top_pk']);
630  foreach($threads['items'] as $thread)
631  {
632  $data = array($thread->getId());
633 
634  // delete tree
635  $statement = $ilDB->manipulateF('
636  DELETE FROM frm_posts_tree WHERE thr_fk = %s',
637  array('integer'), $data);
638 
639  // delete posts
640  $statement = $ilDB->manipulateF('
641  DELETE FROM frm_posts WHERE pos_thr_fk = %s',
642  array('integer'), $data);
643 
644  // delete threads
645  $statement = $ilDB->manipulateF('
646  DELETE FROM frm_threads WHERE thr_pk = %s',
647  array('integer'), $data);
648 
649  }
650 
651  $data = array($this->getId());
652  // delete forum
653  $statement = $ilDB->manipulateF('
654  DELETE FROM frm_data WHERE top_frm_fk = %s',
655  array('integer'), $data);
656 
657  // delete settings
658  $statement = $ilDB->manipulateF('
659  DELETE FROM frm_settings WHERE obj_id = %s',
660  array('integer'), $data);
661 
662  // delete read infos
663  $statement = $ilDB->manipulateF('
664  DELETE FROM frm_user_read WHERE obj_id = %s',
665  array('integer'), $data);
666 
667  // delete thread access entries
668  $statement = $ilDB->manipulateF('
669  DELETE FROM frm_thread_access WHERE obj_id = %s',
670  array('integer'), $data);
671 
672  //delete notifications
673  $ilDB->manipulateF('
674  DELETE FROM frm_notification WHERE frm_id = %s',
675  array('integer'), $data);
676 
677  return true;
678  }
679 
685  public function initDefaultRoles()
686  {
692  global $rbacadmin, $rbacreview, $ilDB;
693 
694  // Create a local role folder
695  $rolf_obj = $this->createRoleFolder();
696 
697  // CREATE Moderator role
698  $role_obj = $rolf_obj->createRole("il_frm_moderator_" . $this->getRefId(), "Moderator of forum obj_no." . $this->getId());
699  $roles[] = $role_obj->getId();
700 
701  // SET PERMISSION TEMPLATE OF NEW LOCAL ADMIN ROLE
702  $statement = $ilDB->queryf('
703  SELECT obj_id FROM object_data
704  WHERE type = %s
705  AND title = %s',
706  array('text', 'text'),
707  array('rolt', 'il_frm_moderator'));
708 
709  $res = $ilDB->fetchObject($statement);
710 
711  $rbacadmin->copyRoleTemplatePermissions($res->obj_id, ROLE_FOLDER_ID, $rolf_obj->getRefId(), $role_obj->getId());
712 
713  // SET OBJECT PERMISSIONS OF COURSE OBJECT
714  $ops = $rbacreview->getOperationsOfRole($role_obj->getId(), "frm", $rolf_obj->getRefId());
715  $rbacadmin->grantPermission($role_obj->getId(), $ops, $this->getRefId());
716 
717  return $roles ? $roles : array();
718  }
719 
727  public static function _lookupModeratorRole($a_ref_id)
728  {
732  global $ilDB;
733 
734  $mod_title = 'il_frm_moderator_' . $a_ref_id;
735 
736  $res = $ilDB->queryf('
737  SELECT * FROM object_data WHERE title = %s',
738  array('text'), array($mod_title));
739 
740  while($row = $ilDB->fetchObject($res))
741  {
742  return $row->obj_id;
743  }
744  return 0;
745  }
746 
747 
748  public function createSettings()
749  {
750  // news settings (public notifications yes/no)
751  include_once("./Services/News/classes/class.ilNewsItem.php");
752  $default_visibility = ilNewsItem::_getDefaultVisibilityForRefId($_GET["ref_id"]);
753  if($default_visibility == "public")
754  {
755  ilBlockSetting::_write("news", "public_notifications", 1, 0, $this->getId());
756  }
757 
758  return true;
759  }
760 
761  public function saveData($a_roles = array())
762  {
767  global $ilUser, $ilDB;
768 
769  $nextId = $ilDB->nextId('frm_data');
770 
771  $top_data = array(
772  'top_frm_fk' => $this->getId(),
773  'top_name' => $this->getTitle(),
774  'top_description' => $this->getDescription(),
775  'top_num_posts' => 0,
776  'top_num_threads' => 0,
777  'top_last_post' => NULL,
778  'top_mods' => !is_numeric($a_roles[0]) ? 0 : $a_roles[0],
779  'top_usr_id' => $ilUser->getId(),
780  'top_date' => ilUtil::now()
781  );
782 
783  $statement = $ilDB->manipulateF('
784  INSERT INTO frm_data
785  (
786  top_pk,
787  top_frm_fk,
788  top_name,
789  top_description,
790  top_num_posts,
791  top_num_threads,
792  top_last_post,
793  top_mods,
794  top_date,
795  top_usr_id
796  )
797  VALUES(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)',
798  array('integer', 'integer', 'text', 'text', 'integer', 'integer', 'text', 'integer', 'timestamp', 'integer'),
799  array(
800  $nextId,
801  $top_data['top_frm_fk'],
802  $top_data['top_name'],
803  $top_data['top_description'],
804  $top_data['top_num_posts'],
805  $top_data['top_num_threads'],
806  $top_data['top_last_post'],
807  $top_data['top_mods'],
808  $top_data['top_date'],
809  $top_data['top_usr_id']
810  ));
811  }
812 
818  public static function lookupForumIdByObjId($obj_id)
819  {
820  if(array_key_exists($obj_id, self::$obj_id_to_forum_id_cache))
821  {
822  return (int)self::$obj_id_to_forum_id_cache[$obj_id];
823  }
824 
825  self::preloadForumIdsByObjIds(array($obj_id));
826 
827  return (int)self::$obj_id_to_forum_id_cache[$obj_id];
828  }
829 
835  public static function lookupForumIdByRefId($ref_id)
836  {
837  if(array_key_exists($ref_id, self::$ref_id_to_forum_id_cache))
838  {
839  return (int)self::$ref_id_to_forum_id_cache[$ref_id];
840  }
841 
842  self::preloadForumIdsByRefIds(array($ref_id));
843 
844  return (int)self::$ref_id_to_forum_id_cache[$ref_id];
845  }
846 
851  public static function preloadForumIdsByObjIds(array $obj_ids)
852  {
856  global $ilDB;
857 
858  if(count($obj_ids) == 1)
859  {
860  $in = " objr.obj_id = " . $ilDB->quote(current($obj_ids), 'integer') . " ";
861  }
862  else
863  {
864  $in = $ilDB->in('objr.obj_id', $obj_ids, false, 'integer');
865  }
866  $query = "
867  SELECT frmd.top_pk, objr.ref_id, objr.obj_id
868  FROM object_reference objr
869  INNER JOIN frm_data frmd ON frmd.top_frm_fk = objr.obj_id
870  WHERE $in
871  ";
872  $res = $ilDB->query($query);
873 
874  // Prepare cache array
875  foreach($obj_ids as $obj_id)
876  {
877  self::$obj_id_to_forum_id_cache[$obj_id] = null;
878  }
879 
880  while($row = $ilDB->fetchAssoc($res))
881  {
882  self::$obj_id_to_forum_id_cache[$row['obj_id']] = $row['top_pk'];
883  self::$ref_id_to_forum_id_cache[$row['ref_id']] = $row['top_pk'];
884  }
885  }
886 
891  public static function preloadForumIdsByRefIds(array $ref_ids)
892  {
896  global $ilDB;
897 
898  if(count($ref_ids) == 1)
899  {
900  $in = " objr.ref_id = " . $ilDB->quote(current($ref_ids), 'integer') . " ";
901  }
902  else
903  {
904  $in = $ilDB->in('objr.ref_id', $ref_ids, false, 'integer');
905  }
906  $query = "
907  SELECT frmd.top_pk, objr.ref_id, objr.obj_id
908  FROM object_reference objr
909  INNER JOIN frm_data frmd ON frmd.top_frm_fk = objr.obj_id
910  WHERE $in
911  ";
912  $res = $ilDB->query($query);
913 
914  // Prepare cache array
915  foreach($ref_ids as $ref_id)
916  {
917  self::$ref_id_to_forum_id_cache[$ref_id] = null;
918  }
919 
920  while($row = $ilDB->fetchAssoc($res))
921  {
922  self::$obj_id_to_forum_id_cache[$row['obj_id']] = $row['top_pk'];
923  self::$ref_id_to_forum_id_cache[$row['ref_id']] = $row['top_pk'];
924  }
925  }
926 
932  public static function lookupStatisticsByRefId($ref_id)
933  {
940  global $ilAccess, $ilUser, $ilDB, $ilSetting;
941 
942  if(isset(self::$forum_statistics_cache[$ref_id]))
943  {
944  return self::$forum_statistics_cache[$ref_id];
945  }
946 
947  $statistics = array(
948  'num_posts' => 0,
949  'num_unread_posts' => 0,
950  'num_new_posts' => 0
951  );
952 
953  $forumId = self::lookupForumIdByRefId($ref_id);
954  if(!$forumId)
955  {
956  self::$forum_statistics_cache[$ref_id] = $statistics;
957  return self::$forum_statistics_cache[$ref_id];
958  }
959 
960  $act_clause = '';
961  if(!$ilAccess->checkAccess('moderate_frm', '', $ref_id))
962  {
963  $act_clause .= " AND (frm_posts.pos_status = " . $ilDB->quote(1, "integer") . " OR frm_posts.pos_usr_id = " . $ilDB->quote($ilUser->getId(), "integer") . ") ";
964  }
965 
966  $new_deadline = date('Y-m-d H:i:s', time() - 60 * 60 * 24 * 7 * ($ilSetting->get('frm_store_new') ? $ilSetting->get('frm_store_new') : 8));
967 
968  if(!$ilUser->isAnonymous())
969  {
970  $query = "
971  (SELECT COUNT(frm_posts.pos_pk) cnt
972  FROM frm_posts
973  INNER JOIN frm_threads ON frm_posts.pos_thr_fk = frm_threads.thr_pk
974  WHERE frm_threads.thr_top_fk = %s $act_clause)
975 
976  UNION ALL
977 
978  (SELECT COUNT(DISTINCT(frm_user_read.post_id)) cnt
979  FROM frm_user_read
980  INNER JOIN frm_posts ON frm_user_read.post_id = frm_posts.pos_pk
981  INNER JOIN frm_threads ON frm_threads.thr_pk = frm_posts.pos_thr_fk
982  WHERE frm_user_read.usr_id = %s AND frm_posts.pos_top_fk = %s $act_clause)
983 
984  UNION ALL
985 
986  (SELECT COUNT(frm_posts.pos_pk) cnt
987  FROM frm_posts
988  LEFT JOIN frm_user_read ON (post_id = frm_posts.pos_pk AND frm_user_read.usr_id = %s)
989  LEFT JOIN frm_thread_access ON (frm_thread_access.thread_id = frm_posts.pos_thr_fk AND frm_thread_access.usr_id = %s)
990  WHERE frm_posts.pos_top_fk = %s
991  AND ((frm_posts.pos_date > frm_thread_access.access_old_ts OR frm_posts.pos_update > frm_thread_access.access_old_ts)
992  OR (frm_thread_access.access_old IS NULL AND (frm_posts.pos_date > %s OR frm_posts.pos_update > %s)))
993  AND frm_posts.pos_usr_id != %s
994  AND frm_user_read.usr_id IS NULL $act_clause)
995  ";
996  $types = array('integer', 'integer', 'integer', 'integer', 'integer', 'integer', 'timestamp', 'timestamp', 'integer');
997  $values = array($forumId, $ilUser->getId(), $forumId, $ilUser->getId(), $ilUser->getId(), $forumId, $new_deadline, $new_deadline, $ilUser->getId());
998  $mapping = array_keys($statistics);
999  $res = $ilDB->queryF(
1000  $query,
1001  $types,
1002  $values
1003  );
1004  for($i = 0; $i <= 2; $i++)
1005  {
1006  $row = $ilDB->fetchAssoc($res);
1007 
1008  $statistics[$mapping[$i]] = (int)$row['cnt'];
1009 
1010  if($i == 1)
1011  {
1012  // unread = all - read
1013  $statistics[$mapping[$i]] = $statistics[$mapping[$i - 1]] - $statistics[$mapping[$i]];
1014  }
1015  }
1016  }
1017  else
1018  {
1019  $query = "
1020  SELECT COUNT(frm_posts.pos_pk) cnt
1021  FROM frm_posts
1022  INNER JOIN frm_threads ON frm_posts.pos_thr_fk = frm_threads.thr_pk
1023  WHERE frm_threads.thr_top_fk = %s $act_clause
1024  ";
1025  $types = array('integer');
1026  $values = array($forumId);
1027  $res = $ilDB->queryF(
1028  $query,
1029  $types,
1030  $values
1031  );
1032  $row = $ilDB->fetchAssoc($res);
1033 
1034  $statistics = array(
1035  'num_posts' => $row['cnt'],
1036  'num_unread_posts' => $row['cnt'],
1037  'num_new_posts' => $row['cnt']
1038  );
1039  }
1040 
1041  self::$forum_statistics_cache[$ref_id] = $statistics;
1042 
1043  return self::$forum_statistics_cache[$ref_id];
1044  }
1045 
1051  public static function lookupLastPostByRefId($ref_id)
1052  {
1058  global $ilAccess, $ilUser, $ilDB;
1059 
1060  if(isset(self::$forum_last_post_cache[$ref_id]))
1061  {
1062  return self::$forum_last_post_cache[$ref_id];
1063  }
1064 
1065  $forumId = self::lookupForumIdByRefId($ref_id);
1066  if(!$forumId)
1067  {
1068  self::$forum_last_post_cache[$ref_id] = array();
1069  return self::$forum_last_post_cache[$ref_id];
1070  }
1071 
1072  $act_clause = '';
1073  if(!$ilAccess->checkAccess('moderate_frm', '', $ref_id))
1074  {
1075  $act_clause .= " AND (frm_posts.pos_status = " . $ilDB->quote(1, "integer") . " OR frm_posts.pos_usr_id = " . $ilDB->quote($ilUser->getId(), "integer") . ") ";
1076  }
1077 
1078  $ilDB->setLimit(1, 0);
1079  $query = "
1080  SELECT *
1081  FROM frm_posts
1082  WHERE pos_top_fk = %s $act_clause
1083  ORDER BY pos_date DESC
1084  ";
1085  $res = $ilDB->queryF(
1086  $query,
1087  array('integer'),
1088  array($forumId)
1089  );
1090 
1091  $data = $ilDB->fetchAssoc($res);
1092 
1093  self::$forum_last_post_cache[$ref_id] = is_array($data) ? $data : array();
1094 
1095  return self::$forum_last_post_cache[$ref_id];
1096  }
1097 
1104  public static function getUserIdsOfLastPostsByRefIdAndThreadIds($ref_id, array $thread_ids)
1105  {
1111  global $ilUser, $ilAccess, $ilDB;
1112 
1113  $act_clause = '';
1114  $act_inner_clause = '';
1115  if(!$ilAccess->checkAccess('moderate_frm', '', $ref_id))
1116  {
1117  $act_clause .= " AND (t1.pos_status = " . $ilDB->quote(1, "integer") . " OR t1.pos_usr_id = " . $ilDB->quote($ilUser->getId(), "integer") . ") ";
1118  $act_inner_clause .= " AND (t3.pos_status = " . $ilDB->quote(1, "integer") . " OR t3.pos_usr_id = " . $ilDB->quote($ilUser->getId(), "integer") . ") ";
1119  }
1120 
1121  $in = $ilDB->in("t1.pos_thr_fk", $thread_ids, false, 'integer');
1122  $inner_in = $ilDB->in("t3.pos_thr_fk", $thread_ids, false, 'integer');
1123 
1124  $query = "
1125  SELECT t1.pos_usr_id, t1.update_user
1126  FROM frm_posts t1
1127  INNER JOIN (
1128  SELECT t3.pos_thr_fk, MAX(t3.pos_date) pos_date
1129  FROM frm_posts t3
1130  WHERE $inner_in $act_inner_clause
1131  GROUP BY t3.pos_thr_fk
1132  ) t2 ON t2.pos_thr_fk = t1.pos_thr_fk AND t2.pos_date = t1.pos_date
1133  WHERE $in $act_clause
1134  ";
1135 
1136  $usr_ids = array();
1137 
1138  $res = $ilDB->query($query);
1139  while($row = $ilDB->fetchAssoc($res))
1140  {
1141  if((int)$row['pos_usr_id'])
1142  {
1143  $usr_ids[] = (int)$row['pos_usr_id'];
1144  }
1145  if((int)$row['update_user'])
1146  {
1147  $usr_ids[] = (int)$row['update_user'];
1148  }
1149  }
1150 
1151  return array_unique($usr_ids);
1152  }
1153 }