ILIAS  release_4-3 Revision
 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-2012 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;
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  // get all items of the personal desktop
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  // get all memberships
266  include_once 'Services/Membership/classes/class.ilParticipants.php';
267  $crs_mbs = ilParticipants::_getMembershipByType($a_user_id, 'crs');
268  $grp_mbs = ilParticipants::_getMembershipByType($a_user_id, 'grp');
269  $items = array_merge($crs_mbs, $grp_mbs);
270  foreach($items as $i)
271  {
272  $item_references = ilObject::_getAllReferences($i);
273  if(is_array($item_references) && count($item_references))
274  {
275  foreach($item_references as $ref_id)
276  {
277  if (!in_array($ref_id, $ref_ids))
278  {
279  $ref_ids[] = $ref_id;
280  }
281  }
282  }
283  }
284  }
285 
286  $data = array();
287 
288  foreach($ref_ids as $ref_id)
289  {
290  if (!$a_only_public)
291  {
292  // this loop should not cost too much performance
293  $acc = $ilAccess->checkAccessOfUser($a_user_id, "read", "", $ref_id);
294 
295  if (!$acc)
296  {
297  continue;
298  }
299  }
300  if (ilNewsItem::getPrivateFeedId() != false) {
301  global $rbacsystem;
302  $acc = $rbacsystem->checkAccessOfUser(ilNewsItem::getPrivateFeedId(),"read", $ref_id);
303 
304  if (!$acc)
305  {
306  continue;
307  }
308  }
309 
310  $obj_id = ilObject::_lookupObjId($ref_id);
311  $obj_type = ilObject::_lookupType($obj_id);
312  $news = $news_item->getNewsForRefId($ref_id, $a_only_public, false,
313  $per, $a_prevent_aggregation, false, false, false, $a_user_id);
314 
315  // counter
316  if (!is_null($a_cnt))
317  {
318  $a_cnt[$ref_id] = count($news);
319  }
320 
322  }
323 
324  $data = ilUtil::sortArray($data, "creation_date", "desc", false, true);
325 
326  return $data;
327  }
328 
334  function getNewsForRefId($a_ref_id, $a_only_public = false, $a_stopnesting = false,
335  $a_time_period = 0, $a_prevent_aggregation = true, $a_forum_group_sequences = false,
336  $a_no_auto_generated = false, $a_ignore_date_filter = false, $a_user_id = null)
337  {
338  $obj_id = ilObject::_lookupObjId($a_ref_id);
339  $obj_type = ilObject::_lookupType($obj_id);
340 
341  // get starting date
342  $starting_date = "";
343  if ($obj_type == "grp" || $obj_type == "crs" || $obj_type == "cat")
344  {
345  include_once("./Services/Block/classes/class.ilBlockSetting.php");
346  $hide_news_per_date = ilBlockSetting::_lookup("news", "hide_news_per_date",
347  0, $obj_id);
348  if ($hide_news_per_date && !$a_ignore_date_filter)
349  {
350  $starting_date = ilBlockSetting::_lookup("news", "hide_news_date",
351  0, $obj_id);
352  }
353  }
354 
355  if ($obj_type == "cat" && !$a_stopnesting)
356  {
357  $news = $this->getAggregatedChildNewsData($a_ref_id, $a_only_public, $a_time_period,
358  $a_prevent_aggregation, $starting_date, $a_no_auto_generated);
359  }
360  else if (($obj_type == "grp" || $obj_type == "crs") &&
361  !$a_stopnesting)
362  {
363  $news = $this->getAggregatedNewsData($a_ref_id, $a_only_public, $a_time_period,
364  $a_prevent_aggregation, $starting_date, $a_no_auto_generated, $a_user_id);
365  }
366  else
367  {
368  $news_item = new ilNewsItem();
369  $news_item->setContextObjId($obj_id);
370  $news_item->setContextObjType($obj_type);
371  $news = $news_item->queryNewsForContext($a_only_public, $a_time_period,
372  $starting_date, $a_no_auto_generated);
373  $unset = array();
374  foreach ($news as $k => $v)
375  {
376  if (!$a_only_public || $v["visibility"] == NEWS_PUBLIC ||
377  ($v["priority"] == 0 &&
378  ilBlockSetting::_lookup("news", "public_notifications",
379  0, $obj_id)))
380  {
381  $news[$k]["ref_id"] = $a_ref_id;
382  }
383  else
384  {
385  $unset[] = $k;
386  }
387  }
388  foreach ($unset as $un)
389  {
390  unset($news[$un]);
391  }
392  }
393 
394  if (!$a_prevent_aggregation)
395  {
396  $news = $this->aggregateForums($news);
397  }
398  else if ($a_forum_group_sequences)
399  {
400  $news = $this->aggregateForums($news, true);
401  }
402 
403  return $news;
404  }
405 
409  function getAggregatedNewsData($a_ref_id, $a_only_public = false, $a_time_period = 0,
410  $a_prevent_aggregation = false, $a_starting_date = "", $a_no_auto_generated = false,
411  $a_user_id = null)
412  {
413  global $tree, $ilAccess, $ilObjDataCache;
414 
415  // get news of parent object
416 
417  $data = array();
418 
419  // get subtree
420  $cur_node = $tree->getNodeData($a_ref_id);
421 
422  if ($cur_node["lft"] != "") // should never be empty
423  {
424  $nodes = $tree->getSubTree($cur_node, true);
425  }
426  else
427  {
428  $nodes = array();
429  }
430 
431  // preload object data cache
432  $ref_ids = array();
433  $obj_ids = array();
434  foreach($nodes as $node)
435  {
436  $ref_ids[] = $node["child"];
437  $obj_ids[] = $node["obj_id"];
438  }
439 
440  $ilObjDataCache->preloadReferenceCache($ref_ids);
441  if (!$a_only_public)
442  {
443  include_once "Services/Object/classes/class.ilObjectActivation.php";
445  }
446 
447  // no check, for which of the objects any news are available
448  $news_obj_ids = ilNewsItem::filterObjIdsPerNews($obj_ids, $a_time_period, $a_starting_date);
449  //$news_obj_ids = $obj_ids;
450 
451  // get news for all subtree nodes
452  $contexts = array();
453  foreach($nodes as $node)
454  {
455  // only go on, if news are available
456  if (!in_array($node["obj_id"], $news_obj_ids))
457  {
458  continue;
459  }
460 
461  if (!$a_only_public)
462  {
463  if(!$a_user_id)
464  {
465  $acc = $ilAccess->checkAccess("read", "", $node["child"]);
466  }
467  else
468  {
469  $acc = $ilAccess->checkAccessOfUser($a_user_id, "read", "",
470  $node["child"]);
471  }
472  if (!$acc)
473  {
474  continue;
475  }
476  }
477 
478  $ref_id[$node["obj_id"]] = $node["child"];
479  $contexts[] = array("obj_id" => $node["obj_id"],
480  "obj_type" => $node["type"]);
481  }
482 
483  // sort and return
484  $news = $this->queryNewsForMultipleContexts($contexts, $a_only_public, $a_time_period,
485  $a_starting_date, $a_no_auto_generated, $a_user_id);
486 
487  $to_del = array();
488  foreach ($news as $k => $v)
489  {
490  $news[$k]["ref_id"] = $ref_id[$v["context_obj_id"]];
491  }
492 
494  $data = ilUtil::sortArray($data, "creation_date", "desc", false, true);
495 
496  if (!$a_prevent_aggregation)
497  {
498  $data = $this->aggregateFiles($data, $a_ref_id);
499  }
500 
501  return $data;
502  }
503 
504  function aggregateForums($news, $a_group_posting_sequence = false)
505  {
506  $to_del = array();
507  $forums = array();
508 
509  // aggregate
510  foreach ($news as $k => $v)
511  {
512  if ($a_group_posting_sequence && $last_aggregation_forum > 0 &&
513  $last_aggregation_forum != $news[$k]["context_obj_id"])
514  {
515  $forums[$last_aggregation_forum] = "";
516  }
517 
518  if ($news[$k]["context_obj_type"] == "frm")
519  {
520  if ($forums[$news[$k]["context_obj_id"]] == "")
521  {
522  // $forums[forum_id] = news_id;
523  $forums[$news[$k]["context_obj_id"]] = $k;
524  $last_aggregation_forum = $news[$k]["context_obj_id"];
525  }
526  else
527  {
528  $to_del[] = $k;
529  }
530 
531  $news[$k]["no_context_title"] = true;
532 
533  // aggregate every forum into it's "k" news
534  $news[$forums[$news[$k]["context_obj_id"]]]["aggregation"][$k]
535  = $news[$k];
536  $news[$k]["agg_ref_id"]
537  = $news[$k]["ref_id"];
538  $news[$k]["content"] = "";
539  $news[$k]["content_long"] = "";
540  }
541  }
542 
543  // delete double entries
544  foreach($to_del as $k)
545  {
546  unset($news[$k]);
547  }
548 //var_dump($news[14]["aggregation"]);
549 
550 
551  return $news;
552  }
553 
554  function aggregateFiles($news, $a_ref_id)
555  {
556  $first_file = "";
557  $to_del = array();
558  foreach ($news as $k => $v)
559  {
560  // aggregate file related news
561  if ($news[$k]["context_obj_type"] == "file")
562  {
563  if ($first_file == "")
564  {
565  $first_file = $k;
566  }
567  else
568  {
569  $to_del[] = $k;
570  }
571  $news[$first_file]["aggregation"][$k] = $news[$k];
572  $news[$first_file]["agg_ref_id"] = $a_ref_id;
573  $news[$first_file]["ref_id"] = $a_ref_id;
574  }
575  }
576 
577  foreach($to_del as $v)
578  {
579  unset($news[$v]);
580  }
581 
582  return $news;
583  }
584 
585 
589  function getAggregatedChildNewsData($a_ref_id, $a_only_public = false,
590  $a_time_period = 0, $a_prevent_aggregation = false, $a_starting_date = "",
591  $a_no_auto_generated = false)
592  {
593  global $tree, $ilAccess;
594 
595  // get news of parent object
596  $data = $this->getNewsForRefId($a_ref_id, $a_only_public, true, $a_time_period,
597  true, false, false, $a_no_auto_generated);
598  foreach ($data as $k => $v)
599  {
600  $data[$k]["ref_id"] = $a_ref_id;
601  }
602 
603  // get childs
604  $nodes = $tree->getChilds($a_ref_id);
605 
606  // no check, for which of the objects any news are available
607  $obj_ids = array();
608  foreach($nodes as $node)
609  {
610  $obj_ids[] = $node["obj_id"];
611  }
612  $news_obj_ids = ilNewsItem::filterObjIdsPerNews($obj_ids, $a_time_period, $a_starting_date);
613  //$news_obj_ids = $obj_ids;
614 
615  // get news for all subtree nodes
616  $contexts = array();
617  foreach($nodes as $node)
618  {
619  // only go on, if news are available
620  if (!in_array($node["obj_id"], $news_obj_ids))
621  {
622  continue;
623  }
624 
625  if (!$a_only_public && !$ilAccess->checkAccess("read", "", $node["child"]))
626  {
627  continue;
628  }
629  $ref_id[$node["obj_id"]] = $node["child"];
630  $contexts[] = array("obj_id" => $node["obj_id"],
631  "obj_type" => $node["type"]);
632  }
633 
634  $news = $this->queryNewsForMultipleContexts($contexts, $a_only_public, $a_time_period,
635  $a_starting_date, $a_no_auto_generated);
636  foreach ($news as $k => $v)
637  {
638  $news[$k]["ref_id"] = $ref_id[$v["context_obj_id"]];
639  }
641 
642  // sort and return
643  $data = ilUtil::sortArray($data, "creation_date", "desc", false, true);
644 
645  if (!$a_prevent_aggregation)
646  {
647  $data = $this->aggregateFiles($data, $a_ref_id);
648  }
649 
650  return $data;
651  }
652 
656  function setContext($a_obj_id, $a_obj_type, $a_sub_obj_id = 0, $a_sub_obj_type = "")
657  {
658  $this->setContextObjId($a_obj_id);
659  $this->setContextObjType($a_obj_type);
660  $this->setContextSubObjId($a_sub_obj_id);
661  $this->setContextSubObjType($a_sub_obj_type);
662  }
663 
672  public function queryNewsForContext($a_for_rss_use = false, $a_time_period = 0,
673  $a_starting_date = "", $a_no_auto_generated = false, $a_oldest_first = false, $a_limit = 0)
674  {
675  global $ilDB, $ilUser, $lng;
676 
677  $and = "";
678  if ($a_time_period > 0)
679  {
680  $limit_ts = date('Y-m-d H:i:s', time() - ($a_time_period * 24 * 60 * 60));
681  $and = " AND creation_date >= ".$ilDB->quote($limit_ts, "timestamp")." ";
682  }
683 
684  if ($a_starting_date != "")
685  {
686  $and.= " AND creation_date > ".$ilDB->quote($a_starting_date, "timestamp")." ";
687  }
688 
689  if ($a_no_auto_generated)
690  {
691  $and.= " AND priority = 1 AND content_type = ".$ilDB->quote("text", "text")." ";
692  }
693 
694  // this is changed with 4.1 (news table for lm pages)
695  if ($this->getContextSubObjId() > 0)
696  {
697  $and.= " AND context_sub_obj_id = ".$ilDB->quote($this->getContextSubObjId(), "integer").
698  " AND context_sub_obj_type = ".$ilDB->quote($this->getContextSubObjType(), "text");
699  }
700 
701  $ordering = ($a_oldest_first)
702  ? " creation_date ASC, id ASC "
703  : " creation_date DESC, id DESC ";
704 
705  if ($a_for_rss_use && ilNewsItem::getPrivateFeedId() == false)
706  {
707  $query = "SELECT * ".
708  "FROM il_news_item ".
709  " WHERE ".
710  "context_obj_id = ".$ilDB->quote($this->getContextObjId(), "integer").
711  " AND context_obj_type = ".$ilDB->quote($this->getContextObjType(), "text").
712  $and.
713  " ORDER BY ".$ordering;
714  }
715  elseif (ilNewsItem::getPrivateFeedId() != false)
716  {
717  $query = "SELECT il_news_item.* ".
718  ", il_news_read.user_id user_read ".
719  "FROM il_news_item LEFT JOIN il_news_read ".
720  "ON il_news_item.id = il_news_read.news_id AND ".
721  " il_news_read.user_id = ".$ilDB->quote(ilNewsItem::getPrivateFeedId(), "integer").
722  " WHERE ".
723  "context_obj_id = ".$ilDB->quote($this->getContextObjId(), "integer").
724  " AND context_obj_type = ".$ilDB->quote($this->getContextObjType(), "text").
725  $and.
726  " ORDER BY ".$ordering;
727  }
728  else
729  {
730  $query = "SELECT il_news_item.* ".
731  ", il_news_read.user_id as user_read ".
732  "FROM il_news_item LEFT JOIN il_news_read ".
733  "ON il_news_item.id = il_news_read.news_id AND ".
734  " il_news_read.user_id = ".$ilDB->quote($ilUser->getId(), "integer").
735  " WHERE ".
736  "context_obj_id = ".$ilDB->quote($this->getContextObjId(), "integer").
737  " AND context_obj_type = ".$ilDB->quote($this->getContextObjType(), "text").
738  $and.
739  " ORDER BY ".$ordering;
740  }
741 //echo $query;
742  $set = $ilDB->query($query);
743  $result = array();
744  while($rec = $ilDB->fetchAssoc($set))
745  {
746  if ($a_limit > 0 && count($result) >= $a_limit)
747  {
748  continue;
749  }
750  if (!$a_for_rss_use || (ilNewsItem::getPrivateFeedId() != false) || ($rec["visibility"] == NEWS_PUBLIC ||
751  ($rec["priority"] == 0 &&
752  ilBlockSetting::_lookup("news", "public_notifications",
753  0, $rec["context_obj_id"]))))
754  {
755  $result[$rec["id"]] = $rec;
756  }
757  }
758 
759  // do we get data for rss and may the time limit by an issue?
760  // do a second query without time limit.
761  // this is not very performant, but I do not have a better
762  // idea. The keep_rss_min setting is currently (Jul 2012) only set
763  // by mediacasts
764  if ($a_time_period != "" && $a_for_rss_use)
765  {
766  include_once("./Services/Block/classes/class.ilBlockSetting.php");
767  $keep_rss_min = ilBlockSetting::_lookup("news", "keep_rss_min",
768  0, $this->getContextObjId());
769  if ($keep_rss_min > 0)
770  {
771  return $this->queryNewsForContext(true, 0,
772  $a_starting_date, $a_no_auto_generated, $a_oldest_first, $keep_rss_min);
773  }
774  }
775 
776  return $result;
777 
778  }
779 
787  public function checkNewsExistsForGroupCourse($a_ref_id, $a_time_period = 1)
788  {
789  global $tree, $ilDB;
790 
791  $all = array();
792 
793  if(!$tree->isDeleted($a_ref_id))
794  {
795  // parse repository branch of group
796  $nodes = array();
797  $node = $tree->getNodeData($a_ref_id);
798  foreach($tree->getSubTree($node) as $child)
799  {
800  if($child["type"] != "rolf")
801  {
802  $nodes[$child["obj_id"]] = $child["type"];
803  }
804  }
805 
806  $limit_ts = date('Y-m-d H:i:s', time() - ($a_time_period * 24 * 60 * 60));
807 
808  // are there any news items for relevant objects and?
809  $query = $ilDB->query("SELECT id,context_obj_id,context_obj_type".
810  " FROM il_news_item".
811  " WHERE ".$ilDB->in("context_obj_id", array_keys($nodes), false, "integer").
812  " AND creation_date >= ".$ilDB->quote($limit_ts, "timestamp"));
813  while($rec = $ilDB->fetchAssoc($query))
814  {
815  if ($nodes[$rec["context_obj_id"]] == $rec["context_obj_type"])
816  {
817  $all[] = $rec["id"];
818  }
819  }
820  }
821 
822  return $all;
823  }
824 
830  public function queryNewsForMultipleContexts($a_contexts, $a_for_rss_use = false,
831  $a_time_period = 0, $a_starting_date = "", $a_no_auto_generated = false,
832  $a_user_id = null)
833  {
834  global $ilDB, $ilUser, $lng, $ilCtrl;
835 
836  $and = "";
837  if ($a_time_period > 0)
838  {
839  $limit_ts = date('Y-m-d H:i:s', time() - ($a_time_period * 24 * 60 * 60));
840  $and = " AND creation_date >= ".$ilDB->quote($limit_ts, "timestamp")." ";
841  }
842 
843  if ($a_starting_date != "")
844  {
845  $and.= " AND creation_date > ".$ilDB->quote($a_starting_date, "timestamp")." ";
846  }
847 
848  if ($a_no_auto_generated)
849  {
850  $and.= " AND priority = 1 AND content_type = ".$ilDB->quote("text", "text")." ";
851  }
852 
853  $ids = array();
854  $type = array();
855  foreach($a_contexts as $cont)
856  {
857  $ids[] = $cont["obj_id"];
858  $type[$cont["obj_id"]] = $cont["obj_type"];
859  }
860 
861  if ($a_for_rss_use && ilNewsItem::getPrivateFeedId() == false)
862  {
863  $query = "SELECT * ".
864  "FROM il_news_item ".
865  " WHERE ".
866  $ilDB->in("context_obj_id", $ids, false, "integer")." ".
867  $and.
868  " ORDER BY creation_date DESC ";
869  }
870  elseif (ilNewsItem::getPrivateFeedId() != false)
871  {
872  $query = "SELECT il_news_item.* ".
873  ", il_news_read.user_id as user_read ".
874  "FROM il_news_item LEFT JOIN il_news_read ".
875  "ON il_news_item.id = il_news_read.news_id AND ".
876  " il_news_read.user_id = ".$ilDB->quote(ilNewsItem::getPrivateFeedId(), "integer").
877  " WHERE ".
878  $ilDB->in("context_obj_id", $ids, false, "integer")." ".
879  $and.
880  " ORDER BY creation_date DESC ";
881  }
882  else
883  {
884  if($a_user_id)
885  {
886  $user_id = $a_user_id;
887  }
888  else
889  {
890  $user_id = $ilUser->getId();
891  }
892  $query = "SELECT il_news_item.* ".
893  ", il_news_read.user_id as user_read ".
894  "FROM il_news_item LEFT JOIN il_news_read ".
895  "ON il_news_item.id = il_news_read.news_id AND ".
896  " il_news_read.user_id = ".$ilDB->quote($user_id, "integer").
897  " WHERE ".
898  $ilDB->in("context_obj_id", $ids, false, "integer")." ".
899  $and.
900  " ORDER BY creation_date DESC ";
901  }
902 
903  $set = $ilDB->query($query);
904  $result = array();
905  while($rec = $ilDB->fetchAssoc($set))
906  {
907  if ($type[$rec["context_obj_id"]] == $rec["context_obj_type"])
908  {
909  if (!$a_for_rss_use || ilNewsItem::getPrivateFeedId() != false || ($rec["visibility"] == NEWS_PUBLIC ||
910  ($rec["priority"] == 0 &&
911  ilBlockSetting::_lookup("news", "public_notifications",
912  0, $rec["context_obj_id"]))))
913  {
914  $result[$rec["id"]] = $rec;
915  }
916  }
917  }
918 
919  return $result;
920 
921  }
922 
923 
927  function _setRead($a_user_id, $a_news_id)
928  {
929  global $ilDB, $ilAppEventHandler;
930 
931  $ilDB->replace("il_news_read",
932  array(
933  "user_id" => array("integer", $a_user_id),
934  "news_id" => array("integer", $a_news_id)
935  ),
936  array()
937  );
938 
939  /*
940  $ilDB->manipulate("DELETE FROM il_news_read WHERE ".
941  "user_id = ".$ilDB->quote($a_user_id, "integer").
942  " AND news_id = ".$ilDB->quote($a_news_id, "integer"));
943  $ilDB->manipulate("INSERT INTO il_news_read (user_id, news_id) VALUES (".
944  $ilDB->quote($a_user_id, "integer").",".
945  $ilDB->quote($a_news_id, "integer").")");*/
946 
947  $ilAppEventHandler->raise("Services/News", "readNews",
948  array("user_id" => $a_user_id, "news_ids" => array($a_news_id)));
949  }
950 
954  function _setUnread($a_user_id, $a_news_id)
955  {
956  global $ilDB, $ilAppEventHandler;
957 
958  $ilDB->manipulate("DELETE FROM il_news_read (user_id, news_id) VALUES (".
959  " WHERE user_id = ".$ilDB->quote($a_user_id, "integer").
960  " AND news_id = ".$ilDB->quote($a_news_id, "integer"));
961 
962  $ilAppEventHandler->raise("Services/News", "unreadNews",
963  array("user_id" => $a_user_id, "news_ids" => array($a_news_id)));
964  }
965 
974  function mergeNews($n1, $n2)
975  {
976  foreach($n2 as $id => $news)
977  {
978  $n1[$id] = $news;
979  }
980 
981  return $n1;
982  }
983 
989  static function _getDefaultVisibilityForRefId($a_ref_id)
990  {
991  global $tree, $ilSetting;
992 
993  include_once("./Services/Block/classes/class.ilBlockSetting.php");
994 
995  $news_set = new ilSetting("news");
996  $default_visibility = ($news_set->get("default_visibility") != "")
997  ? $news_set->get("default_visibility")
998  : "users";
999 
1000  if ($tree->isInTree($a_ref_id))
1001  {
1002  $path = $tree->getPathFull($a_ref_id);
1003 
1004  foreach ($path as $key => $row)
1005  {
1006  if (!in_array($row["type"], array("root", "cat","crs", "fold", "grp", "icrs")))
1007  {
1008  continue;
1009  }
1010 
1011  $visibility = ilBlockSetting::_lookup("news", "default_visibility",
1012  0, $row["obj_id"]);
1013 
1014  if ($visibility != "")
1015  {
1016  $default_visibility = $visibility;
1017  }
1018  }
1019  }
1020 
1021  return $default_visibility;
1022  }
1023 
1024 
1029  public function delete()
1030  {
1031  global $ilDB;
1032 
1033  // delete il_news_read entries
1034  $ilDB->manipulate("DELETE FROM il_news_read ".
1035  " WHERE news_id = ".$ilDB->quote($this->getId(), "integer"));
1036 
1037  // delete multimedia object
1038  $mob = $this->getMobId();
1039 
1040  // delete
1041  parent::delete();
1042 
1043  // delete mob after news, to have a "mob usage" of 0
1044  if ($mob > 0 and ilObject::_exists($mob))
1045  {
1046  include_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
1047  $mob = new ilObjMediaObject($mob);
1048  $mob->delete();
1049  }
1050  }
1051 
1056  static public function deleteNewsOfContext($a_context_obj_id,
1057  $a_context_obj_type, $a_context_sub_obj_id = 0, $a_context_sub_obj_type = "")
1058  {
1059  global $ilDB;
1060 
1061  if ($a_context_obj_id == 0 || $a_context_obj_type == "")
1062  {
1063  return;
1064  }
1065 
1066  if ($a_context_sub_obj_id > 0)
1067  {
1068  $and = " AND context_sub_obj_id = ".$ilDB->quote($a_context_sub_obj_id, "integer").
1069  " AND context_sub_obj_type = ".$ilDB->quote($a_context_sub_obj_type, "text");
1070  }
1071 
1072  // get news records
1073  $query = "SELECT * FROM il_news_item".
1074  " WHERE context_obj_id = ".$ilDB->quote($a_context_obj_id, "integer").
1075  " AND context_obj_type = ".$ilDB->quote($a_context_obj_type, "text").
1076  $and;
1077 
1078  $news_set = $ilDB->query($query);
1079 
1080  while ($news = $ilDB->fetchAssoc($news_set))
1081  {
1082  $news_obj = new ilNewsItem($news["id"]);
1083  $news_obj->delete();
1084  }
1085  }
1086 
1090  static function _lookupTitle($a_news_id)
1091  {
1092  global $ilDB;
1093 
1094  $query = "SELECT title FROM il_news_item WHERE id = ".
1095  $ilDB->quote($a_news_id, "integer");
1096  $set = $ilDB->query($query);
1097  $rec = $ilDB->fetchAssoc($set);
1098  return $rec["title"];
1099  }
1100 
1104  static function _lookupVisibility($a_news_id)
1105  {
1106  global $ilDB;
1107 
1108  $query = "SELECT visibility FROM il_news_item WHERE id = ".
1109  $ilDB->quote($a_news_id, "integer");
1110  $set = $ilDB->query($query);
1111  $rec = $ilDB->fetchAssoc($set);
1112 
1113  return $rec["visibility"];
1114  }
1115 
1119  static function _lookupMobId($a_news_id)
1120  {
1121  global $ilDB;
1122 
1123  $query = "SELECT mob_id FROM il_news_item WHERE id = ".
1124  $ilDB->quote($a_news_id, "integer");
1125  $set = $ilDB->query($query);
1126  $rec = $ilDB->fetchAssoc($set);
1127  return $rec["mob_id"];
1128  }
1129 
1133  static function filterObjIdsPerNews($a_obj_ids, $a_time_period = 0, $a_starting_date = "",$a_ending_date = '', $ignore_period = false)
1134  {
1135  global $ilDB;
1136 
1137  $and = "";
1138  if ($a_time_period > 0)
1139  {
1140  $limit_ts = date('Y-m-d H:i:s', time() - ($a_time_period * 24 * 60 * 60));
1141  $and = " AND creation_date >= ".$ilDB->quote($limit_ts, "timestamp")." ";
1142  }
1143 
1144  if ($a_starting_date != "")
1145  {
1146  $and.= " AND creation_date >= ".$ilDB->quote($a_starting_date, "timestamp");
1147  }
1148 
1149  $query = "SELECT DISTINCT(context_obj_id) AS obj_id FROM il_news_item".
1150  " WHERE ".$ilDB->in("context_obj_id", $a_obj_ids, false, "integer")." ".$and;
1151  //" WHERE context_obj_id IN (".implode(ilUtil::quoteArray($a_obj_ids),",").")".$and;
1152 
1153  $set = $ilDB->query($query);
1154  $objs = array();
1155  while($rec = $ilDB->fetchAssoc($set))
1156  {
1157  $objs[] = $rec["obj_id"];
1158  }
1159 
1160  return $objs;
1161  }
1162 
1166  static function determineNewsTitle($a_context_obj_type, $a_title, $a_content_is_lang_var,
1167  $a_agg_ref_id = 0, $a_aggregation = "")
1168  {
1169  global $lng;
1170 
1171  if ($a_agg_ref_id > 0)
1172  {
1173  $cnt = count($a_aggregation);
1174 
1175  // forums
1176  if ($a_context_obj_type == "frm")
1177  {
1178  if ($cnt > 1)
1179  {
1180  return sprintf($lng->txt("news_x_postings"), $cnt);
1181  }
1182  else
1183  {
1184  return $lng->txt("news_1_postings");
1185  }
1186  }
1187  else // files
1188  {
1189  $up_cnt = $cr_cnt = 0;
1190  foreach($a_aggregation as $item)
1191  {
1192  if ($item["title"] == "file_updated")
1193  {
1194  $up_cnt++;
1195  }
1196  else
1197  {
1198  $cr_cnt++;
1199  }
1200  }
1201  $sep = "";
1202  if ($cr_cnt == 1)
1203  {
1204  $tit = $lng->txt("news_1_file_created");
1205  $sep = "<br />";
1206  }
1207  else if ($cr_cnt > 1)
1208  {
1209  $tit = sprintf($lng->txt("news_x_files_created"), $cr_cnt);
1210  $sep = "<br />";
1211  }
1212  if ($up_cnt == 1)
1213  {
1214  $tit .= $sep.$lng->txt("news_1_file_updated");
1215  }
1216  else if ($up_cnt > 1)
1217  {
1218  $tit .= $sep.sprintf($lng->txt("news_x_files_updated"), $up_cnt);
1219  }
1220  return $tit;
1221  }
1222  }
1223  else
1224  {
1225  if ($a_content_is_lang_var)
1226  {
1227  return $lng->txt($a_title);
1228  }
1229  else
1230  {
1231  return $a_title;
1232  }
1233  }
1234 
1235  return "";
1236  }
1237 
1241  static function determineNewsContent($a_context_obj_type, $a_content, $a_is_lang_var)
1242  {
1243  global $lng;
1244 
1245  if ($a_is_lang_var)
1246  {
1247  $lng->loadLanguageModule($a_context_obj_type);
1248  return $lng->txt($a_content);
1249  }
1250  else
1251  {
1252  return $a_content;
1253  }
1254  }
1255 
1256 
1257 
1261  static function getFirstNewsIdForContext($a_context_obj_id,
1262  $a_context_obj_type, $a_context_sub_obj_id = "", $a_context_sub_obj_type = "")
1263  {
1264  global $ilDB;
1265 
1266  // Determine how many rows should be deleted
1267  $query = "SELECT * ".
1268  "FROM il_news_item ".
1269  "WHERE ".
1270  "context_obj_id = ".$ilDB->quote($a_context_obj_id, "integer").
1271  " AND context_obj_type = ".$ilDB->quote($a_context_obj_type, "text").
1272  " AND context_sub_obj_id = ".$ilDB->quote($a_context_sub_obj_id, "integer").
1273  " AND ".$ilDB->equals("context_sub_obj_type", $a_context_sub_obj_type, "text", true);
1274 
1275  $set = $ilDB->query($query);
1276  $rec = $ilDB->fetchAssoc($set);
1277 
1278  return $rec["id"];
1279  }
1280 
1284  static function getLastNewsIdForContext($a_context_obj_id,
1285  $a_context_obj_type, $a_context_sub_obj_id = "", $a_context_sub_obj_type = "",
1286  $a_only_today = false)
1287  {
1288  global $ilDB;
1289 
1290  // Determine how many rows should be deleted
1291  $query = "SELECT id, update_date ".
1292  "FROM il_news_item ".
1293  "WHERE ".
1294  "context_obj_id = ".$ilDB->quote($a_context_obj_id, "integer").
1295  " AND context_obj_type = ".$ilDB->quote($a_context_obj_type, "text").
1296  " AND context_sub_obj_id = ".$ilDB->quote($a_context_sub_obj_id, "integer").
1297  " AND ".$ilDB->equals("context_sub_obj_type", $a_context_sub_obj_type, "text", true).
1298  " ORDER BY update_date DESC";
1299 
1300  $ilDB->setLimit(1);
1301  $set = $ilDB->query($query);
1302  $rec = $ilDB->fetchAssoc($set);
1303 
1304  $id = (int) $rec["id"];
1305  if ($a_only_today)
1306  {
1307  $now = ilUtil::now();
1308  if (substr($now, 0, 10) != substr($rec["update_date"], 0, 10))
1309  {
1310  $id = 0;
1311  }
1312  }
1313 
1314  return $id;
1315  }
1316 
1317 
1321  static function _lookupMediaObjectUsages($a_mob_id)
1322  {
1323  global $ilDB;
1324 
1325  $query = "SELECT * ".
1326  "FROM il_news_item ".
1327  "WHERE ".
1328  " mob_id = ".$ilDB->quote($a_mob_id, "integer");
1329 
1330  $usages = array();
1331  $set = $ilDB->query($query);
1332  while ($rec = $ilDB->fetchAssoc($set))
1333  {
1334  $usages[$rec["id"]] = array("type" => "news", "id" => $rec["id"]);
1335  }
1336 
1337  return $usages;
1338  }
1339 
1343  static function _lookupContextObjId($a_news_id)
1344  {
1345  global $ilDB;
1346 
1347  $query = "SELECT * ".
1348  "FROM il_news_item ".
1349  "WHERE ".
1350  " id = ".$ilDB->quote($a_news_id, "integer");
1351  $set = $ilDB->query($query);
1352  $rec = $ilDB->fetchAssoc($set);
1353 
1354  return $rec["context_obj_id"];
1355  }
1356 
1358  {
1359  $news_set = new ilSetting("news");
1360  $per = $news_set->get("pd_period");
1361  if ($per == 0)
1362  {
1363  $per = 30;
1364  }
1365 
1366  return $per;
1367  }
1368 
1369  function _lookupUserPDPeriod($a_user_id)
1370  {
1371  global $ilSetting;
1372 
1373  $news_set = new ilSetting("news");
1374  $allow_shorter_periods = $news_set->get("allow_shorter_periods");
1375  $allow_longer_periods = $news_set->get("allow_longer_periods");
1376  $default_per = ilNewsItem::_lookupDefaultPDPeriod();
1377 
1378  include_once("./Services/Block/classes/class.ilBlockSetting.php");
1379  $per = ilBlockSetting::_lookup("pdnews", "news_pd_period",
1380  $a_user_id, 0);
1381 
1382  // news period information
1383  if ($per <= 0 ||
1384  (!$allow_shorter_periods && ($per < $default_per)) ||
1385  (!$allow_longer_periods && ($per > $default_per))
1386  )
1387  {
1388  $per = $default_per;
1389  }
1390 
1391  return $per;
1392  }
1393 
1394  function _lookupRSSPeriod()
1395  {
1396  $news_set = new ilSetting("news");
1397  $rss_period = $news_set->get("rss_period");
1398  if ($rss_period == 0) // default to two weeks
1399  {
1400  $rss_period = 14;
1401  }
1402  return $rss_period;
1403  }
1404  function setPrivateFeedId ($a_userId)
1405  {
1406  ilNewsItem::$privFeedId = $a_userId;
1407  }
1408 
1409  function getPrivateFeedId () {
1410 
1411  return ilNewsItem::$privFeedId;
1412  }
1413 }
1414 ?>