ILIAS  Release_4_2_x_branch Revision 61807
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.ilNewsItem.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (c) 1998-2009 ILIAS open source, Extended GPL, see docs/LICENSE */
3 
4 define("NEWS_NOTICE", 0);
5 define("NEWS_MESSAGE", 1);
6 define("NEWS_WARNING", 2);
7 
8 include_once("./Services/News/classes/class.ilNewsItemGen.php");
9 
23 {
24 
25  private static $privFeedId = false;
26  private $limitation;
27 
33  public function __construct($a_id = 0)
34  {
35  parent::__construct($a_id);
36  $this->limitation = true;
37  }
38 
39 
45  function setLimitation($a_limitation)
46  {
47  $this->limitation = $a_limitation;
48  }
49 
55  function getLimitation()
56  {
57  return $this->limitation;
58  }
59 
65  public function setContentTextIsLangVar($a_val = 0)
66  {
67  $this->content_text_is_lang_var = $a_val;
68  }
69 
75  public function getContentTextIsLangVar()
76  {
77  return $this->content_text_is_lang_var;
78  }
79 
80 
84  public function read()
85  {
86  global $ilDB;
87 
88  $query = "SELECT * FROM il_news_item WHERE id = ".
89  $ilDB->quote($this->getId(), "integer");
90  $set = $ilDB->query($query);
91  $rec = $ilDB->fetchAssoc($set);
92 
93  $this->setTitle($rec["title"]);
94  $this->setContent($rec["content"]);
95  $this->setContextObjId((int) $rec["context_obj_id"]);
96  $this->setContextObjType($rec["context_obj_type"]);
97  $this->setContextSubObjId((int) $rec["context_sub_obj_id"]);
98  $this->setContextSubObjType($rec["context_sub_obj_type"]);
99  $this->setContentType($rec["content_type"]);
100  $this->setCreationDate($rec["creation_date"]);
101  $this->setUpdateDate($rec["update_date"]);
102  $this->setUserId($rec["user_id"]);
103  $this->setVisibility($rec["visibility"]);
104  $this->setContentLong($rec["content_long"]);
105  $this->setPriority($rec["priority"]);
106  $this->setContentIsLangVar($rec["content_is_lang_var"]);
107  $this->setContentTextIsLangVar((int) $rec["content_text_is_lang_var"]);
108  $this->setMobId($rec["mob_id"]);
109  $this->setPlaytime($rec["playtime"]);
110 
111  }
112 
116  function create()
117  {
118  global $ilDB;
119 
120  // insert new record into db
121  $this->setId($ilDB->nextId("il_news_item"));
122  $ilDB->insert("il_news_item", array(
123  "id" => array("integer", $this->getId()),
124  "title" => array("text", $this->getTitle()),
125  "content" => array("clob", $this->getContent()),
126  "context_obj_id" => array("integer", (int) $this->getContextObjId()),
127  "context_obj_type" => array("text", $this->getContextObjType()),
128  "context_sub_obj_id" => array("integer", (int) $this->getContextSubObjId()),
129  "context_sub_obj_type" => array("text", $this->getContextSubObjType()),
130  "content_type" => array("text", $this->getContentType()),
131  "creation_date" => array("timestamp", ilUtil::now()),
132  "update_date" => array("timestamp", ilUtil::now()),
133  "user_id" => array("integer", $this->getUserId()),
134  "visibility" => array("text", $this->getVisibility()),
135  "content_long" => array("clob", $this->getContentLong()),
136  "priority" => array("integer", $this->getPriority()),
137  "content_is_lang_var" => array("integer", $this->getContentIsLangVar()),
138  "content_text_is_lang_var" => array("integer", (int) $this->getContentTextIsLangVar()),
139  "mob_id" => array("integer", $this->getMobId()),
140  "playtime" => array("text", $this->getPlaytime())
141  ));
142 
143 
144  $news_set = new ilSetting("news");
145  $max_items = $news_set->get("max_items");
146  if ($max_items <= 0)
147  {
148  $max_items = 50;
149  }
150 
151  // limit number of news
152  if ($this->getLimitation())
153  {
154  // Determine how many rows should be deleted
155  $query = "SELECT count(*) cnt ".
156  "FROM il_news_item ".
157  "WHERE ".
158  "context_obj_id = ".$ilDB->quote($this->getContextObjId(), "integer").
159  " AND context_obj_type = ".$ilDB->quote($this->getContextObjType(), "text").
160  " AND context_sub_obj_id = ".$ilDB->quote($this->getContextSubObjId(), "integer").
161  " AND ".$ilDB->equals("context_sub_obj_type", $this->getContextSubObjType(), "text", true)." ";
162 
163  $set = $ilDB->query($query);
164  $rec = $ilDB->fetchAssoc($set);
165 
166  // if we have more records than allowed, delete them
167  if (($rec["cnt"] > $max_items) && $this->getContextObjId() > 0)
168  {
169  $query = "SELECT * ".
170  "FROM il_news_item ".
171  "WHERE ".
172  "context_obj_id = ".$ilDB->quote($this->getContextObjId(), "integer").
173  " AND context_obj_type = ".$ilDB->quote($this->getContextObjType(), "text").
174  " AND context_sub_obj_id = ".$ilDB->quote($this->getContextSubObjId(), "integer").
175  " AND ".$ilDB->equals("context_sub_obj_type", $this->getContextSubObjType(), "text", true).
176  " ORDER BY creation_date ASC";
177 
178  $ilDB->setLimit($rec["cnt"] - $max_items);
179  $del_set = $ilDB->query($query);
180  while ($del_item = $ilDB->fetchAssoc($del_set))
181  {
182  $del_news = new ilNewsItem($del_item["id"]);
183  $del_news->delete();
184  }
185  }
186  }
187  }
188 
194  public function update($a_as_new = false)
195  {
196  global $ilDB;
197 
198  $fields = array(
199  "title" => array("text", $this->getTitle()),
200  "content" => array("clob", $this->getContent()),
201  "context_obj_id" => array("integer", $this->getContextObjId()),
202  "context_obj_type" => array("text", $this->getContextObjType()),
203  "context_sub_obj_id" => array("integer", $this->getContextSubObjId()),
204  "context_sub_obj_type" => array("text", $this->getContextSubObjType()),
205  "content_type" => array("text", $this->getContentType()),
206  "user_id" => array("integer", $this->getUserId()),
207  "visibility" => array("text", $this->getVisibility()),
208  "content_long" => array("clob", $this->getContentLong()),
209  "priority" => array("integer", $this->getPriority()),
210  "content_is_lang_var" => array("integer", $this->getContentIsLangVar()),
211  "content_text_is_lang_var" => array("integer", (int) $this->getContentTextIsLangVar()),
212  "mob_id" => array("integer", $this->getMobId()),
213  "playtime" => array("text", $this->getPlaytime())
214  );
215 
216  $now = ilUtil::now();
217  if ($a_as_new)
218  {
219  $fields["creation_date"] = array("timestamp", $now);
220  $fields["update_date"] = array("timestamp", $now);
221  }
222  else
223  {
224  $fields["update_date"] = array("timestamp", $now);
225  }
226 
227  $ilDB->update("il_news_item", $fields, array(
228  "id" => array("integer", $this->getId())
229  ));
230 
231  }
232 
233 
237  static function _getNewsItemsOfUser($a_user_id, $a_only_public = false,
238  $a_prevent_aggregation = false, $a_per = 0, &$a_cnt = NULL)
239  {
240  global $ilAccess, $ilUser;
241 
242  $news_item = new ilNewsItem();
243  $news_set = new ilSetting("news");
244 
245  $per = $a_per;
246 
247  include_once("./Services/News/classes/class.ilNewsSubscription.php");
248  include_once("./Services/Block/classes/class.ilBlockSetting.php");
249 
250  // this is currently not used
251  $ref_ids = ilNewsSubscription::_getSubscriptionsOfUser($a_user_id);
252 
253  if (ilObjUser::_lookupPref($a_user_id, "pd_items_news") != "n")
254  {
255  // this should be the case for all users
256  $pd_items = ilObjUser::_lookupDesktopItems($a_user_id);
257  foreach($pd_items as $item)
258  {
259  if (!in_array($item["ref_id"], $ref_ids))
260  {
261  $ref_ids[] = $item["ref_id"];
262  }
263  }
264  }
265 
266  $data = array();
267 
268  foreach($ref_ids as $ref_id)
269  {
270  if (!$a_only_public)
271  {
272  // this loop should not cost too much performance
273  $acc = $ilAccess->checkAccess("read", "", $ref_id);
274 
275  if (!$acc)
276  {
277  continue;
278  }
279  }
280  if (ilNewsItem::getPrivateFeedId() != false) {
281  global $rbacsystem;
282  $acc = $rbacsystem->checkAccessOfUser(ilNewsItem::getPrivateFeedId(),"read", $ref_id);
283 
284  if (!$acc)
285  {
286  continue;
287  }
288  }
289 
290  $obj_id = ilObject::_lookupObjId($ref_id);
291  $obj_type = ilObject::_lookupType($obj_id);
292  $news = $news_item->getNewsForRefId($ref_id, $a_only_public, false,
293  $per, $a_prevent_aggregation);
294 
295  // counter
296  if (!is_null($a_cnt))
297  {
298  $a_cnt[$ref_id] = count($news);
299  }
300 
302  }
303 
304  $data = ilUtil::sortArray($data, "creation_date", "desc", false, true);
305 
306  return $data;
307  }
308 
314  function getNewsForRefId($a_ref_id, $a_only_public = false, $a_stopnesting = false,
315  $a_time_period = 0, $a_prevent_aggregation = true, $a_forum_group_sequences = false,
316  $a_no_auto_generated = false, $a_ignore_date_filter = false, $a_user_id = null)
317  {
318  $obj_id = ilObject::_lookupObjId($a_ref_id);
319  $obj_type = ilObject::_lookupType($obj_id);
320 
321  // get starting date
322  $starting_date = "";
323  if ($obj_type == "grp" || $obj_type == "crs" || $obj_type == "cat")
324  {
325  include_once("./Services/Block/classes/class.ilBlockSetting.php");
326  $hide_news_per_date = ilBlockSetting::_lookup("news", "hide_news_per_date",
327  0, $obj_id);
328  if ($hide_news_per_date && !$a_ignore_date_filter)
329  {
330  $starting_date = ilBlockSetting::_lookup("news", "hide_news_date",
331  0, $obj_id);
332  }
333  }
334 
335  if ($obj_type == "cat" && !$a_stopnesting)
336  {
337  $news = $this->getAggregatedChildNewsData($a_ref_id, $a_only_public, $a_time_period,
338  $a_prevent_aggregation, $starting_date, $a_no_auto_generated);
339  }
340  else if (($obj_type == "grp" || $obj_type == "crs") &&
341  !$a_stopnesting)
342  {
343  $news = $this->getAggregatedNewsData($a_ref_id, $a_only_public, $a_time_period,
344  $a_prevent_aggregation, $starting_date, $a_no_auto_generated, $a_user_id);
345  }
346  else
347  {
348  $news_item = new ilNewsItem();
349  $news_item->setContextObjId($obj_id);
350  $news_item->setContextObjType($obj_type);
351  $news = $news_item->queryNewsForContext($a_only_public, $a_time_period,
352  $starting_date, $a_no_auto_generated);
353  $unset = array();
354  foreach ($news as $k => $v)
355  {
356  if (!$a_only_public || $v["visibility"] == NEWS_PUBLIC ||
357  ($v["priority"] == 0 &&
358  ilBlockSetting::_lookup("news", "public_notifications",
359  0, $obj_id)))
360  {
361  $news[$k]["ref_id"] = $a_ref_id;
362  }
363  else
364  {
365  $unset[] = $k;
366  }
367  }
368  foreach ($unset as $un)
369  {
370  unset($news[$un]);
371  }
372  }
373 
374  if (!$a_prevent_aggregation)
375  {
376  $news = $this->aggregateForums($news);
377  }
378  else if ($a_forum_group_sequences)
379  {
380  $news = $this->aggregateForums($news, true);
381  }
382 
383  return $news;
384  }
385 
389  function getAggregatedNewsData($a_ref_id, $a_only_public = false, $a_time_period = 0,
390  $a_prevent_aggregation = false, $a_starting_date = "", $a_no_auto_generated = false,
391  $a_user_id = null)
392  {
393  global $tree, $ilAccess, $ilObjDataCache;
394 
395  // get news of parent object
396 
397  $data = array();
398 
399  // get subtree
400  $cur_node = $tree->getNodeData($a_ref_id);
401 
402  if ($cur_node["lft"] != "") // should never be empty
403  {
404  $nodes = $tree->getSubTree($cur_node, true);
405  }
406  else
407  {
408  $nodes = array();
409  }
410 
411  // preload object data cache
412  $ref_ids = array();
413  $obj_ids = array();
414  foreach($nodes as $node)
415  {
416  $ref_ids[] = $node["child"];
417  $obj_ids[] = $node["obj_id"];
418  }
419 
420  $ilObjDataCache->preloadReferenceCache($ref_ids);
421  if (!$a_only_public)
422  {
423  $ilAccess->preloadActivationTimes($ref_ids);
424  }
425 
426  // no check, for which of the objects any news are available
427  $news_obj_ids = ilNewsItem::filterObjIdsPerNews($obj_ids, $a_time_period, $a_starting_date);
428  //$news_obj_ids = $obj_ids;
429 
430  // get news for all subtree nodes
431  $contexts = array();
432  foreach($nodes as $node)
433  {
434  // only go on, if news are available
435  if (!in_array($node["obj_id"], $news_obj_ids))
436  {
437  continue;
438  }
439 
440  if (!$a_only_public)
441  {
442  if(!$a_user_id)
443  {
444  $acc = $ilAccess->checkAccess("read", "", $node["child"]);
445  }
446  else
447  {
448  $acc = $ilAccess->checkAccessOfUser($a_user_id, "read", "",
449  $node["child"]);
450  }
451  if (!$acc)
452  {
453  continue;
454  }
455  }
456 
457  $ref_id[$node["obj_id"]] = $node["child"];
458  $contexts[] = array("obj_id" => $node["obj_id"],
459  "obj_type" => $node["type"]);
460  }
461 
462  // sort and return
463  $news = $this->queryNewsForMultipleContexts($contexts, $a_only_public, $a_time_period,
464  $a_starting_date, $a_no_auto_generated, $a_user_id);
465 
466  $to_del = array();
467  foreach ($news as $k => $v)
468  {
469  $news[$k]["ref_id"] = $ref_id[$v["context_obj_id"]];
470  }
471 
473  $data = ilUtil::sortArray($data, "creation_date", "desc", false, true);
474 
475  if (!$a_prevent_aggregation)
476  {
477  $data = $this->aggregateFiles($data, $a_ref_id);
478  }
479 
480  return $data;
481  }
482 
483  function aggregateForums($news, $a_group_posting_sequence = false)
484  {
485  $to_del = array();
486  $forums = array();
487 
488  // aggregate
489  foreach ($news as $k => $v)
490  {
491  if ($a_group_posting_sequence && $last_aggregation_forum > 0 &&
492  $last_aggregation_forum != $news[$k]["context_obj_id"])
493  {
494  $forums[$last_aggregation_forum] = "";
495  }
496 
497  if ($news[$k]["context_obj_type"] == "frm")
498  {
499  if ($forums[$news[$k]["context_obj_id"]] == "")
500  {
501  // $forums[forum_id] = news_id;
502  $forums[$news[$k]["context_obj_id"]] = $k;
503  $last_aggregation_forum = $news[$k]["context_obj_id"];
504  }
505  else
506  {
507  $to_del[] = $k;
508  }
509 
510  $news[$k]["no_context_title"] = true;
511 
512  // aggregate every forum into it's "k" news
513  $news[$forums[$news[$k]["context_obj_id"]]]["aggregation"][$k]
514  = $news[$k];
515  $news[$k]["agg_ref_id"]
516  = $news[$k]["ref_id"];
517  $news[$k]["content"] = "";
518  $news[$k]["content_long"] = "";
519  }
520  }
521 
522  // delete double entries
523  foreach($to_del as $k)
524  {
525  unset($news[$k]);
526  }
527 //var_dump($news[14]["aggregation"]);
528 
529 
530  return $news;
531  }
532 
533  function aggregateFiles($news, $a_ref_id)
534  {
535  $first_file = "";
536  $to_del = array();
537  foreach ($news as $k => $v)
538  {
539  // aggregate file related news
540  if ($news[$k]["context_obj_type"] == "file")
541  {
542  if ($first_file == "")
543  {
544  $first_file = $k;
545  }
546  else
547  {
548  $to_del[] = $k;
549  }
550  $news[$first_file]["aggregation"][$k] = $news[$k];
551  $news[$first_file]["agg_ref_id"] = $a_ref_id;
552  $news[$first_file]["ref_id"] = $a_ref_id;
553  }
554  }
555 
556  foreach($to_del as $v)
557  {
558  unset($news[$v]);
559  }
560 
561  return $news;
562  }
563 
564 
568  function getAggregatedChildNewsData($a_ref_id, $a_only_public = false,
569  $a_time_period = 0, $a_prevent_aggregation = false, $a_starting_date = "",
570  $a_no_auto_generated = false)
571  {
572  global $tree, $ilAccess;
573 
574  // get news of parent object
575  $data = $this->getNewsForRefId($a_ref_id, $a_only_public, true, $a_time_period,
576  true, false, false, $a_no_auto_generated);
577  foreach ($data as $k => $v)
578  {
579  $data[$k]["ref_id"] = $a_ref_id;
580  }
581 
582  // get childs
583  $nodes = $tree->getChilds($a_ref_id);
584 
585  // no check, for which of the objects any news are available
586  $obj_ids = array();
587  foreach($nodes as $node)
588  {
589  $obj_ids[] = $node["obj_id"];
590  }
591  $news_obj_ids = ilNewsItem::filterObjIdsPerNews($obj_ids, $a_time_period, $a_starting_date);
592  //$news_obj_ids = $obj_ids;
593 
594  // get news for all subtree nodes
595  $contexts = array();
596  foreach($nodes as $node)
597  {
598  // only go on, if news are available
599  if (!in_array($node["obj_id"], $news_obj_ids))
600  {
601  continue;
602  }
603 
604  if (!$a_only_public && !$ilAccess->checkAccess("read", "", $node["child"]))
605  {
606  continue;
607  }
608  $ref_id[$node["obj_id"]] = $node["child"];
609  $contexts[] = array("obj_id" => $node["obj_id"],
610  "obj_type" => $node["type"]);
611  }
612 
613  $news = $this->queryNewsForMultipleContexts($contexts, $a_only_public, $a_time_period,
614  $a_starting_date, $a_no_auto_generated);
615  foreach ($news as $k => $v)
616  {
617  $news[$k]["ref_id"] = $ref_id[$v["context_obj_id"]];
618  }
620 
621  // sort and return
622  $data = ilUtil::sortArray($data, "creation_date", "desc", false, true);
623 
624  if (!$a_prevent_aggregation)
625  {
626  $data = $this->aggregateFiles($data, $a_ref_id);
627  }
628 
629  return $data;
630  }
631 
635  function setContext($a_obj_id, $a_obj_type, $a_sub_obj_id = 0, $a_sub_obj_type = "")
636  {
637  $this->setContextObjId($a_obj_id);
638  $this->setContextObjType($a_obj_type);
639  $this->setContextSubObjId($a_sub_obj_id);
640  $this->setContextSubObjType($a_sub_obj_type);
641  }
642 
651  public function queryNewsForContext($a_for_rss_use = false, $a_time_period = 0,
652  $a_starting_date = "", $a_no_auto_generated = false, $a_oldest_first = false)
653  {
654  global $ilDB, $ilUser, $lng;
655 
656  $and = "";
657  if ($a_time_period > 0)
658  {
659  $limit_ts = date('Y-m-d H:i:s', time() - ($a_time_period * 24 * 60 * 60));
660  $and = " AND creation_date >= ".$ilDB->quote($limit_ts, "timestamp")." ";
661  }
662 
663  if ($a_starting_date != "")
664  {
665  $and.= " AND creation_date > ".$ilDB->quote($a_starting_date, "timestamp")." ";
666  }
667 
668  if ($a_no_auto_generated)
669  {
670  $and.= " AND priority = 1 AND content_type = ".$ilDB->quote("text", "text")." ";
671  }
672 
673  // this is changed with 4.1 (news table for lm pages)
674  if ($this->getContextSubObjId() > 0)
675  {
676  $and.= " AND context_sub_obj_id = ".$ilDB->quote($this->getContextSubObjId(), "integer").
677  " AND context_sub_obj_type = ".$ilDB->quote($this->getContextSubObjType(), "text");
678  }
679 
680  $ordering = ($a_oldest_first)
681  ? " creation_date ASC, id ASC "
682  : " creation_date DESC, id DESC ";
683 
684  if ($a_for_rss_use && ilNewsItem::getPrivateFeedId() == false)
685  {
686  $query = "SELECT * ".
687  "FROM il_news_item ".
688  " WHERE ".
689  "context_obj_id = ".$ilDB->quote($this->getContextObjId(), "integer").
690  " AND context_obj_type = ".$ilDB->quote($this->getContextObjType(), "text").
691  $and.
692  " ORDER BY ".$ordering;
693  }
694  elseif (ilNewsItem::getPrivateFeedId() != false)
695  {
696  $query = "SELECT il_news_item.* ".
697  ", il_news_read.user_id user_read ".
698  "FROM il_news_item LEFT JOIN il_news_read ".
699  "ON il_news_item.id = il_news_read.news_id AND ".
700  " il_news_read.user_id = ".$ilDB->quote(ilNewsItem::getPrivateFeedId(), "integer").
701  " WHERE ".
702  "context_obj_id = ".$ilDB->quote($this->getContextObjId(), "integer").
703  " AND context_obj_type = ".$ilDB->quote($this->getContextObjType(), "text").
704  $and.
705  " ORDER BY ".$ordering;
706  }
707  else
708  {
709  $query = "SELECT il_news_item.* ".
710  ", il_news_read.user_id as user_read ".
711  "FROM il_news_item LEFT JOIN il_news_read ".
712  "ON il_news_item.id = il_news_read.news_id AND ".
713  " il_news_read.user_id = ".$ilDB->quote($ilUser->getId(), "integer").
714  " WHERE ".
715  "context_obj_id = ".$ilDB->quote($this->getContextObjId(), "integer").
716  " AND context_obj_type = ".$ilDB->quote($this->getContextObjType(), "text").
717  $and.
718  " ORDER BY ".$ordering;
719  }
720 //echo $query;
721  $set = $ilDB->query($query);
722  $result = array();
723  while($rec = $ilDB->fetchAssoc($set))
724  {
725  if (!$a_for_rss_use || (ilNewsItem::getPrivateFeedId() != false) || ($rec["visibility"] == NEWS_PUBLIC ||
726  ($rec["priority"] == 0 &&
727  ilBlockSetting::_lookup("news", "public_notifications",
728  0, $rec["context_obj_id"]))))
729  {
730  $result[$rec["id"]] = $rec;
731  }
732  }
733 
734  return $result;
735 
736  }
737 
745  public function checkNewsExistsForGroupCourse($a_ref_id, $a_time_period = 1)
746  {
747  global $tree, $ilDB;
748 
749  // parse repository branch of group
750  $nodes = array();
751  $node = $tree->getNodeData($a_ref_id);
752  foreach($tree->getSubTree($node) as $child)
753  {
754  if($child["type"] != "rolf")
755  {
756  $nodes[$child["obj_id"]] = $child["type"];
757  }
758  }
759 
760  $limit_ts = date('Y-m-d H:i:s', time() - ($a_time_period * 24 * 60 * 60));
761 
762  // are there any news items for relevant objects and?
763  $all = array();
764  $query = $ilDB->query("SELECT id,context_obj_id,context_obj_type".
765  " FROM il_news_item".
766  " WHERE ".$ilDB->in("context_obj_id", array_keys($nodes), false, "integer").
767  " AND creation_date >= ".$ilDB->quote($limit_ts, "timestamp"));
768  while($rec = $ilDB->fetchAssoc($query))
769  {
770  if ($nodes[$rec["context_obj_id"]] == $rec["context_obj_type"])
771  {
772  $all[] = $rec["id"];
773  }
774  }
775 
776  return $all;
777  }
778 
784  public function queryNewsForMultipleContexts($a_contexts, $a_for_rss_use = false,
785  $a_time_period = 0, $a_starting_date = "", $a_no_auto_generated = false,
786  $a_user_id = null)
787  {
788  global $ilDB, $ilUser, $lng, $ilCtrl;
789 
790  $and = "";
791  if ($a_time_period > 0)
792  {
793  $limit_ts = date('Y-m-d H:i:s', time() - ($a_time_period * 24 * 60 * 60));
794  $and = " AND creation_date >= ".$ilDB->quote($limit_ts, "timestamp")." ";
795  }
796 
797  if ($a_starting_date != "")
798  {
799  $and.= " AND creation_date > ".$ilDB->quote($a_starting_date, "timestamp")." ";
800  }
801 
802  if ($a_no_auto_generated)
803  {
804  $and.= " AND priority = 1 AND content_type = ".$ilDB->quote("text", "text")." ";
805  }
806 
807  $ids = array();
808  $type = array();
809  foreach($a_contexts as $cont)
810  {
811  $ids[] = $cont["obj_id"];
812  $type[$cont["obj_id"]] = $cont["obj_type"];
813  }
814 
815  if ($a_for_rss_use && ilNewsItem::getPrivateFeedId() == false)
816  {
817  $query = "SELECT * ".
818  "FROM il_news_item ".
819  " WHERE ".
820  $ilDB->in("context_obj_id", $ids, false, "integer")." ".
821  $and.
822  " ORDER BY creation_date DESC ";
823  }
824  elseif (ilNewsItem::getPrivateFeedId() != false)
825  {
826  $query = "SELECT il_news_item.* ".
827  ", il_news_read.user_id as user_read ".
828  "FROM il_news_item LEFT JOIN il_news_read ".
829  "ON il_news_item.id = il_news_read.news_id AND ".
830  " il_news_read.user_id = ".$ilDB->quote(ilNewsItem::getPrivateFeedId(), "integer").
831  " WHERE ".
832  $ilDB->in("context_obj_id", $ids, false, "integer")." ".
833  $and.
834  " ORDER BY creation_date DESC ";
835  }
836  else
837  {
838  if($a_user_id)
839  {
840  $user_id = $a_user_id;
841  }
842  else
843  {
844  $user_id = $ilUser->getId();
845  }
846  $query = "SELECT il_news_item.* ".
847  ", il_news_read.user_id as user_read ".
848  "FROM il_news_item LEFT JOIN il_news_read ".
849  "ON il_news_item.id = il_news_read.news_id AND ".
850  " il_news_read.user_id = ".$ilDB->quote($user_id, "integer").
851  " WHERE ".
852  $ilDB->in("context_obj_id", $ids, false, "integer")." ".
853  $and.
854  " ORDER BY creation_date DESC ";
855  }
856 
857  $set = $ilDB->query($query);
858  $result = array();
859  while($rec = $ilDB->fetchAssoc($set))
860  {
861  if ($type[$rec["context_obj_id"]] == $rec["context_obj_type"])
862  {
863  if (!$a_for_rss_use || ilNewsItem::getPrivateFeedId() != false || ($rec["visibility"] == NEWS_PUBLIC ||
864  ($rec["priority"] == 0 &&
865  ilBlockSetting::_lookup("news", "public_notifications",
866  0, $rec["context_obj_id"]))))
867  {
868  $result[$rec["id"]] = $rec;
869  }
870  }
871  }
872 
873  return $result;
874 
875  }
876 
877 
881  function _setRead($a_user_id, $a_news_id)
882  {
883  global $ilDB, $ilAppEventHandler;
884 
885  $ilDB->manipulate("DELETE FROM il_news_read WHERE ".
886  "user_id = ".$ilDB->quote($a_user_id, "integer").
887  " AND news_id = ".$ilDB->quote($a_news_id, "integer"));
888  $ilDB->manipulate("INSERT INTO il_news_read (user_id, news_id) VALUES (".
889  $ilDB->quote($a_user_id, "integer").",".
890  $ilDB->quote($a_news_id, "integer").")");
891 
892  $ilAppEventHandler->raise("Services/News", "readNews",
893  array("user_id" => $a_user_id, "news_ids" => array($a_news_id)));
894  }
895 
899  function _setUnread($a_user_id, $a_news_id)
900  {
901  global $ilDB, $ilAppEventHandler;
902 
903  $ilDB->manipulate("DELETE FROM il_news_read (user_id, news_id) VALUES (".
904  " WHERE user_id = ".$ilDB->quote($a_user_id, "integer").
905  " AND news_id = ".$ilDB->quote($a_news_id, "integer"));
906 
907  $ilAppEventHandler->raise("Services/News", "unreadNews",
908  array("user_id" => $a_user_id, "news_ids" => array($a_news_id)));
909  }
910 
919  function mergeNews($n1, $n2)
920  {
921  foreach($n2 as $id => $news)
922  {
923  $n1[$id] = $news;
924  }
925 
926  return $n1;
927  }
928 
934  static function _getDefaultVisibilityForRefId($a_ref_id)
935  {
936  global $tree, $ilSetting;
937 
938  include_once("./Services/Block/classes/class.ilBlockSetting.php");
939 
940  $news_set = new ilSetting("news");
941  $default_visibility = ($news_set->get("default_visibility") != "")
942  ? $news_set->get("default_visibility")
943  : "users";
944 
945  if ($tree->isInTree($a_ref_id))
946  {
947  $path = $tree->getPathFull($a_ref_id);
948 
949  foreach ($path as $key => $row)
950  {
951  if (!in_array($row["type"], array("root", "cat","crs", "fold", "grp", "icrs")))
952  {
953  continue;
954  }
955 
956  $visibility = ilBlockSetting::_lookup("news", "default_visibility",
957  0, $row["obj_id"]);
958 
959  if ($visibility != "")
960  {
961  $default_visibility = $visibility;
962  }
963  }
964  }
965 
966  return $default_visibility;
967  }
968 
969 
974  public function delete()
975  {
976  global $ilDB;
977 
978  // delete il_news_read entries
979  $ilDB->manipulate("DELETE FROM il_news_read ".
980  " WHERE news_id = ".$ilDB->quote($this->getId(), "integer"));
981 
982  // delete multimedia object
983  $mob = $this->getMobId();
984 
985  // delete
986  parent::delete();
987 
988  // delete mob after news, to have a "mob usage" of 0
989  if ($mob > 0 and ilObject::_exists($mob))
990  {
991  include_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
992  $mob = new ilObjMediaObject($mob);
993  $mob->delete();
994  }
995  }
996 
1001  static public function deleteNewsOfContext($a_context_obj_id,
1002  $a_context_obj_type, $a_context_sub_obj_id = 0, $a_context_sub_obj_type = "")
1003  {
1004  global $ilDB;
1005 
1006  if ($a_context_obj_id == 0 || $a_context_obj_type == "")
1007  {
1008  return;
1009  }
1010 
1011  if ($a_context_sub_obj_id > 0)
1012  {
1013  $and = " AND context_sub_obj_id = ".$ilDB->quote($a_context_sub_obj_id, "integer").
1014  " AND context_sub_obj_type = ".$ilDB->quote($a_context_sub_obj_type, "text");
1015  }
1016 
1017  // get news records
1018  $query = "SELECT * FROM il_news_item".
1019  " WHERE context_obj_id = ".$ilDB->quote($a_context_obj_id, "integer").
1020  " AND context_obj_type = ".$ilDB->quote($a_context_obj_type, "text").
1021  $and;
1022 
1023  $news_set = $ilDB->query($query);
1024 
1025  while ($news = $ilDB->fetchAssoc($news_set))
1026  {
1027  $news_obj = new ilNewsItem($news["id"]);
1028  $news_obj->delete();
1029  }
1030  }
1031 
1035  static function _lookupTitle($a_news_id)
1036  {
1037  global $ilDB;
1038 
1039  $query = "SELECT title FROM il_news_item WHERE id = ".
1040  $ilDB->quote($a_news_id, "integer");
1041  $set = $ilDB->query($query);
1042  $rec = $ilDB->fetchAssoc($set);
1043  return $rec["title"];
1044  }
1045 
1049  static function _lookupVisibility($a_news_id)
1050  {
1051  global $ilDB;
1052 
1053  $query = "SELECT visibility FROM il_news_item WHERE id = ".
1054  $ilDB->quote($a_news_id, "integer");
1055  $set = $ilDB->query($query);
1056  $rec = $ilDB->fetchAssoc($set);
1057 
1058  return $rec["visibility"];
1059  }
1060 
1064  static function _lookupMobId($a_news_id)
1065  {
1066  global $ilDB;
1067 
1068  $query = "SELECT mob_id FROM il_news_item WHERE id = ".
1069  $ilDB->quote($a_news_id, "integer");
1070  $set = $ilDB->query($query);
1071  $rec = $ilDB->fetchAssoc($set);
1072  return $rec["mob_id"];
1073  }
1074 
1078  static function filterObjIdsPerNews($a_obj_ids, $a_time_period = 0, $a_starting_date = "",$a_ending_date = '', $ignore_period = false)
1079  {
1080  global $ilDB;
1081 
1082  $and = "";
1083  if ($a_time_period > 0)
1084  {
1085  $limit_ts = date('Y-m-d H:i:s', time() - ($a_time_period * 24 * 60 * 60));
1086  $and = " AND creation_date >= ".$ilDB->quote($limit_ts, "timestamp")." ";
1087  }
1088 
1089  if ($a_starting_date != "")
1090  {
1091  $and.= " AND creation_date >= ".$ilDB->quote($a_starting_date, "timestamp");
1092  }
1093 
1094  $query = "SELECT DISTINCT(context_obj_id) AS obj_id FROM il_news_item".
1095  " WHERE ".$ilDB->in("context_obj_id", $a_obj_ids, false, "integer")." ".$and;
1096  //" WHERE context_obj_id IN (".implode(ilUtil::quoteArray($a_obj_ids),",").")".$and;
1097 
1098  $set = $ilDB->query($query);
1099  $objs = array();
1100  while($rec = $ilDB->fetchAssoc($set))
1101  {
1102  $objs[] = $rec["obj_id"];
1103  }
1104 
1105  return $objs;
1106  }
1107 
1111  static function determineNewsTitle($a_context_obj_type, $a_title, $a_content_is_lang_var,
1112  $a_agg_ref_id = 0, $a_aggregation = "")
1113  {
1114  global $lng;
1115 
1116  if ($a_agg_ref_id > 0)
1117  {
1118  $cnt = count($a_aggregation);
1119 
1120  // forums
1121  if ($a_context_obj_type == "frm")
1122  {
1123  if ($cnt > 1)
1124  {
1125  return sprintf($lng->txt("news_x_postings"), $cnt);
1126  }
1127  else
1128  {
1129  return $lng->txt("news_1_postings");
1130  }
1131  }
1132  else // files
1133  {
1134  $up_cnt = $cr_cnt = 0;
1135  foreach($a_aggregation as $item)
1136  {
1137  if ($item["title"] == "file_updated")
1138  {
1139  $up_cnt++;
1140  }
1141  else
1142  {
1143  $cr_cnt++;
1144  }
1145  }
1146  $sep = "";
1147  if ($cr_cnt == 1)
1148  {
1149  $tit = $lng->txt("news_1_file_created");
1150  $sep = "<br />";
1151  }
1152  else if ($cr_cnt > 1)
1153  {
1154  $tit = sprintf($lng->txt("news_x_files_created"), $cr_cnt);
1155  $sep = "<br />";
1156  }
1157  if ($up_cnt == 1)
1158  {
1159  $tit .= $sep.$lng->txt("news_1_file_updated");
1160  }
1161  else if ($up_cnt > 1)
1162  {
1163  $tit .= $sep.sprintf($lng->txt("news_x_files_updated"), $up_cnt);
1164  }
1165  return $tit;
1166  }
1167  }
1168  else
1169  {
1170  if ($a_content_is_lang_var)
1171  {
1172  return $lng->txt($a_title);
1173  }
1174  else
1175  {
1176  return $a_title;
1177  }
1178  }
1179 
1180  return "";
1181  }
1182 
1186  static function determineNewsContent($a_context_obj_type, $a_content, $a_is_lang_var)
1187  {
1188  global $lng;
1189 
1190  if ($a_is_lang_var)
1191  {
1192  $lng->loadLanguageModule($a_context_obj_type);
1193  return $lng->txt($a_content);
1194  }
1195  else
1196  {
1197  return $a_content;
1198  }
1199  }
1200 
1201 
1202 
1206  static function getFirstNewsIdForContext($a_context_obj_id,
1207  $a_context_obj_type, $a_context_sub_obj_id = "", $a_context_sub_obj_type = "")
1208  {
1209  global $ilDB;
1210 
1211  // Determine how many rows should be deleted
1212  $query = "SELECT * ".
1213  "FROM il_news_item ".
1214  "WHERE ".
1215  "context_obj_id = ".$ilDB->quote($a_context_obj_id, "integer").
1216  " AND context_obj_type = ".$ilDB->quote($a_context_obj_type, "text").
1217  " AND context_sub_obj_id = ".$ilDB->quote($a_context_sub_obj_id, "integer").
1218  " AND ".$ilDB->equals("context_sub_obj_type", $a_context_sub_obj_type, "text", true);
1219 
1220  $set = $ilDB->query($query);
1221  $rec = $ilDB->fetchAssoc($set);
1222 
1223  return $rec["id"];
1224  }
1225 
1229  static function getLastNewsIdForContext($a_context_obj_id,
1230  $a_context_obj_type, $a_context_sub_obj_id = "", $a_context_sub_obj_type = "",
1231  $a_only_today = false)
1232  {
1233  global $ilDB;
1234 
1235  // Determine how many rows should be deleted
1236  $query = "SELECT id, update_date ".
1237  "FROM il_news_item ".
1238  "WHERE ".
1239  "context_obj_id = ".$ilDB->quote($a_context_obj_id, "integer").
1240  " AND context_obj_type = ".$ilDB->quote($a_context_obj_type, "text").
1241  " AND context_sub_obj_id = ".$ilDB->quote($a_context_sub_obj_id, "integer").
1242  " AND ".$ilDB->equals("context_sub_obj_type", $a_context_sub_obj_type, "text", true).
1243  " ORDER BY update_date DESC";
1244 
1245  $ilDB->setLimit(1);
1246  $set = $ilDB->query($query);
1247  $rec = $ilDB->fetchAssoc($set);
1248 
1249  $id = (int) $rec["id"];
1250  if ($a_only_today)
1251  {
1252  $now = ilUtil::now();
1253  if (substr($now, 0, 10) != substr($rec["update_date"], 0, 10))
1254  {
1255  $id = 0;
1256  }
1257  }
1258 
1259  return $id;
1260  }
1261 
1262 
1266  static function _lookupMediaObjectUsages($a_mob_id)
1267  {
1268  global $ilDB;
1269 
1270  $query = "SELECT * ".
1271  "FROM il_news_item ".
1272  "WHERE ".
1273  " mob_id = ".$ilDB->quote($a_mob_id, "integer");
1274 
1275  $usages = array();
1276  $set = $ilDB->query($query);
1277  while ($rec = $ilDB->fetchAssoc($set))
1278  {
1279  $usages[$rec["id"]] = array("type" => "news", "id" => $rec["id"]);
1280  }
1281 
1282  return $usages;
1283  }
1284 
1288  static function _lookupContextObjId($a_news_id)
1289  {
1290  global $ilDB;
1291 
1292  $query = "SELECT * ".
1293  "FROM il_news_item ".
1294  "WHERE ".
1295  " id = ".$ilDB->quote($a_news_id, "integer");
1296  $set = $ilDB->query($query);
1297  $rec = $ilDB->fetchAssoc($set);
1298 
1299  return $rec["context_obj_id"];
1300  }
1301 
1303  {
1304  $news_set = new ilSetting("news");
1305  $per = $news_set->get("pd_period");
1306  if ($per == 0)
1307  {
1308  $per = 30;
1309  }
1310 
1311  return $per;
1312  }
1313 
1314  function _lookupUserPDPeriod($a_user_id)
1315  {
1316  global $ilSetting;
1317 
1318  $news_set = new ilSetting("news");
1319  $allow_shorter_periods = $news_set->get("allow_shorter_periods");
1320  $allow_longer_periods = $news_set->get("allow_longer_periods");
1321  $default_per = ilNewsItem::_lookupDefaultPDPeriod();
1322 
1323  include_once("./Services/Block/classes/class.ilBlockSetting.php");
1324  $per = ilBlockSetting::_lookup("pdnews", "news_pd_period",
1325  $a_user_id, 0);
1326 
1327  // news period information
1328  if ($per <= 0 ||
1329  (!$allow_shorter_periods && ($per < $default_per)) ||
1330  (!$allow_longer_periods && ($per > $default_per))
1331  )
1332  {
1333  $per = $default_per;
1334  }
1335 
1336  return $per;
1337  }
1338 
1339  function _lookupRSSPeriod()
1340  {
1341  $news_set = new ilSetting("news");
1342  $rss_period = $news_set->get("rss_period");
1343  if ($rss_period == 0) // default to two weeks
1344  {
1345  $rss_period = 14;
1346  }
1347  return $rss_period;
1348  }
1349  function setPrivateFeedId ($a_userId)
1350  {
1351  ilNewsItem::$privFeedId = $a_userId;
1352  }
1353 
1354  function getPrivateFeedId () {
1355 
1356  return ilNewsItem::$privFeedId;
1357  }
1358 }
1359 ?>