ILIAS  Release_5_0_x_branch Revision 61816
 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 
85  function setMobPlayCounter($a_val)
86  {
87  $this->mob_cnt_play = $a_val;
88  }
89 
95  function getMobPlayCounter()
96  {
97  return $this->mob_cnt_play;
98  }
99 
105  function setMobDownloadCounter($a_val)
106  {
107  $this->mob_cnt_download = $a_val;
108  }
109 
116  {
117  return $this->mob_cnt_download;
118  }
119 
123  public function read()
124  {
125  global $ilDB;
126 
127  $query = "SELECT * FROM il_news_item WHERE id = ".
128  $ilDB->quote($this->getId(), "integer");
129  $set = $ilDB->query($query);
130  $rec = $ilDB->fetchAssoc($set);
131 
132  $this->setTitle($rec["title"]);
133  $this->setContent($rec["content"]);
134  $this->setContextObjId((int) $rec["context_obj_id"]);
135  $this->setContextObjType($rec["context_obj_type"]);
136  $this->setContextSubObjId((int) $rec["context_sub_obj_id"]);
137  $this->setContextSubObjType($rec["context_sub_obj_type"]);
138  $this->setContentType($rec["content_type"]);
139  $this->setCreationDate($rec["creation_date"]);
140  $this->setUpdateDate($rec["update_date"]);
141  $this->setUserId($rec["user_id"]);
142  $this->setVisibility($rec["visibility"]);
143  $this->setContentLong($rec["content_long"]);
144  $this->setPriority($rec["priority"]);
145  $this->setContentIsLangVar($rec["content_is_lang_var"]);
146  $this->setContentTextIsLangVar((int) $rec["content_text_is_lang_var"]);
147  $this->setMobId($rec["mob_id"]);
148  $this->setPlaytime($rec["playtime"]);
149  $this->setMobPlayCounter($rec["mob_cnt_play"]);
150  $this->setMobDownloadCounter($rec["mob_cnt_download"]);
151 
152  }
153 
157  function create()
158  {
159  global $ilDB;
160 
161  // insert new record into db
162  $this->setId($ilDB->nextId("il_news_item"));
163  $ilDB->insert("il_news_item", array(
164  "id" => array("integer", $this->getId()),
165  "title" => array("text", $this->getTitle()),
166  "content" => array("clob", $this->getContent()),
167  "context_obj_id" => array("integer", (int) $this->getContextObjId()),
168  "context_obj_type" => array("text", $this->getContextObjType()),
169  "context_sub_obj_id" => array("integer", (int) $this->getContextSubObjId()),
170  "context_sub_obj_type" => array("text", $this->getContextSubObjType()),
171  "content_type" => array("text", $this->getContentType()),
172  "creation_date" => array("timestamp", ilUtil::now()),
173  "update_date" => array("timestamp", ilUtil::now()),
174  "user_id" => array("integer", $this->getUserId()),
175  "visibility" => array("text", $this->getVisibility()),
176  "content_long" => array("clob", $this->getContentLong()),
177  "priority" => array("integer", $this->getPriority()),
178  "content_is_lang_var" => array("integer", $this->getContentIsLangVar()),
179  "content_text_is_lang_var" => array("integer", (int) $this->getContentTextIsLangVar()),
180  "mob_id" => array("integer", $this->getMobId()),
181  "playtime" => array("text", $this->getPlaytime())
182  ));
183 
184 
185  $news_set = new ilSetting("news");
186  $max_items = $news_set->get("max_items");
187  if ($max_items <= 0)
188  {
189  $max_items = 50;
190  }
191 
192  // limit number of news
193  if ($this->getLimitation())
194  {
195  // Determine how many rows should be deleted
196  $query = "SELECT count(*) cnt ".
197  "FROM il_news_item ".
198  "WHERE ".
199  "context_obj_id = ".$ilDB->quote($this->getContextObjId(), "integer").
200  " AND context_obj_type = ".$ilDB->quote($this->getContextObjType(), "text").
201  " AND context_sub_obj_id = ".$ilDB->quote($this->getContextSubObjId(), "integer").
202  " AND ".$ilDB->equals("context_sub_obj_type", $this->getContextSubObjType(), "text", true)." ";
203 
204  $set = $ilDB->query($query);
205  $rec = $ilDB->fetchAssoc($set);
206 
207  // if we have more records than allowed, delete them
208  if (($rec["cnt"] > $max_items) && $this->getContextObjId() > 0)
209  {
210  $query = "SELECT * ".
211  "FROM il_news_item ".
212  "WHERE ".
213  "context_obj_id = ".$ilDB->quote($this->getContextObjId(), "integer").
214  " AND context_obj_type = ".$ilDB->quote($this->getContextObjType(), "text").
215  " AND context_sub_obj_id = ".$ilDB->quote($this->getContextSubObjId(), "integer").
216  " AND ".$ilDB->equals("context_sub_obj_type", $this->getContextSubObjType(), "text", true).
217  " ORDER BY creation_date ASC";
218 
219  $ilDB->setLimit($rec["cnt"] - $max_items);
220  $del_set = $ilDB->query($query);
221  while ($del_item = $ilDB->fetchAssoc($del_set))
222  {
223  $del_news = new ilNewsItem($del_item["id"]);
224  $del_news->delete();
225  }
226  }
227  }
228  }
229 
235  public function update($a_as_new = false)
236  {
237  global $ilDB;
238 
239  $fields = array(
240  "title" => array("text", $this->getTitle()),
241  "content" => array("clob", $this->getContent()),
242  "context_obj_id" => array("integer", $this->getContextObjId()),
243  "context_obj_type" => array("text", $this->getContextObjType()),
244  "context_sub_obj_id" => array("integer", $this->getContextSubObjId()),
245  "context_sub_obj_type" => array("text", $this->getContextSubObjType()),
246  "content_type" => array("text", $this->getContentType()),
247  "user_id" => array("integer", $this->getUserId()),
248  "visibility" => array("text", $this->getVisibility()),
249  "content_long" => array("clob", $this->getContentLong()),
250  "priority" => array("integer", $this->getPriority()),
251  "content_is_lang_var" => array("integer", $this->getContentIsLangVar()),
252  "content_text_is_lang_var" => array("integer", (int) $this->getContentTextIsLangVar()),
253  "mob_id" => array("integer", $this->getMobId()),
254  "mob_cnt_play" => array("integer", $this->getMobPlayCounter()),
255  "mob_cnt_download" => array("integer", $this->getMobDownloadCounter()),
256  "playtime" => array("text", $this->getPlaytime())
257  );
258 
259  $now = ilUtil::now();
260  if ($a_as_new)
261  {
262  $fields["creation_date"] = array("timestamp", $now);
263  $fields["update_date"] = array("timestamp", $now);
264  }
265  else
266  {
267  $fields["update_date"] = array("timestamp", $now);
268  }
269 
270  $ilDB->update("il_news_item", $fields, array(
271  "id" => array("integer", $this->getId())
272  ));
273 
274  }
275 
276 
280  static function _getNewsItemsOfUser($a_user_id, $a_only_public = false,
281  $a_prevent_aggregation = false, $a_per = 0, &$a_cnt = NULL)
282  {
283  global $ilAccess;
284 
285  $news_item = new ilNewsItem();
286  $news_set = new ilSetting("news");
287 
288  $per = $a_per;
289 
290  include_once("./Services/News/classes/class.ilNewsSubscription.php");
291  include_once("./Services/Block/classes/class.ilBlockSetting.php");
292 
293  // this is currently not used
294  $ref_ids = ilNewsSubscription::_getSubscriptionsOfUser($a_user_id);
295 
296  if (ilObjUser::_lookupPref($a_user_id, "pd_items_news") != "n")
297  {
298  // get all items of the personal desktop
299  $pd_items = ilObjUser::_lookupDesktopItems($a_user_id);
300  foreach($pd_items as $item)
301  {
302  if (!in_array($item["ref_id"], $ref_ids))
303  {
304  $ref_ids[] = $item["ref_id"];
305  }
306  }
307 
308  // get all memberships
309  include_once 'Services/Membership/classes/class.ilParticipants.php';
310  $crs_mbs = ilParticipants::_getMembershipByType($a_user_id, 'crs');
311  $grp_mbs = ilParticipants::_getMembershipByType($a_user_id, 'grp');
312  $items = array_merge($crs_mbs, $grp_mbs);
313  foreach($items as $i)
314  {
315  $item_references = ilObject::_getAllReferences($i);
316  if(is_array($item_references) && count($item_references))
317  {
318  foreach($item_references as $ref_id)
319  {
320  if (!in_array($ref_id, $ref_ids))
321  {
322  $ref_ids[] = $ref_id;
323  }
324  }
325  }
326  }
327  }
328 
329  $data = array();
330 
331  foreach($ref_ids as $ref_id)
332  {
333  if (!$a_only_public)
334  {
335  // this loop should not cost too much performance
336  $acc = $ilAccess->checkAccessOfUser($a_user_id, "read", "", $ref_id);
337 
338  if (!$acc)
339  {
340  continue;
341  }
342  }
343  if (ilNewsItem::getPrivateFeedId() != false) {
344  global $rbacsystem;
345  $acc = $rbacsystem->checkAccessOfUser(ilNewsItem::getPrivateFeedId(),"read", $ref_id);
346 
347  if (!$acc)
348  {
349  continue;
350  }
351  }
352 
353  $obj_id = ilObject::_lookupObjId($ref_id);
354  $obj_type = ilObject::_lookupType($obj_id);
355  $news = $news_item->getNewsForRefId($ref_id, $a_only_public, false,
356  $per, $a_prevent_aggregation, false, false, false, $a_user_id);
357 
358  // counter
359  if (!is_null($a_cnt))
360  {
361  $a_cnt[$ref_id] = count($news);
362  }
363 
364  $data = ilNewsItem::mergeNews($data, $news);
365  }
366 
367  $data = ilUtil::sortArray($data, "creation_date", "desc", false, true);
368 
369  return $data;
370  }
371 
377  function getNewsForRefId($a_ref_id, $a_only_public = false, $a_stopnesting = false,
378  $a_time_period = 0, $a_prevent_aggregation = true, $a_forum_group_sequences = false,
379  $a_no_auto_generated = false, $a_ignore_date_filter = false, $a_user_id = null)
380  {
381  $obj_id = ilObject::_lookupObjId($a_ref_id);
382  $obj_type = ilObject::_lookupType($obj_id);
383 
384  // get starting date
385  $starting_date = "";
386  if ($obj_type == "grp" || $obj_type == "crs" || $obj_type == "cat")
387  {
388  include_once("./Services/Block/classes/class.ilBlockSetting.php");
389  $hide_news_per_date = ilBlockSetting::_lookup("news", "hide_news_per_date",
390  0, $obj_id);
391  if ($hide_news_per_date && !$a_ignore_date_filter)
392  {
393  $starting_date = ilBlockSetting::_lookup("news", "hide_news_date",
394  0, $obj_id);
395  }
396  }
397 
398  if ($obj_type == "cat" && !$a_stopnesting)
399  {
400  $news = $this->getAggregatedChildNewsData($a_ref_id, $a_only_public, $a_time_period,
401  $a_prevent_aggregation, $starting_date, $a_no_auto_generated);
402  }
403  else if (($obj_type == "grp" || $obj_type == "crs") &&
404  !$a_stopnesting)
405  {
406  $news = $this->getAggregatedNewsData($a_ref_id, $a_only_public, $a_time_period,
407  $a_prevent_aggregation, $starting_date, $a_no_auto_generated, $a_user_id);
408  }
409  else
410  {
411  $news_item = new ilNewsItem();
412  $news_item->setContextObjId($obj_id);
413  $news_item->setContextObjType($obj_type);
414  $news = $news_item->queryNewsForContext($a_only_public, $a_time_period,
415  $starting_date, $a_no_auto_generated);
416  $unset = array();
417  foreach ($news as $k => $v)
418  {
419  if (!$a_only_public || $v["visibility"] == NEWS_PUBLIC ||
420  ($v["priority"] == 0 &&
421  ilBlockSetting::_lookup("news", "public_notifications",
422  0, $obj_id)))
423  {
424  $news[$k]["ref_id"] = $a_ref_id;
425  }
426  else
427  {
428  $unset[] = $k;
429  }
430  }
431  foreach ($unset as $un)
432  {
433  unset($news[$un]);
434  }
435  }
436 
437  if (!$a_prevent_aggregation)
438  {
439  $news = $this->aggregateForums($news);
440  }
441  else if ($a_forum_group_sequences)
442  {
443  $news = $this->aggregateForums($news, true);
444  }
445 
446  return $news;
447  }
448 
452  function getAggregatedNewsData($a_ref_id, $a_only_public = false, $a_time_period = 0,
453  $a_prevent_aggregation = false, $a_starting_date = "", $a_no_auto_generated = false,
454  $a_user_id = null)
455  {
456  global $tree, $ilAccess, $ilObjDataCache;
457 
458  // get news of parent object
459 
460  $data = array();
461 
462  // get subtree
463  $cur_node = $tree->getNodeData($a_ref_id);
464 
465  // do not check for lft (materialized path)
466  if($cur_node)
467  {
468  $nodes = (array) $tree->getSubTree($cur_node,true);
469  }
470  else
471  {
472  $nodes = array();
473  }
474 
475  // preload object data cache
476  $ref_ids = array();
477  $obj_ids = array();
478  foreach($nodes as $node)
479  {
480  $ref_ids[] = $node["child"];
481  $obj_ids[] = $node["obj_id"];
482  }
483 
484  $ilObjDataCache->preloadReferenceCache($ref_ids);
485  if (!$a_only_public)
486  {
487  include_once "Services/Object/classes/class.ilObjectActivation.php";
489  }
490 
491  // no check, for which of the objects any news are available
492  $news_obj_ids = ilNewsItem::filterObjIdsPerNews($obj_ids, $a_time_period, $a_starting_date);
493  //$news_obj_ids = $obj_ids;
494 
495  // get news for all subtree nodes
496  $contexts = array();
497  foreach($nodes as $node)
498  {
499  // only go on, if news are available
500  if (!in_array($node["obj_id"], $news_obj_ids))
501  {
502  continue;
503  }
504 
505  if (!$a_only_public)
506  {
507  if(!$a_user_id)
508  {
509  $acc = $ilAccess->checkAccess("read", "", $node["child"]);
510  }
511  else
512  {
513  $acc = $ilAccess->checkAccessOfUser($a_user_id, "read", "",
514  $node["child"]);
515  }
516  if (!$acc)
517  {
518  continue;
519  }
520  }
521 
522  $ref_id[$node["obj_id"]] = $node["child"];
523  $contexts[] = array("obj_id" => $node["obj_id"],
524  "obj_type" => $node["type"]);
525  }
526 
527  // sort and return
528  $news = $this->queryNewsForMultipleContexts($contexts, $a_only_public, $a_time_period,
529  $a_starting_date, $a_no_auto_generated, $a_user_id);
530 
531  $to_del = array();
532  foreach ($news as $k => $v)
533  {
534  $news[$k]["ref_id"] = $ref_id[$v["context_obj_id"]];
535  }
536 
537  $data = ilNewsItem::mergeNews($data, $news);
538  $data = ilUtil::sortArray($data, "creation_date", "desc", false, true);
539 
540  if (!$a_prevent_aggregation)
541  {
542  $data = $this->aggregateFiles($data, $a_ref_id);
543  }
544 
545  return $data;
546  }
547 
548  function aggregateForums($news, $a_group_posting_sequence = false)
549  {
550  $to_del = array();
551  $forums = array();
552 
553  // aggregate
554  foreach ($news as $k => $v)
555  {
556  if ($a_group_posting_sequence && $last_aggregation_forum > 0 &&
557  $last_aggregation_forum != $news[$k]["context_obj_id"])
558  {
559  $forums[$last_aggregation_forum] = "";
560  }
561 
562  if ($news[$k]["context_obj_type"] == "frm")
563  {
564  if ($forums[$news[$k]["context_obj_id"]] == "")
565  {
566  // $forums[forum_id] = news_id;
567  $forums[$news[$k]["context_obj_id"]] = $k;
568  $last_aggregation_forum = $news[$k]["context_obj_id"];
569  }
570  else
571  {
572  $to_del[] = $k;
573  }
574 
575  $news[$k]["no_context_title"] = true;
576 
577  // aggregate every forum into it's "k" news
578  $news[$forums[$news[$k]["context_obj_id"]]]["aggregation"][$k]
579  = $news[$k];
580  $news[$k]["agg_ref_id"]
581  = $news[$k]["ref_id"];
582  $news[$k]["content"] = "";
583  $news[$k]["content_long"] = "";
584  }
585  }
586 
587  // delete double entries
588  foreach($to_del as $k)
589  {
590  unset($news[$k]);
591  }
592 //var_dump($news[14]["aggregation"]);
593 
594 
595  return $news;
596  }
597 
598  function aggregateFiles($news, $a_ref_id)
599  {
600  $first_file = "";
601  $to_del = array();
602  foreach ($news as $k => $v)
603  {
604  // aggregate file related news
605  if ($news[$k]["context_obj_type"] == "file")
606  {
607  if ($first_file == "")
608  {
609  $first_file = $k;
610  }
611  else
612  {
613  $to_del[] = $k;
614  }
615  $news[$first_file]["aggregation"][$k] = $news[$k];
616  $news[$first_file]["agg_ref_id"] = $a_ref_id;
617  $news[$first_file]["ref_id"] = $a_ref_id;
618  }
619  }
620 
621  foreach($to_del as $v)
622  {
623  unset($news[$v]);
624  }
625 
626  return $news;
627  }
628 
629 
633  function getAggregatedChildNewsData($a_ref_id, $a_only_public = false,
634  $a_time_period = 0, $a_prevent_aggregation = false, $a_starting_date = "",
635  $a_no_auto_generated = false)
636  {
637  global $tree, $ilAccess;
638 
639  // get news of parent object
640  $data = $this->getNewsForRefId($a_ref_id, $a_only_public, true, $a_time_period,
641  true, false, false, $a_no_auto_generated);
642  foreach ($data as $k => $v)
643  {
644  $data[$k]["ref_id"] = $a_ref_id;
645  }
646 
647  // get childs
648  $nodes = $tree->getChilds($a_ref_id);
649 
650  // no check, for which of the objects any news are available
651  $obj_ids = array();
652  foreach($nodes as $node)
653  {
654  $obj_ids[] = $node["obj_id"];
655  }
656  $news_obj_ids = ilNewsItem::filterObjIdsPerNews($obj_ids, $a_time_period, $a_starting_date);
657  //$news_obj_ids = $obj_ids;
658 
659  // get news for all subtree nodes
660  $contexts = array();
661  foreach($nodes as $node)
662  {
663  // only go on, if news are available
664  if (!in_array($node["obj_id"], $news_obj_ids))
665  {
666  continue;
667  }
668 
669  if (!$a_only_public && !$ilAccess->checkAccess("read", "", $node["child"]))
670  {
671  continue;
672  }
673  $ref_id[$node["obj_id"]] = $node["child"];
674  $contexts[] = array("obj_id" => $node["obj_id"],
675  "obj_type" => $node["type"]);
676  }
677 
678  $news = $this->queryNewsForMultipleContexts($contexts, $a_only_public, $a_time_period,
679  $a_starting_date, $a_no_auto_generated);
680  foreach ($news as $k => $v)
681  {
682  $news[$k]["ref_id"] = $ref_id[$v["context_obj_id"]];
683  }
684  $data = ilNewsItem::mergeNews($data, $news);
685 
686  // sort and return
687  $data = ilUtil::sortArray($data, "creation_date", "desc", false, true);
688 
689  if (!$a_prevent_aggregation)
690  {
691  $data = $this->aggregateFiles($data, $a_ref_id);
692  }
693 
694  return $data;
695  }
696 
700  function setContext($a_obj_id, $a_obj_type, $a_sub_obj_id = 0, $a_sub_obj_type = "")
701  {
702  $this->setContextObjId($a_obj_id);
703  $this->setContextObjType($a_obj_type);
704  $this->setContextSubObjId($a_sub_obj_id);
705  $this->setContextSubObjType($a_sub_obj_type);
706  }
707 
716  public function queryNewsForContext($a_for_rss_use = false, $a_time_period = 0,
717  $a_starting_date = "", $a_no_auto_generated = false, $a_oldest_first = false, $a_limit = 0)
718  {
719  global $ilDB, $ilUser, $lng;
720 
721  $and = "";
722  if ($a_time_period > 0)
723  {
724  $limit_ts = date('Y-m-d H:i:s', time() - ($a_time_period * 24 * 60 * 60));
725  $and = " AND creation_date >= ".$ilDB->quote($limit_ts, "timestamp")." ";
726  }
727 
728  if ($a_starting_date != "")
729  {
730  $and.= " AND creation_date > ".$ilDB->quote($a_starting_date, "timestamp")." ";
731  }
732 
733  if ($a_no_auto_generated)
734  {
735  $and.= " AND priority = 1 AND content_type = ".$ilDB->quote("text", "text")." ";
736  }
737 
738  // this is changed with 4.1 (news table for lm pages)
739  if ($this->getContextSubObjId() > 0)
740  {
741  $and.= " AND context_sub_obj_id = ".$ilDB->quote($this->getContextSubObjId(), "integer").
742  " AND context_sub_obj_type = ".$ilDB->quote($this->getContextSubObjType(), "text");
743  }
744 
745  $ordering = ($a_oldest_first)
746  ? " creation_date ASC, id ASC "
747  : " creation_date DESC, id DESC ";
748 
749  if ($a_for_rss_use && ilNewsItem::getPrivateFeedId() == false)
750  {
751  $query = "SELECT * ".
752  "FROM il_news_item ".
753  " WHERE ".
754  "context_obj_id = ".$ilDB->quote($this->getContextObjId(), "integer").
755  " AND context_obj_type = ".$ilDB->quote($this->getContextObjType(), "text").
756  $and.
757  " ORDER BY ".$ordering;
758  }
759  elseif (ilNewsItem::getPrivateFeedId() != false)
760  {
761  $query = "SELECT il_news_item.* ".
762  ", il_news_read.user_id user_read ".
763  "FROM il_news_item LEFT JOIN il_news_read ".
764  "ON il_news_item.id = il_news_read.news_id AND ".
765  " il_news_read.user_id = ".$ilDB->quote(ilNewsItem::getPrivateFeedId(), "integer").
766  " WHERE ".
767  "context_obj_id = ".$ilDB->quote($this->getContextObjId(), "integer").
768  " AND context_obj_type = ".$ilDB->quote($this->getContextObjType(), "text").
769  $and.
770  " ORDER BY ".$ordering;
771  }
772  else
773  {
774  $query = "SELECT il_news_item.* ".
775  ", il_news_read.user_id as user_read ".
776  "FROM il_news_item LEFT JOIN il_news_read ".
777  "ON il_news_item.id = il_news_read.news_id AND ".
778  " il_news_read.user_id = ".$ilDB->quote($ilUser->getId(), "integer").
779  " WHERE ".
780  "context_obj_id = ".$ilDB->quote($this->getContextObjId(), "integer").
781  " AND context_obj_type = ".$ilDB->quote($this->getContextObjType(), "text").
782  $and.
783  " ORDER BY ".$ordering;
784  }
785 //echo $query;
786  $set = $ilDB->query($query);
787  $result = array();
788  while($rec = $ilDB->fetchAssoc($set))
789  {
790  if ($a_limit > 0 && count($result) >= $a_limit)
791  {
792  continue;
793  }
794  if (!$a_for_rss_use || (ilNewsItem::getPrivateFeedId() != false) || ($rec["visibility"] == NEWS_PUBLIC ||
795  ($rec["priority"] == 0 &&
796  ilBlockSetting::_lookup("news", "public_notifications",
797  0, $rec["context_obj_id"]))))
798  {
799  $result[$rec["id"]] = $rec;
800  }
801  }
802 
803  // do we get data for rss and may the time limit by an issue?
804  // do a second query without time limit.
805  // this is not very performant, but I do not have a better
806  // idea. The keep_rss_min setting is currently (Jul 2012) only set
807  // by mediacasts
808  if ($a_time_period != "" && $a_for_rss_use)
809  {
810  include_once("./Services/Block/classes/class.ilBlockSetting.php");
811  $keep_rss_min = ilBlockSetting::_lookup("news", "keep_rss_min",
812  0, $this->getContextObjId());
813  if ($keep_rss_min > 0)
814  {
815  return $this->queryNewsForContext(true, 0,
816  $a_starting_date, $a_no_auto_generated, $a_oldest_first, $keep_rss_min);
817  }
818  }
819 
820  return $result;
821 
822  }
823 
831  public function checkNewsExistsForGroupCourse($a_ref_id, $a_time_period = 1)
832  {
833  global $tree, $ilDB;
834 
835  $all = array();
836 
837  if(!$tree->isDeleted($a_ref_id))
838  {
839  // parse repository branch of group
840  $nodes = array();
841  $node = $tree->getNodeData($a_ref_id);
842  foreach($tree->getSubTree($node) as $child)
843  {
844  if($child["type"] != "rolf")
845  {
846  $nodes[$child["obj_id"]] = $child["type"];
847  }
848  }
849 
850  $limit_ts = date('Y-m-d H:i:s', time() - ($a_time_period * 24 * 60 * 60));
851 
852  // are there any news items for relevant objects and?
853  $query = $ilDB->query("SELECT id,context_obj_id,context_obj_type".
854  " FROM il_news_item".
855  " WHERE ".$ilDB->in("context_obj_id", array_keys($nodes), false, "integer").
856  " AND creation_date >= ".$ilDB->quote($limit_ts, "timestamp"));
857  while($rec = $ilDB->fetchAssoc($query))
858  {
859  if ($nodes[$rec["context_obj_id"]] == $rec["context_obj_type"])
860  {
861  $all[] = $rec["id"];
862  }
863  }
864  }
865 
866  return $all;
867  }
868 
874  public function queryNewsForMultipleContexts($a_contexts, $a_for_rss_use = false,
875  $a_time_period = 0, $a_starting_date = "", $a_no_auto_generated = false,
876  $a_user_id = null)
877  {
878  global $ilDB, $ilUser, $lng, $ilCtrl;
879 
880  $and = "";
881  if ($a_time_period > 0)
882  {
883  $limit_ts = date('Y-m-d H:i:s', time() - ($a_time_period * 24 * 60 * 60));
884  $and = " AND creation_date >= ".$ilDB->quote($limit_ts, "timestamp")." ";
885  }
886 
887  if ($a_starting_date != "")
888  {
889  $and.= " AND creation_date > ".$ilDB->quote($a_starting_date, "timestamp")." ";
890  }
891 
892  if ($a_no_auto_generated)
893  {
894  $and.= " AND priority = 1 AND content_type = ".$ilDB->quote("text", "text")." ";
895  }
896 
897  $ids = array();
898  $type = array();
899  foreach($a_contexts as $cont)
900  {
901  $ids[] = $cont["obj_id"];
902  $type[$cont["obj_id"]] = $cont["obj_type"];
903  }
904 
905  if ($a_for_rss_use && ilNewsItem::getPrivateFeedId() == false)
906  {
907  $query = "SELECT * ".
908  "FROM il_news_item ".
909  " WHERE ".
910  $ilDB->in("context_obj_id", $ids, false, "integer")." ".
911  $and.
912  " ORDER BY creation_date DESC ";
913  }
914  elseif (ilNewsItem::getPrivateFeedId() != false)
915  {
916  $query = "SELECT il_news_item.* ".
917  ", il_news_read.user_id as user_read ".
918  "FROM il_news_item LEFT JOIN il_news_read ".
919  "ON il_news_item.id = il_news_read.news_id AND ".
920  " il_news_read.user_id = ".$ilDB->quote(ilNewsItem::getPrivateFeedId(), "integer").
921  " WHERE ".
922  $ilDB->in("context_obj_id", $ids, false, "integer")." ".
923  $and.
924  " ORDER BY creation_date DESC ";
925  }
926  else
927  {
928  if($a_user_id)
929  {
930  $user_id = $a_user_id;
931  }
932  else
933  {
934  $user_id = $ilUser->getId();
935  }
936  $query = "SELECT il_news_item.* ".
937  ", il_news_read.user_id as user_read ".
938  "FROM il_news_item LEFT JOIN il_news_read ".
939  "ON il_news_item.id = il_news_read.news_id AND ".
940  " il_news_read.user_id = ".$ilDB->quote($user_id, "integer").
941  " WHERE ".
942  $ilDB->in("context_obj_id", $ids, false, "integer")." ".
943  $and.
944  " ORDER BY creation_date DESC ";
945  }
946 
947  $set = $ilDB->query($query);
948  $result = array();
949  while($rec = $ilDB->fetchAssoc($set))
950  {
951  if ($type[$rec["context_obj_id"]] == $rec["context_obj_type"])
952  {
953  if (!$a_for_rss_use || ilNewsItem::getPrivateFeedId() != false || ($rec["visibility"] == NEWS_PUBLIC ||
954  ($rec["priority"] == 0 &&
955  ilBlockSetting::_lookup("news", "public_notifications",
956  0, $rec["context_obj_id"]))))
957  {
958  $result[$rec["id"]] = $rec;
959  }
960  }
961  }
962 
963  return $result;
964 
965  }
966 
967 
971  function _setRead($a_user_id, $a_news_id)
972  {
973  global $ilDB, $ilAppEventHandler;
974 
975  $ilDB->replace("il_news_read",
976  array(
977  "user_id" => array("integer", $a_user_id),
978  "news_id" => array("integer", $a_news_id)
979  ),
980  array()
981  );
982 
983  /*
984  $ilDB->manipulate("DELETE FROM il_news_read WHERE ".
985  "user_id = ".$ilDB->quote($a_user_id, "integer").
986  " AND news_id = ".$ilDB->quote($a_news_id, "integer"));
987  $ilDB->manipulate("INSERT INTO il_news_read (user_id, news_id) VALUES (".
988  $ilDB->quote($a_user_id, "integer").",".
989  $ilDB->quote($a_news_id, "integer").")");*/
990 
991  $ilAppEventHandler->raise("Services/News", "readNews",
992  array("user_id" => $a_user_id, "news_ids" => array($a_news_id)));
993  }
994 
998  function _setUnread($a_user_id, $a_news_id)
999  {
1000  global $ilDB, $ilAppEventHandler;
1001 
1002  $ilDB->manipulate("DELETE FROM il_news_read (user_id, news_id) VALUES (".
1003  " WHERE user_id = ".$ilDB->quote($a_user_id, "integer").
1004  " AND news_id = ".$ilDB->quote($a_news_id, "integer"));
1005 
1006  $ilAppEventHandler->raise("Services/News", "unreadNews",
1007  array("user_id" => $a_user_id, "news_ids" => array($a_news_id)));
1008  }
1009 
1018  function mergeNews($n1, $n2)
1019  {
1020  foreach($n2 as $id => $news)
1021  {
1022  $n1[$id] = $news;
1023  }
1024 
1025  return $n1;
1026  }
1027 
1033  static function _getDefaultVisibilityForRefId($a_ref_id)
1034  {
1035  global $tree, $ilSetting;
1036 
1037  include_once("./Services/Block/classes/class.ilBlockSetting.php");
1038 
1039  $news_set = new ilSetting("news");
1040  $default_visibility = ($news_set->get("default_visibility") != "")
1041  ? $news_set->get("default_visibility")
1042  : "users";
1043 
1044  if ($tree->isInTree($a_ref_id))
1045  {
1046  $path = $tree->getPathFull($a_ref_id);
1047 
1048  foreach ($path as $key => $row)
1049  {
1050  if (!in_array($row["type"], array("root", "cat","crs", "fold", "grp", "icrs")))
1051  {
1052  continue;
1053  }
1054 
1055  $visibility = ilBlockSetting::_lookup("news", "default_visibility",
1056  0, $row["obj_id"]);
1057 
1058  if ($visibility != "")
1059  {
1060  $default_visibility = $visibility;
1061  }
1062  }
1063  }
1064 
1065  return $default_visibility;
1066  }
1067 
1068 
1073  public function delete()
1074  {
1075  global $ilDB;
1076 
1077  // delete il_news_read entries
1078  $ilDB->manipulate("DELETE FROM il_news_read ".
1079  " WHERE news_id = ".$ilDB->quote($this->getId(), "integer"));
1080 
1081  // delete multimedia object
1082  $mob = $this->getMobId();
1083 
1084  // delete
1085  parent::delete();
1086 
1087  // delete mob after news, to have a "mob usage" of 0
1088  if ($mob > 0 and ilObject::_exists($mob))
1089  {
1090  include_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
1091  $mob = new ilObjMediaObject($mob);
1092  $mob->delete();
1093  }
1094  }
1095 
1100  static public function deleteNewsOfContext($a_context_obj_id,
1101  $a_context_obj_type, $a_context_sub_obj_id = 0, $a_context_sub_obj_type = "")
1102  {
1103  global $ilDB;
1104 
1105  if ($a_context_obj_id == 0 || $a_context_obj_type == "")
1106  {
1107  return;
1108  }
1109 
1110  if ($a_context_sub_obj_id > 0)
1111  {
1112  $and = " AND context_sub_obj_id = ".$ilDB->quote($a_context_sub_obj_id, "integer").
1113  " AND context_sub_obj_type = ".$ilDB->quote($a_context_sub_obj_type, "text");
1114  }
1115 
1116  // get news records
1117  $query = "SELECT * FROM il_news_item".
1118  " WHERE context_obj_id = ".$ilDB->quote($a_context_obj_id, "integer").
1119  " AND context_obj_type = ".$ilDB->quote($a_context_obj_type, "text").
1120  $and;
1121 
1122  $news_set = $ilDB->query($query);
1123 
1124  while ($news = $ilDB->fetchAssoc($news_set))
1125  {
1126  $news_obj = new ilNewsItem($news["id"]);
1127  $news_obj->delete();
1128  }
1129  }
1130 
1134  static function _lookupTitle($a_news_id)
1135  {
1136  global $ilDB;
1137 
1138  $query = "SELECT title FROM il_news_item WHERE id = ".
1139  $ilDB->quote($a_news_id, "integer");
1140  $set = $ilDB->query($query);
1141  $rec = $ilDB->fetchAssoc($set);
1142  return $rec["title"];
1143  }
1144 
1148  static function _lookupVisibility($a_news_id)
1149  {
1150  global $ilDB;
1151 
1152  $query = "SELECT visibility FROM il_news_item WHERE id = ".
1153  $ilDB->quote($a_news_id, "integer");
1154  $set = $ilDB->query($query);
1155  $rec = $ilDB->fetchAssoc($set);
1156 
1157  return $rec["visibility"];
1158  }
1159 
1163  static function _lookupMobId($a_news_id)
1164  {
1165  global $ilDB;
1166 
1167  $query = "SELECT mob_id FROM il_news_item WHERE id = ".
1168  $ilDB->quote($a_news_id, "integer");
1169  $set = $ilDB->query($query);
1170  $rec = $ilDB->fetchAssoc($set);
1171  return $rec["mob_id"];
1172  }
1173 
1177  static function filterObjIdsPerNews($a_obj_ids, $a_time_period = 0, $a_starting_date = "",$a_ending_date = '', $ignore_period = false)
1178  {
1179  global $ilDB;
1180 
1181  $and = "";
1182  if ($a_time_period > 0)
1183  {
1184  $limit_ts = date('Y-m-d H:i:s', time() - ($a_time_period * 24 * 60 * 60));
1185  $and = " AND creation_date >= ".$ilDB->quote($limit_ts, "timestamp")." ";
1186  }
1187 
1188  if ($a_starting_date != "")
1189  {
1190  $and.= " AND creation_date >= ".$ilDB->quote($a_starting_date, "timestamp");
1191  }
1192 
1193  $query = "SELECT DISTINCT(context_obj_id) AS obj_id FROM il_news_item".
1194  " WHERE ".$ilDB->in("context_obj_id", $a_obj_ids, false, "integer")." ".$and;
1195  //" WHERE context_obj_id IN (".implode(ilUtil::quoteArray($a_obj_ids),",").")".$and;
1196 
1197  $set = $ilDB->query($query);
1198  $objs = array();
1199  while($rec = $ilDB->fetchAssoc($set))
1200  {
1201  $objs[] = $rec["obj_id"];
1202  }
1203 
1204  return $objs;
1205  }
1206 
1210  static function determineNewsTitle($a_context_obj_type, $a_title, $a_content_is_lang_var,
1211  $a_agg_ref_id = 0, $a_aggregation = "")
1212  {
1213  global $lng;
1214 
1215  if ($a_agg_ref_id > 0)
1216  {
1217  $cnt = count($a_aggregation);
1218 
1219  // forums
1220  if ($a_context_obj_type == "frm")
1221  {
1222  if ($cnt > 1)
1223  {
1224  return sprintf($lng->txt("news_x_postings"), $cnt);
1225  }
1226  else
1227  {
1228  return $lng->txt("news_1_postings");
1229  }
1230  }
1231  else // files
1232  {
1233  $up_cnt = $cr_cnt = 0;
1234  foreach($a_aggregation as $item)
1235  {
1236  if ($item["title"] == "file_updated")
1237  {
1238  $up_cnt++;
1239  }
1240  else
1241  {
1242  $cr_cnt++;
1243  }
1244  }
1245  $sep = "";
1246  if ($cr_cnt == 1)
1247  {
1248  $tit = $lng->txt("news_1_file_created");
1249  $sep = "<br />";
1250  }
1251  else if ($cr_cnt > 1)
1252  {
1253  $tit = sprintf($lng->txt("news_x_files_created"), $cr_cnt);
1254  $sep = "<br />";
1255  }
1256  if ($up_cnt == 1)
1257  {
1258  $tit .= $sep.$lng->txt("news_1_file_updated");
1259  }
1260  else if ($up_cnt > 1)
1261  {
1262  $tit .= $sep.sprintf($lng->txt("news_x_files_updated"), $up_cnt);
1263  }
1264  return $tit;
1265  }
1266  }
1267  else
1268  {
1269  if ($a_content_is_lang_var)
1270  {
1271  return $lng->txt($a_title);
1272  }
1273  else
1274  {
1275  return $a_title;
1276  }
1277  }
1278 
1279  return "";
1280  }
1281 
1285  static function determineNewsContent($a_context_obj_type, $a_content, $a_is_lang_var)
1286  {
1287  global $lng;
1288 
1289  if ($a_is_lang_var)
1290  {
1291  $lng->loadLanguageModule($a_context_obj_type);
1292  return $lng->txt($a_content);
1293  }
1294  else
1295  {
1296  return $a_content;
1297  }
1298  }
1299 
1300 
1301 
1305  static function getFirstNewsIdForContext($a_context_obj_id,
1306  $a_context_obj_type, $a_context_sub_obj_id = "", $a_context_sub_obj_type = "")
1307  {
1308  global $ilDB;
1309 
1310  // Determine how many rows should be deleted
1311  $query = "SELECT * ".
1312  "FROM il_news_item ".
1313  "WHERE ".
1314  "context_obj_id = ".$ilDB->quote($a_context_obj_id, "integer").
1315  " AND context_obj_type = ".$ilDB->quote($a_context_obj_type, "text").
1316  " AND context_sub_obj_id = ".$ilDB->quote($a_context_sub_obj_id, "integer").
1317  " AND ".$ilDB->equals("context_sub_obj_type", $a_context_sub_obj_type, "text", true);
1318 
1319  $set = $ilDB->query($query);
1320  $rec = $ilDB->fetchAssoc($set);
1321 
1322  return $rec["id"];
1323  }
1324 
1328  static function getLastNewsIdForContext($a_context_obj_id,
1329  $a_context_obj_type, $a_context_sub_obj_id = "", $a_context_sub_obj_type = "",
1330  $a_only_today = false)
1331  {
1332  global $ilDB;
1333 
1334  // Determine how many rows should be deleted
1335  $query = "SELECT id, update_date ".
1336  "FROM il_news_item ".
1337  "WHERE ".
1338  "context_obj_id = ".$ilDB->quote($a_context_obj_id, "integer").
1339  " AND context_obj_type = ".$ilDB->quote($a_context_obj_type, "text").
1340  " AND context_sub_obj_id = ".$ilDB->quote($a_context_sub_obj_id, "integer").
1341  " AND ".$ilDB->equals("context_sub_obj_type", $a_context_sub_obj_type, "text", true).
1342  " ORDER BY update_date DESC";
1343 
1344  $ilDB->setLimit(1);
1345  $set = $ilDB->query($query);
1346  $rec = $ilDB->fetchAssoc($set);
1347 
1348  $id = (int) $rec["id"];
1349  if ($a_only_today)
1350  {
1351  $now = ilUtil::now();
1352  if (substr($now, 0, 10) != substr($rec["update_date"], 0, 10))
1353  {
1354  $id = 0;
1355  }
1356  }
1357 
1358  return $id;
1359  }
1360 
1361 
1365  static function _lookupMediaObjectUsages($a_mob_id)
1366  {
1367  global $ilDB;
1368 
1369  $query = "SELECT * ".
1370  "FROM il_news_item ".
1371  "WHERE ".
1372  " mob_id = ".$ilDB->quote($a_mob_id, "integer");
1373 
1374  $usages = array();
1375  $set = $ilDB->query($query);
1376  while ($rec = $ilDB->fetchAssoc($set))
1377  {
1378  $usages[$rec["id"]] = array("type" => "news", "id" => $rec["id"]);
1379  }
1380 
1381  return $usages;
1382  }
1383 
1387  static function _lookupContextObjId($a_news_id)
1388  {
1389  global $ilDB;
1390 
1391  $query = "SELECT * ".
1392  "FROM il_news_item ".
1393  "WHERE ".
1394  " id = ".$ilDB->quote($a_news_id, "integer");
1395  $set = $ilDB->query($query);
1396  $rec = $ilDB->fetchAssoc($set);
1397 
1398  return $rec["context_obj_id"];
1399  }
1400 
1402  {
1403  $news_set = new ilSetting("news");
1404  $per = $news_set->get("pd_period");
1405  if ($per == 0)
1406  {
1407  $per = 30;
1408  }
1409 
1410  return $per;
1411  }
1412 
1413  function _lookupUserPDPeriod($a_user_id)
1414  {
1415  global $ilSetting;
1416 
1417  $news_set = new ilSetting("news");
1418  $allow_shorter_periods = $news_set->get("allow_shorter_periods");
1419  $allow_longer_periods = $news_set->get("allow_longer_periods");
1420  $default_per = ilNewsItem::_lookupDefaultPDPeriod();
1421 
1422  include_once("./Services/Block/classes/class.ilBlockSetting.php");
1423  $per = ilBlockSetting::_lookup("pdnews", "news_pd_period",
1424  $a_user_id, 0);
1425 
1426  // news period information
1427  if ($per <= 0 ||
1428  (!$allow_shorter_periods && ($per < $default_per)) ||
1429  (!$allow_longer_periods && ($per > $default_per))
1430  )
1431  {
1432  $per = $default_per;
1433  }
1434 
1435  return $per;
1436  }
1437 
1438  function _lookupRSSPeriod()
1439  {
1440  $news_set = new ilSetting("news");
1441  $rss_period = $news_set->get("rss_period");
1442  if ($rss_period == 0) // default to two weeks
1443  {
1444  $rss_period = 14;
1445  }
1446  return $rss_period;
1447  }
1448  function setPrivateFeedId ($a_userId)
1449  {
1450  ilNewsItem::$privFeedId = $a_userId;
1451  }
1452 
1453  function getPrivateFeedId () {
1454 
1455  return ilNewsItem::$privFeedId;
1456  }
1457 
1464  function deliverMobFile($a_purpose = "Standard", $a_increase_download_cnt = false)
1465  {
1466  $mob = $this->getMobId();
1467  include_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php");
1468  $mob = new ilObjMediaObject($mob);
1469  $mob_dir = ilObjMediaObject::_getDirectory($mob->getId());
1470 
1471  // check purpose
1472  if (!$mob->hasPurposeItem($a_purpose))
1473  {
1474  return false;
1475  }
1476 
1477  $m_item = $mob->getMediaItem($a_purpose);
1478  if ($m_item->getLocationType() != "Reference")
1479  {
1480  $file = $mob_dir."/".$m_item->getLocation();
1481  if (file_exists($file) && is_file($file))
1482  {
1483  if ($a_increase_download_cnt)
1484  {
1485  $this->increaseDownloadCounter();
1486  }
1487  ilUtil::deliverFile($file, $m_item->getLocation());
1488  }
1489  else
1490  {
1491  ilUtil::sendFailure("File not found!",true);
1492  return false;
1493  }
1494  }
1495  else
1496  {
1497  if ($a_increase_download_cnt)
1498  {
1499  $this->increaseDownloadCounter();
1500  }
1501  ilUtil::redirect($m_item->getLocation());
1502  }
1503  }
1504 
1512  {
1513  global $ilDB;
1514 
1515  $cnt = $this->getMobDownloadCounter();
1516  $cnt++;
1517  $this->setMobDownloadCounter($cnt);
1518  $ilDB->manipulate("UPDATE il_news_item SET ".
1519  " mob_cnt_download = ".$ilDB->quote($cnt, "integer").
1520  " WHERE id = ".$ilDB->quote($this->getId(), "integer")
1521  );
1522  }
1523 
1531  {
1532  global $ilDB;
1533 
1534  $cnt = $this->getMobPlayCounter();
1535  $cnt++;
1536  $this->setMobPlayCounter($cnt);
1537  $ilDB->manipulate("UPDATE il_news_item SET ".
1538  " mob_cnt_play = ".$ilDB->quote($cnt, "integer").
1539  " WHERE id = ".$ilDB->quote($this->getId(), "integer")
1540  );
1541  }
1542 
1543 }
1544 ?>