1<?php 2/* Copyright (c) 1998-2012 ILIAS open source, Extended GPL, see docs/LICENSE */ 3 4define("NEWS_NOTICE", 0); 5define("NEWS_MESSAGE", 1); 6define("NEWS_WARNING", 2); 7 8define("NEWS_TEXT", "text"); 9define("NEWS_HTML", "html"); 10define("NEWS_AUDIO", "audio"); 11define("NEWS_USERS", "users"); 12define("NEWS_PUBLIC", "public"); 13 14 15 16/** 17 * @defgroup ServicesNews Services/News 18 * 19 * A news item can be created by different sources. E.g. when 20 * a new forum posting is created, or when a change in a 21 * learning module is announced. 22 * 23 * Please note that this class contains a lot of deprectated functions that 24 * will be move to other classes in the future. Please avoid to use these functions. This class should 25 * be a pure data class without persistence in the future. 26 * 27 * @author Alex Killing <alex.killing@gmx.de> 28 * @version $Id$ 29 * 30 * @ingroup ServicesNews 31 */ 32class ilNewsItem 33{ 34 /** 35 * @var ilDB 36 */ 37 protected $db; 38 39 /** 40 * @var ilTree 41 */ 42 protected $tree; 43 44 /** 45 * @var ilAccessHandler 46 */ 47 protected $access; 48 49 /** 50 * @var ilObjectDataCache 51 */ 52 protected $obj_data_cache; 53 54 /** 55 * @var ilObjUser 56 */ 57 protected $user; 58 59 /** 60 * @var ilLanguage 61 */ 62 protected $lng; 63 64 /** 65 * @var ilCtrl 66 */ 67 protected $ctrl; 68 69 protected $id; 70 protected $title; 71 protected $content; 72 /** 73 * @var bool 74 */ 75 protected $content_html; 76 protected $context_obj_id; 77 protected $context_obj_type; 78 protected $context_sub_obj_id; 79 protected $context_sub_obj_type; 80 protected $content_type = "text"; 81 protected $creation_date; 82 protected $update_date; 83 protected $user_id; 84 /** 85 * @var int 86 */ 87 protected $update_user_id; 88 protected $visibility = "users"; 89 protected $content_long; 90 protected $priority = 1; 91 protected $content_is_lang_var = 0; 92 protected $mob_id; 93 protected $playtime; 94 95 private static $privFeedId = false; 96 private $limitation; 97 98 /** 99 * Constructor. 100 * 101 * @param int $a_id 102 */ 103 public function __construct($a_id = 0) 104 { 105 global $DIC; 106 107 $this->db = $DIC->database(); 108 $this->tree = $DIC->repositoryTree(); 109 $this->access = $DIC->access(); 110 $this->obj_data_cache = $DIC["ilObjDataCache"]; 111 $this->user = $DIC->user(); 112 $this->lng = $DIC->language(); 113 $this->ctrl = $DIC->ctrl(); 114 if ($a_id > 0) { 115 $this->setId($a_id); 116 $this->read(); 117 } 118 $this->limitation = true; 119 } 120 121 /** 122 * Set Id. 123 * 124 * @param int $a_id 125 */ 126 public function setId($a_id) 127 { 128 $this->id = $a_id; 129 } 130 131 /** 132 * Get Id. 133 * 134 * @return int 135 */ 136 public function getId() 137 { 138 return $this->id; 139 } 140 141 /** 142 * Set Title. 143 * 144 * @param string $a_title Title of news item. 145 */ 146 public function setTitle($a_title) 147 { 148 $this->title = $a_title; 149 } 150 151 /** 152 * Get Title. 153 * 154 * @return string Title of news item. 155 */ 156 public function getTitle() 157 { 158 return $this->title; 159 } 160 161 /** 162 * Set Content. 163 * 164 * @param string $a_content Content of news. 165 */ 166 public function setContent($a_content) 167 { 168 $this->content = $a_content; 169 } 170 171 /** 172 * Get Content. 173 * 174 * @return string Content of news. 175 */ 176 public function getContent() 177 { 178 return $this->content; 179 } 180 181 /** 182 * Set ContextObjId. 183 * 184 * @param int $a_context_obj_id 185 */ 186 public function setContextObjId($a_context_obj_id) 187 { 188 $this->context_obj_id = $a_context_obj_id; 189 } 190 191 /** 192 * Get ContextObjId. 193 * 194 * @return int 195 */ 196 public function getContextObjId() 197 { 198 return $this->context_obj_id; 199 } 200 201 /** 202 * Set ContextObjType. 203 * 204 * @param int $a_context_obj_type 205 */ 206 public function setContextObjType($a_context_obj_type) 207 { 208 $this->context_obj_type = $a_context_obj_type; 209 } 210 211 /** 212 * Get ContextObjType. 213 * 214 * @return int 215 */ 216 public function getContextObjType() 217 { 218 return $this->context_obj_type; 219 } 220 221 /** 222 * Set ContextSubObjId. 223 * 224 * @param int $a_context_sub_obj_id 225 */ 226 public function setContextSubObjId($a_context_sub_obj_id) 227 { 228 $this->context_sub_obj_id = $a_context_sub_obj_id; 229 } 230 231 /** 232 * Get ContextSubObjId. 233 * 234 * @return int 235 */ 236 public function getContextSubObjId() 237 { 238 return $this->context_sub_obj_id; 239 } 240 241 /** 242 * Set ContextSubObjType. 243 * 244 * @param int $a_context_sub_obj_type 245 */ 246 public function setContextSubObjType($a_context_sub_obj_type) 247 { 248 $this->context_sub_obj_type = $a_context_sub_obj_type; 249 } 250 251 /** 252 * Get ContextSubObjType. 253 * 254 * @return int 255 */ 256 public function getContextSubObjType() 257 { 258 return $this->context_sub_obj_type; 259 } 260 261 /** 262 * Set ContentType. 263 * 264 * @param string $a_content_type Content type. 265 */ 266 public function setContentType($a_content_type = "text") 267 { 268 $this->content_type = $a_content_type; 269 } 270 271 /** 272 * Get ContentType. 273 * 274 * @return string Content type. 275 */ 276 public function getContentType() 277 { 278 return $this->content_type; 279 } 280 281 /** 282 * Set CreationDate. 283 * 284 * @param string $a_creation_date Date of creation. 285 */ 286 public function setCreationDate($a_creation_date) 287 { 288 $this->creation_date = $a_creation_date; 289 } 290 291 /** 292 * Get CreationDate. 293 * 294 * @return string Date of creation. 295 */ 296 public function getCreationDate() 297 { 298 return $this->creation_date; 299 } 300 301 /** 302 * Set UpdateDate. 303 * 304 * @param string $a_update_date Date of last update. 305 */ 306 public function setUpdateDate($a_update_date) 307 { 308 $this->update_date = $a_update_date; 309 } 310 311 /** 312 * Get UpdateDate. 313 * 314 * @return string Date of last update. 315 */ 316 public function getUpdateDate() 317 { 318 return $this->update_date; 319 } 320 321 /** 322 * Set UserId. 323 * 324 * @param int $a_user_id User Id of last update. 325 */ 326 public function setUserId($a_user_id) 327 { 328 $this->user_id = $a_user_id; 329 } 330 331 /** 332 * Get UserId. 333 * 334 * @return int User Id of last update. 335 */ 336 public function getUserId() 337 { 338 return $this->user_id; 339 } 340 341 /** 342 * Set update user id 343 * 344 * @param int $a_val update user id 345 */ 346 public function setUpdateUserId($a_val) 347 { 348 $this->update_user_id = $a_val; 349 } 350 351 /** 352 * Get update user id 353 * 354 * @return int update user id 355 */ 356 public function getUpdateUserId() 357 { 358 return $this->update_user_id; 359 } 360 361 /** 362 * Set Visibility. 363 * 364 * @param string $a_visibility Access level of news. 365 */ 366 public function setVisibility($a_visibility = "users") 367 { 368 $this->visibility = $a_visibility; 369 } 370 371 /** 372 * Get Visibility. 373 * 374 * @return string Access level of news. 375 */ 376 public function getVisibility() 377 { 378 return $this->visibility; 379 } 380 381 /** 382 * Set ContentLong. 383 * 384 * @param string $a_content_long Long content of news 385 */ 386 public function setContentLong($a_content_long) 387 { 388 $this->content_long = $a_content_long; 389 } 390 391 /** 392 * Get ContentLong. 393 * 394 * @return string Long content of news 395 */ 396 public function getContentLong() 397 { 398 return $this->content_long; 399 } 400 401 /** 402 * Set Priority. 403 * 404 * @param int $a_priority News Priority 405 */ 406 public function setPriority($a_priority = 1) 407 { 408 $this->priority = $a_priority; 409 } 410 411 /** 412 * Get Priority. 413 * 414 * @return int News Priority 415 */ 416 public function getPriority() 417 { 418 return $this->priority; 419 } 420 421 /** 422 * Set ContentIsLangVar. 423 * 424 * @param boolean $a_content_is_lang_var 425 */ 426 public function setContentIsLangVar($a_content_is_lang_var = 0) 427 { 428 $this->content_is_lang_var = $a_content_is_lang_var; 429 } 430 431 /** 432 * Get ContentIsLangVar. 433 * 434 * @return boolean 435 */ 436 public function getContentIsLangVar() 437 { 438 return $this->content_is_lang_var; 439 } 440 441 /** 442 * Set MobId. 443 * 444 * @param int $a_mob_id Media Object ID (if news includes attachement) 445 */ 446 public function setMobId($a_mob_id) 447 { 448 $this->mob_id = $a_mob_id; 449 } 450 451 /** 452 * Get MobId. 453 * 454 * @return int Media Object ID (if news includes attachement) 455 */ 456 public function getMobId() 457 { 458 return $this->mob_id; 459 } 460 461 /** 462 * Set Playtime. 463 * 464 * @param string $a_playtime Play Time, hh:mm:ss (of attached media file) 465 */ 466 public function setPlaytime($a_playtime) 467 { 468 $this->playtime = $a_playtime; 469 } 470 471 /** 472 * Get Playtime. 473 * 474 * @return string Play Time, hh:mm:ss (of attached media file) 475 */ 476 public function getPlaytime() 477 { 478 return $this->playtime; 479 } 480 481 482 /** 483 * Set Limitation for number of items. 484 * 485 * @param boolean $a_limitation Limitation for number of items 486 */ 487 public function setLimitation($a_limitation) 488 { 489 $this->limitation = $a_limitation; 490 } 491 492 /** 493 * Get Limitation for number of items. 494 * 495 * @return boolean Limitation for number of items 496 */ 497 public function getLimitation() 498 { 499 return $this->limitation; 500 } 501 502 /** 503 * Set content text ist lang var 504 * 505 * @param boolean $a_content_is_lang_var 506 */ 507 public function setContentTextIsLangVar($a_val = 0) 508 { 509 $this->content_text_is_lang_var = $a_val; 510 } 511 512 /** 513 * Get content text ist lang var 514 * 515 * @return boolean 516 */ 517 public function getContentTextIsLangVar() 518 { 519 return $this->content_text_is_lang_var; 520 } 521 522 /** 523 * Set mob play counter 524 * 525 * @param int $a_val counter 526 */ 527 public function setMobPlayCounter($a_val) 528 { 529 $this->mob_cnt_play = $a_val; 530 } 531 532 /** 533 * Get mob play counter 534 * 535 * @return int counter 536 */ 537 public function getMobPlayCounter() 538 { 539 return $this->mob_cnt_play; 540 } 541 542 /** 543 * Set mob download counter 544 * 545 * @param int $a_val counter 546 */ 547 public function setMobDownloadCounter($a_val) 548 { 549 $this->mob_cnt_download = $a_val; 550 } 551 552 /** 553 * Get mob download counter 554 * 555 * @return int counter 556 */ 557 public function getMobDownloadCounter() 558 { 559 return $this->mob_cnt_download; 560 } 561 562 /** 563 * Is content HTML (tiny used?) 564 * 565 * @param bool $a_val 566 */ 567 public function setContentHtml($a_val) 568 { 569 $this->content_html = $a_val; 570 } 571 572 /** 573 * Get content as html 574 * 575 * @return bool 576 */ 577 public function getContentHtml() 578 { 579 return $this->content_html; 580 } 581 582 /** 583 * Read item from database. 584 * @deprecated (will migrate to ilNewsData or other class taking care of persistence) 585 */ 586 public function read() 587 { 588 $ilDB = $this->db; 589 590 $query = "SELECT * FROM il_news_item WHERE id = " . 591 $ilDB->quote($this->getId(), "integer"); 592 $set = $ilDB->query($query); 593 $rec = $ilDB->fetchAssoc($set); 594 595 $this->setTitle($rec["title"]); 596 $this->setContent($rec["content"]); 597 $this->setContextObjId((int) $rec["context_obj_id"]); 598 $this->setContextObjType($rec["context_obj_type"]); 599 $this->setContextSubObjId((int) $rec["context_sub_obj_id"]); 600 $this->setContextSubObjType($rec["context_sub_obj_type"]); 601 $this->setContentType($rec["content_type"]); 602 $this->setCreationDate($rec["creation_date"]); 603 $this->setUpdateDate($rec["update_date"]); 604 $this->setUserId($rec["user_id"]); 605 $this->setUpdateUserId($rec["update_user_id"]); 606 $this->setVisibility($rec["visibility"]); 607 $this->setContentLong($rec["content_long"]); 608 $this->setPriority($rec["priority"]); 609 $this->setContentIsLangVar($rec["content_is_lang_var"]); 610 $this->setContentTextIsLangVar((int) $rec["content_text_is_lang_var"]); 611 $this->setMobId($rec["mob_id"]); 612 $this->setPlaytime($rec["playtime"]); 613 $this->setMobPlayCounter($rec["mob_cnt_play"]); 614 $this->setMobDownloadCounter($rec["mob_cnt_download"]); 615 $this->setContentHtml($rec["content_html"]); 616 } 617 618 /** 619 * Create 620 * @deprecated (will migrate to ilNewsData or other class taking care of persistence) 621 */ 622 public function create() 623 { 624 $ilDB = $this->db; 625 626 // insert new record into db 627 $this->setId($ilDB->nextId("il_news_item")); 628 $ilDB->insert("il_news_item", array( 629 "id" => array("integer", $this->getId()), 630 "title" => array("text", $this->getTitle()), 631 "content" => array("clob", $this->getContent()), 632 "content_html" => array("integer", (int) $this->getContentHtml()), 633 "context_obj_id" => array("integer", (int) $this->getContextObjId()), 634 "context_obj_type" => array("text", $this->getContextObjType()), 635 "context_sub_obj_id" => array("integer", (int) $this->getContextSubObjId()), 636 "context_sub_obj_type" => array("text", $this->getContextSubObjType()), 637 "content_type" => array("text", $this->getContentType()), 638 "creation_date" => array("timestamp", ilUtil::now()), 639 "update_date" => array("timestamp", ilUtil::now()), 640 "user_id" => array("integer", $this->getUserId()), 641 "update_user_id" => array("integer", (int) $this->getUpdateUserId()), 642 "visibility" => array("text", $this->getVisibility()), 643 "content_long" => array("clob", $this->getContentLong()), 644 "priority" => array("integer", $this->getPriority()), 645 "content_is_lang_var" => array("integer", $this->getContentIsLangVar()), 646 "content_text_is_lang_var" => array("integer", (int) $this->getContentTextIsLangVar()), 647 "mob_id" => array("integer", $this->getMobId()), 648 "playtime" => array("text", $this->getPlaytime()) 649 )); 650 651 652 $news_set = new ilSetting("news"); 653 $max_items = $news_set->get("max_items"); 654 if ($max_items <= 0) { 655 $max_items = 50; 656 } 657 658 // limit number of news 659 if ($this->getLimitation()) { 660 // Determine how many rows should be deleted 661 $query = "SELECT count(*) cnt " . 662 "FROM il_news_item " . 663 "WHERE " . 664 "context_obj_id = " . $ilDB->quote($this->getContextObjId(), "integer") . 665 " AND context_obj_type = " . $ilDB->quote($this->getContextObjType(), "text") . 666 " AND context_sub_obj_id = " . $ilDB->quote($this->getContextSubObjId(), "integer") . 667 " AND " . $ilDB->equals("context_sub_obj_type", $this->getContextSubObjType(), "text", true) . " "; 668 669 $set = $ilDB->query($query); 670 $rec = $ilDB->fetchAssoc($set); 671 672 // if we have more records than allowed, delete them 673 if (($rec["cnt"] > $max_items) && $this->getContextObjId() > 0) { 674 $query = "SELECT * " . 675 "FROM il_news_item " . 676 "WHERE " . 677 "context_obj_id = " . $ilDB->quote($this->getContextObjId(), "integer") . 678 " AND context_obj_type = " . $ilDB->quote($this->getContextObjType(), "text") . 679 " AND context_sub_obj_id = " . $ilDB->quote($this->getContextSubObjId(), "integer") . 680 " AND " . $ilDB->equals("context_sub_obj_type", $this->getContextSubObjType(), "text", true) . 681 " ORDER BY creation_date ASC"; 682 683 $ilDB->setLimit($rec["cnt"] - $max_items); 684 $del_set = $ilDB->query($query); 685 while ($del_item = $ilDB->fetchAssoc($del_set)) { 686 $del_news = new ilNewsItem($del_item["id"]); 687 $del_news->delete(); 688 } 689 } 690 } 691 } 692 693 /** 694 * Update item in database 695 * 696 * @deprecated (will migrate to ilNewsData or other class taking care of persistence) 697 * @param boolean $a_as_new If true, creation date is set "now" 698 */ 699 public function update($a_as_new = false) 700 { 701 $ilDB = $this->db; 702 703 $fields = array( 704 "title" => array("text", $this->getTitle()), 705 "content" => array("clob", $this->getContent()), 706 "content_html" => array("integer", (int) $this->getContentHtml()), 707 "context_obj_id" => array("integer", $this->getContextObjId()), 708 "context_obj_type" => array("text", $this->getContextObjType()), 709 "context_sub_obj_id" => array("integer", $this->getContextSubObjId()), 710 "context_sub_obj_type" => array("text", $this->getContextSubObjType()), 711 "content_type" => array("text", $this->getContentType()), 712 "user_id" => array("integer", $this->getUserId()), 713 "update_user_id" => array("integer", (int) $this->getUpdateUserId()), 714 "visibility" => array("text", $this->getVisibility()), 715 "content_long" => array("clob", $this->getContentLong()), 716 "priority" => array("integer", $this->getPriority()), 717 "content_is_lang_var" => array("integer", $this->getContentIsLangVar()), 718 "content_text_is_lang_var" => array("integer", (int) $this->getContentTextIsLangVar()), 719 "mob_id" => array("integer", $this->getMobId()), 720 "mob_cnt_play" => array("integer", $this->getMobPlayCounter()), 721 "mob_cnt_download" => array("integer", $this->getMobDownloadCounter()), 722 "playtime" => array("text", $this->getPlaytime()) 723 ); 724 725 $now = ilUtil::now(); 726 if ($a_as_new) { 727 $fields["creation_date"] = array("timestamp", $now); 728 $fields["update_date"] = array("timestamp", $now); 729 } else { 730 $fields["update_date"] = array("timestamp", $now); 731 } 732 733 $ilDB->update("il_news_item", $fields, array( 734 "id" => array("integer", $this->getId()) 735 )); 736 } 737 738 739 /** 740 * Get all news items for a user. 741 * @deprecated (will migrate to ilNewsData) 742 */ 743 public static function _getNewsItemsOfUser( 744 $a_user_id, 745 $a_only_public = false, 746 $a_prevent_aggregation = false, 747 $a_per = 0, 748 &$a_cnt = null 749 ) { 750 global $DIC; 751 752 $ilAccess = $DIC->access(); 753 754 $fav_rep = new ilFavouritesDBRepository(); 755 756 $news_item = new ilNewsItem(); 757 $news_set = new ilSetting("news"); 758 759 $per = $a_per; 760 761 include_once("./Services/News/classes/class.ilNewsSubscription.php"); 762 include_once("./Services/Block/classes/class.ilBlockSetting.php"); 763 764 // this is currently not used 765 $ref_ids = ilNewsSubscription::_getSubscriptionsOfUser($a_user_id); 766 767 if (ilObjUser::_lookupPref($a_user_id, "pd_items_news") != "n") { 768 // get all items of the personal desktop 769 $pd_items = $fav_rep->getFavouritesOfUser($a_user_id); 770 foreach ($pd_items as $item) { 771 if (!in_array($item["ref_id"], $ref_ids)) { 772 $ref_ids[] = $item["ref_id"]; 773 } 774 } 775 776 // get all memberships 777 include_once 'Services/Membership/classes/class.ilParticipants.php'; 778 $crs_mbs = ilParticipants::_getMembershipByType($a_user_id, 'crs'); 779 $grp_mbs = ilParticipants::_getMembershipByType($a_user_id, 'grp'); 780 $items = array_merge($crs_mbs, $grp_mbs); 781 foreach ($items as $i) { 782 $item_references = ilObject::_getAllReferences($i); 783 if (is_array($item_references) && count($item_references)) { 784 foreach ($item_references as $ref_id) { 785 if (!in_array($ref_id, $ref_ids)) { 786 $ref_ids[] = $ref_id; 787 } 788 } 789 } 790 } 791 } 792 793 $data = array(); 794 795 foreach ($ref_ids as $ref_id) { 796 if (!$a_only_public) { 797 // this loop should not cost too much performance 798 $acc = $ilAccess->checkAccessOfUser($a_user_id, "read", "", $ref_id); 799 800 if (!$acc) { 801 continue; 802 } 803 } 804 if (ilNewsItem::getPrivateFeedId() != false) { 805 global $DIC; 806 807 $rbacsystem = $DIC->rbac()->system(); 808 $acc = $rbacsystem->checkAccessOfUser(ilNewsItem::getPrivateFeedId(), "read", $ref_id); 809 810 if (!$acc) { 811 continue; 812 } 813 } 814 815 $obj_id = ilObject::_lookupObjId($ref_id); 816 $obj_type = ilObject::_lookupType($obj_id); 817 $news = $news_item->getNewsForRefId( 818 $ref_id, 819 $a_only_public, 820 false, 821 $per, 822 $a_prevent_aggregation, 823 false, 824 false, 825 false, 826 $a_user_id 827 ); 828 829 // counter 830 if (!is_null($a_cnt)) { 831 $a_cnt[$ref_id] = count($news); 832 } 833 834 $data = ilNewsItem::mergeNews($data, $news); 835 } 836 837 $data = ilUtil::sortArray($data, "creation_date", "desc", false, true); 838 839 return $data; 840 } 841 842 /** 843 * Get News For Ref Id. 844 * 845 * @deprecated (will migrate to ilNewsData) 846 * 847 * @param int $a_ref_id 848 * @param bool $a_only_public 849 * @param bool $a_stopnesting 850 * @param int $a_time_period 851 * @param bool $a_prevent_aggregation 852 * @param bool $a_forum_group_sequences 853 * @param bool $a_no_auto_generated 854 * @param bool $a_ignore_date_filter 855 * @param null $a_user_id 856 * @param int $a_limit currently only supported for groups and courses 857 * @param int[] $a_excluded currently only supported for groups and courses (news ids) 858 * @return array|mixed 859 */ 860 public function getNewsForRefId( 861 $a_ref_id, 862 $a_only_public = false, 863 $a_stopnesting = false, 864 $a_time_period = 0, 865 $a_prevent_aggregation = true, 866 $a_forum_group_sequences = false, 867 $a_no_auto_generated = false, 868 $a_ignore_date_filter = false, 869 $a_user_id = null, 870 $a_limit = 0, 871 $a_excluded = array() 872 ) { 873 $obj_id = ilObject::_lookupObjId($a_ref_id); 874 $obj_type = ilObject::_lookupType($obj_id); 875 876 // get starting date 877 $starting_date = ""; 878 if ($obj_type == "grp" || $obj_type == "crs") { 879 // see #31471, #30687, and ilMembershipNotification 880 if (!ilContainer::_lookupContainerSetting( 881 $obj_id, 882 'cont_use_news', 883 true 884 ) || ( 885 !ilContainer::_lookupContainerSetting( 886 $obj_id, 887 'cont_show_news', 888 true 889 ) && !ilContainer::_lookupContainerSetting( 890 $obj_id, 891 'news_timeline' 892 ) 893 )) { 894 return []; 895 } 896 897 include_once("./Services/Block/classes/class.ilBlockSetting.php"); 898 $hide_news_per_date = ilBlockSetting::_lookup( 899 "news", 900 "hide_news_per_date", 901 0, 902 $obj_id 903 ); 904 if ($hide_news_per_date && !$a_ignore_date_filter) { 905 $starting_date = ilBlockSetting::_lookup( 906 "news", 907 "hide_news_date", 908 0, 909 $obj_id 910 ); 911 } 912 } 913 914 if ($obj_type == "cat" && !$a_stopnesting) { 915 $news = $this->getAggregatedChildNewsData( 916 $a_ref_id, 917 $a_only_public, 918 $a_time_period, 919 $a_prevent_aggregation, 920 $starting_date, 921 $a_no_auto_generated 922 ); 923 } elseif (($obj_type == "grp" || $obj_type == "crs") && 924 !$a_stopnesting) { 925 $news = $this->getAggregatedNewsData( 926 $a_ref_id, 927 $a_only_public, 928 $a_time_period, 929 $a_prevent_aggregation, 930 $starting_date, 931 $a_no_auto_generated, 932 $a_user_id, 933 $a_limit, 934 $a_excluded 935 ); 936 } else { 937 $news_item = new ilNewsItem(); 938 $news_item->setContextObjId($obj_id); 939 $news_item->setContextObjType($obj_type); 940 $news = $news_item->queryNewsForContext( 941 $a_only_public, 942 $a_time_period, 943 $starting_date, 944 $a_no_auto_generated 945 ); 946 $unset = array(); 947 foreach ($news as $k => $v) { 948 if (!$a_only_public || $v["visibility"] == NEWS_PUBLIC || 949 ($v["priority"] == 0 && 950 ilBlockSetting::_lookup( 951 "news", 952 "public_notifications", 953 0, 954 $obj_id 955 ))) { 956 $news[$k]["ref_id"] = $a_ref_id; 957 } else { 958 $unset[] = $k; 959 } 960 } 961 foreach ($unset as $un) { 962 unset($news[$un]); 963 } 964 } 965 966 if (!$a_prevent_aggregation) { 967 $news = $this->aggregateForums($news); 968 } elseif ($a_forum_group_sequences) { 969 $news = $this->aggregateForums($news, true); 970 } 971 972 return $news; 973 } 974 975 /** 976 * Get news aggregation (e.g. for courses, groups) 977 * @deprecated (will migrate to ilNewsData) 978 */ 979 public function getAggregatedNewsData( 980 $a_ref_id, 981 $a_only_public = false, 982 $a_time_period = 0, 983 $a_prevent_aggregation = false, 984 $a_starting_date = "", 985 $a_no_auto_generated = false, 986 $a_user_id = null, 987 $a_limit = 0, 988 $a_exclude = array() 989 ) { 990 $tree = $this->tree; 991 $ilAccess = $this->access; 992 $ilObjDataCache = $this->obj_data_cache; 993 994 // get news of parent object 995 996 $data = array(); 997 998 // get subtree 999 $cur_node = $tree->getNodeData($a_ref_id); 1000 1001 // do not check for lft (materialized path) 1002 if ($cur_node) { 1003 $nodes = (array) $tree->getSubTree($cur_node, true); 1004 } else { 1005 $nodes = array(); 1006 } 1007 1008 // preload object data cache 1009 $ref_ids = array(); 1010 $obj_ids = array(); 1011 foreach ($nodes as $node) { 1012 $ref_ids[] = $node["child"]; 1013 $obj_ids[] = $node["obj_id"]; 1014 } 1015 1016 $ilObjDataCache->preloadReferenceCache($ref_ids); 1017 if (!$a_only_public) { 1018 include_once "Services/Object/classes/class.ilObjectActivation.php"; 1019 ilObjectActivation::preloadData($ref_ids); 1020 } 1021 1022 // no check, for which of the objects any news are available 1023 $news_obj_ids = ilNewsItem::filterObjIdsPerNews($obj_ids, $a_time_period, $a_starting_date); 1024 //$news_obj_ids = $obj_ids; 1025 1026 // get news for all subtree nodes 1027 $contexts = array(); 1028 foreach ($nodes as $node) { 1029 // only go on, if news are available 1030 if (!in_array($node["obj_id"], $news_obj_ids)) { 1031 continue; 1032 } 1033 1034 if (!$a_only_public) { 1035 if (!$a_user_id) { 1036 $acc = $ilAccess->checkAccess("read", "", $node["child"]); 1037 } else { 1038 $acc = $ilAccess->checkAccessOfUser( 1039 $a_user_id, 1040 "read", 1041 "", 1042 $node["child"] 1043 ); 1044 } 1045 if (!$acc) { 1046 continue; 1047 } 1048 } 1049 1050 $ref_id[$node["obj_id"]] = $node["child"]; 1051 $contexts[] = array("obj_id" => $node["obj_id"], 1052 "obj_type" => $node["type"]); 1053 } 1054 1055 // sort and return 1056 $news = $this->queryNewsForMultipleContexts( 1057 $contexts, 1058 $a_only_public, 1059 $a_time_period, 1060 $a_starting_date, 1061 $a_no_auto_generated, 1062 $a_user_id, 1063 $a_limit, 1064 $a_exclude 1065 ); 1066 1067 $to_del = array(); 1068 foreach ($news as $k => $v) { 1069 $news[$k]["ref_id"] = $ref_id[$v["context_obj_id"]]; 1070 } 1071 1072 $data = ilNewsItem::mergeNews($data, $news); 1073 $data = ilUtil::sortArray($data, "creation_date", "desc", false, true); 1074 1075 if (!$a_prevent_aggregation) { 1076 $data = $this->aggregateFiles($data, $a_ref_id); 1077 } 1078 1079 return $data; 1080 } 1081 1082 /** 1083 * @deprecated will move to ilNewsData 1084 * @param $news 1085 * @param bool $a_group_posting_sequence 1086 * @return mixed 1087 */ 1088 protected function aggregateForums($news, $a_group_posting_sequence = false) 1089 { 1090 $to_del = array(); 1091 $forums = array(); 1092 1093 // aggregate 1094 foreach ($news as $k => $v) { 1095 if ($a_group_posting_sequence && $last_aggregation_forum > 0 && 1096 $last_aggregation_forum != $news[$k]["context_obj_id"]) { 1097 $forums[$last_aggregation_forum] = ""; 1098 } 1099 1100 if ($news[$k]["context_obj_type"] == "frm") { 1101 if ($forums[$news[$k]["context_obj_id"]] == "") { 1102 // $forums[forum_id] = news_id; 1103 $forums[$news[$k]["context_obj_id"]] = $k; 1104 $last_aggregation_forum = $news[$k]["context_obj_id"]; 1105 } else { 1106 $to_del[] = $k; 1107 } 1108 1109 $news[$k]["no_context_title"] = true; 1110 1111 // aggregate every forum into it's "k" news 1112 $news[$forums[$news[$k]["context_obj_id"]]]["aggregation"][$k] 1113 = $news[$k]; 1114 $news[$k]["agg_ref_id"] 1115 = $news[$k]["ref_id"]; 1116 $news[$k]["content"] = ""; 1117 $news[$k]["content_long"] = ""; 1118 } 1119 } 1120 1121 // delete double entries 1122 foreach ($to_del as $k) { 1123 unset($news[$k]); 1124 } 1125 //var_dump($news[14]["aggregation"]); 1126 1127 1128 return $news; 1129 } 1130 1131 /** 1132 * @deprecated will move to ilNewsData 1133 * @param $news 1134 * @param $a_ref_id 1135 * @return mixed 1136 */ 1137 protected function aggregateFiles($news, $a_ref_id) 1138 { 1139 $first_file = ""; 1140 $to_del = array(); 1141 foreach ($news as $k => $v) { 1142 // aggregate file related news 1143 if ($news[$k]["context_obj_type"] == "file") { 1144 if ($first_file == "") { 1145 $first_file = $k; 1146 } else { 1147 $to_del[] = $k; 1148 } 1149 $news[$first_file]["aggregation"][$k] = $news[$k]; 1150 $news[$first_file]["agg_ref_id"] = $a_ref_id; 1151 $news[$first_file]["ref_id"] = $a_ref_id; 1152 } 1153 } 1154 1155 foreach ($to_del as $v) { 1156 unset($news[$v]); 1157 } 1158 1159 return $news; 1160 } 1161 1162 1163 /** 1164 * Get news aggregation for child objects (e.g. for categories) 1165 * @deprecated will move to ilNewsData 1166 * @param $a_ref_id 1167 * @param bool $a_only_public 1168 * @param int $a_time_period 1169 * @param bool $a_prevent_aggregation 1170 * @param string $a_starting_date 1171 * @param bool $a_no_auto_generated 1172 * @return array|mixed 1173 */ 1174 protected function getAggregatedChildNewsData( 1175 $a_ref_id, 1176 $a_only_public = false, 1177 $a_time_period = 0, 1178 $a_prevent_aggregation = false, 1179 $a_starting_date = "", 1180 $a_no_auto_generated = false 1181 ) { 1182 $tree = $this->tree; 1183 $ilAccess = $this->access; 1184 1185 // get news of parent object 1186 $data = $this->getNewsForRefId( 1187 $a_ref_id, 1188 $a_only_public, 1189 true, 1190 $a_time_period, 1191 true, 1192 false, 1193 false, 1194 $a_no_auto_generated 1195 ); 1196 foreach ($data as $k => $v) { 1197 $data[$k]["ref_id"] = $a_ref_id; 1198 } 1199 1200 // get childs 1201 $nodes = $tree->getChilds($a_ref_id); 1202 1203 // no check, for which of the objects any news are available 1204 $obj_ids = array(); 1205 foreach ($nodes as $node) { 1206 $obj_ids[] = $node["obj_id"]; 1207 } 1208 $news_obj_ids = ilNewsItem::filterObjIdsPerNews($obj_ids, $a_time_period, $a_starting_date); 1209 //$news_obj_ids = $obj_ids; 1210 1211 // get news for all subtree nodes 1212 $contexts = array(); 1213 foreach ($nodes as $node) { 1214 // only go on, if news are available 1215 if (!in_array($node["obj_id"], $news_obj_ids)) { 1216 continue; 1217 } 1218 1219 if (!$a_only_public && !$ilAccess->checkAccess("read", "", $node["child"])) { 1220 continue; 1221 } 1222 $ref_id[$node["obj_id"]] = $node["child"]; 1223 $contexts[] = array("obj_id" => $node["obj_id"], 1224 "obj_type" => $node["type"]); 1225 } 1226 1227 $news = $this->queryNewsForMultipleContexts( 1228 $contexts, 1229 $a_only_public, 1230 $a_time_period, 1231 $a_starting_date, 1232 $a_no_auto_generated 1233 ); 1234 foreach ($news as $k => $v) { 1235 $news[$k]["ref_id"] = $ref_id[$v["context_obj_id"]]; 1236 } 1237 $data = ilNewsItem::mergeNews($data, $news); 1238 1239 // sort and return 1240 $data = ilUtil::sortArray($data, "creation_date", "desc", false, true); 1241 1242 if (!$a_prevent_aggregation) { 1243 $data = $this->aggregateFiles($data, $a_ref_id); 1244 } 1245 1246 return $data; 1247 } 1248 1249 /** 1250 * Set context for news 1251 * 1252 * @param int $a_obj_id 1253 * @param int $a_obj_type 1254 * @param int $a_sub_obj_id 1255 * @param string $a_sub_obj_type 1256 */ 1257 public function setContext(int $a_obj_id, string $a_obj_type, int $a_sub_obj_id = 0, string $a_sub_obj_type = "") 1258 { 1259 $this->setContextObjId($a_obj_id); 1260 $this->setContextObjType($a_obj_type); 1261 $this->setContextSubObjId($a_sub_obj_id); 1262 $this->setContextSubObjType($a_sub_obj_type); 1263 } 1264 1265 /** 1266 * Convert time period for DB-queries 1267 * 1268 * @param mixed $a_time_period 1269 * @return string 1270 */ 1271 protected static function handleTimePeriod($a_time_period) 1272 { 1273 // time period is number of days 1274 if (is_numeric($a_time_period)) { 1275 if ($a_time_period > 0) { 1276 return date('Y-m-d H:i:s', time() - ($a_time_period * 24 * 60 * 60)); 1277 } 1278 } 1279 // time period is datetime 1280 elseif (preg_match("/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/", $a_time_period)) { 1281 return $a_time_period; 1282 } 1283 // :TODO: what to return? 1284 } 1285 1286 /** 1287 * Query news for a context 1288 * 1289 * @deprecated will move to ilNewsData 1290 * @param boolean query for outgoing rss feed 1291 * @param int time period in seconds 1292 * @param string startind date 1293 * @param boolean do not include auto generated news items 1294 */ 1295 public function queryNewsForContext( 1296 $a_for_rss_use = false, 1297 $a_time_period = 0, 1298 $a_starting_date = "", 1299 $a_no_auto_generated = false, 1300 $a_oldest_first = false, 1301 $a_limit = 0 1302 ) { 1303 $ilDB = $this->db; 1304 $ilUser = $this->user; 1305 $lng = $this->lng; 1306 1307 $and = ""; 1308 if ($a_time_period > 0) { 1309 $limit_ts = self::handleTimePeriod($a_time_period); 1310 $and = " AND creation_date >= " . $ilDB->quote($limit_ts, "timestamp") . " "; 1311 } 1312 1313 if ($a_starting_date != "") { 1314 $and .= " AND creation_date > " . $ilDB->quote($a_starting_date, "timestamp") . " "; 1315 } 1316 1317 if ($a_no_auto_generated) { 1318 $and .= " AND priority = 1 AND content_type = " . $ilDB->quote("text", "text") . " "; 1319 } 1320 1321 // this is changed with 4.1 (news table for lm pages) 1322 if ($this->getContextSubObjId() > 0) { 1323 $and .= " AND context_sub_obj_id = " . $ilDB->quote($this->getContextSubObjId(), "integer") . 1324 " AND context_sub_obj_type = " . $ilDB->quote($this->getContextSubObjType(), "text"); 1325 } 1326 1327 $ordering = ($a_oldest_first) 1328 ? " creation_date ASC, id ASC " 1329 : " creation_date DESC, id DESC "; 1330 1331 if ($a_for_rss_use && ilNewsItem::getPrivateFeedId() == false) { 1332 $query = "SELECT * " . 1333 "FROM il_news_item " . 1334 " WHERE " . 1335 "context_obj_id = " . $ilDB->quote($this->getContextObjId(), "integer") . 1336 " AND context_obj_type = " . $ilDB->quote($this->getContextObjType(), "text") . 1337 $and . 1338 " ORDER BY " . $ordering; 1339 } elseif (ilNewsItem::getPrivateFeedId() != false) { 1340 $query = "SELECT il_news_item.* " . 1341 ", il_news_read.user_id user_read " . 1342 "FROM il_news_item LEFT JOIN il_news_read " . 1343 "ON il_news_item.id = il_news_read.news_id AND " . 1344 " il_news_read.user_id = " . $ilDB->quote(ilNewsItem::getPrivateFeedId(), "integer") . 1345 " WHERE " . 1346 "context_obj_id = " . $ilDB->quote($this->getContextObjId(), "integer") . 1347 " AND context_obj_type = " . $ilDB->quote($this->getContextObjType(), "text") . 1348 $and . 1349 " ORDER BY " . $ordering; 1350 } else { 1351 $query = "SELECT il_news_item.* " . 1352 ", il_news_read.user_id as user_read " . 1353 "FROM il_news_item LEFT JOIN il_news_read " . 1354 "ON il_news_item.id = il_news_read.news_id AND " . 1355 " il_news_read.user_id = " . $ilDB->quote($ilUser->getId(), "integer") . 1356 " WHERE " . 1357 "context_obj_id = " . $ilDB->quote($this->getContextObjId(), "integer") . 1358 " AND context_obj_type = " . $ilDB->quote($this->getContextObjType(), "text") . 1359 $and . 1360 " ORDER BY " . $ordering; 1361 } 1362 //echo $query; 1363 $set = $ilDB->query($query); 1364 $result = array(); 1365 while ($rec = $ilDB->fetchAssoc($set)) { 1366 if ($a_limit > 0 && count($result) >= $a_limit) { 1367 continue; 1368 } 1369 if (!$a_for_rss_use || (ilNewsItem::getPrivateFeedId() != false) || ($rec["visibility"] == NEWS_PUBLIC || 1370 ($rec["priority"] == 0 && 1371 ilBlockSetting::_lookup( 1372 "news", 1373 "public_notifications", 1374 0, 1375 $rec["context_obj_id"] 1376 )))) { 1377 $result[$rec["id"]] = $rec; 1378 } 1379 } 1380 1381 // do we get data for rss and may the time limit by an issue? 1382 // do a second query without time limit. 1383 // this is not very performant, but I do not have a better 1384 // idea. The keep_rss_min setting is currently (Jul 2012) only set 1385 // by mediacasts 1386 if ($a_time_period != "" && $a_for_rss_use) { 1387 include_once("./Services/Block/classes/class.ilBlockSetting.php"); 1388 $keep_rss_min = ilBlockSetting::_lookup( 1389 "news", 1390 "keep_rss_min", 1391 0, 1392 $this->getContextObjId() 1393 ); 1394 if ($keep_rss_min > 0) { 1395 return $this->queryNewsForContext( 1396 true, 1397 0, 1398 $a_starting_date, 1399 $a_no_auto_generated, 1400 $a_oldest_first, 1401 $keep_rss_min 1402 ); 1403 } 1404 } 1405 1406 return $result; 1407 } 1408 1409 /** 1410 * Query news data by news ids 1411 * 1412 * @param int[] $a_news_ids 1413 * @return array[] 1414 */ 1415 public static function queryNewsByIds(array $a_news_ids) 1416 { 1417 global $DIC; 1418 $ilDB = $DIC->database(); 1419 $news = array(); 1420 $set = $ilDB->query("SELECT * FROM il_news_item " . 1421 " WHERE " . $ilDB->in("id", $a_news_ids, false, "integer")); 1422 while ($rec = $ilDB->fetchAssoc($set)) { 1423 $news[$rec["id"]] = $rec; 1424 } 1425 return $news; 1426 } 1427 1428 /** 1429 * 1430 * @deprecated will move to ilNewsData 1431 * @param int $a_ref_id 1432 * @param int $a_time_period hours 1433 * @return array news item ids 1434 */ 1435 public function checkNewsExistsForObjects($objects, $a_time_period = 1) 1436 { 1437 $ilDB = $this->db; 1438 1439 $all = array(); 1440 1441 $limit_ts = self::handleTimePeriod($a_time_period); 1442 1443 // are there any news items for relevant objects and? 1444 $query = $ilDB->query("SELECT id,context_obj_id,context_obj_type" . 1445 " FROM il_news_item" . 1446 " WHERE " . $ilDB->in("context_obj_id", array_keys($objects), false, "integer") . 1447 " AND creation_date >= " . $ilDB->quote($limit_ts, "timestamp")); 1448 while ($rec = $ilDB->fetchAssoc($query)) { 1449 if ($objects[$rec["context_obj_id"]]["type"] == $rec["context_obj_type"]) { 1450 $all[] = $rec["id"]; 1451 } 1452 } 1453 1454 return $all; 1455 } 1456 1457 /** 1458 * Query News for multiple Contexts 1459 * @deprecated will move to ilNewsData 1460 * @param array $a_contexts 1461 * @param bool $a_for_rss_use 1462 * @param int $a_time_period 1463 * @param string $a_starting_date 1464 * @param bool $a_no_auto_generated 1465 * @param null $a_user_id 1466 * @param int $a_limit 1467 * @param int[] $a_exclude 1468 * @return array 1469 */ 1470 public function queryNewsForMultipleContexts( 1471 $a_contexts, 1472 $a_for_rss_use = false, 1473 $a_time_period = 0, 1474 $a_starting_date = "", 1475 $a_no_auto_generated = false, 1476 $a_user_id = null, 1477 $a_limit = 0, 1478 $a_exclude = array() 1479 ) { 1480 $ilDB = $this->db; 1481 $ilUser = $this->user; 1482 $lng = $this->lng; 1483 $ilCtrl = $this->ctrl; 1484 1485 $and = ""; 1486 if ($a_time_period > 0) { 1487 $limit_ts = self::handleTimePeriod($a_time_period); 1488 $and = " AND creation_date >= " . $ilDB->quote($limit_ts, "timestamp") . " "; 1489 } 1490 1491 if ($a_starting_date != "") { 1492 $and .= " AND creation_date > " . $ilDB->quote($a_starting_date, "timestamp") . " "; 1493 } 1494 1495 if ($a_no_auto_generated) { 1496 $and .= " AND priority = 1 AND content_type = " . $ilDB->quote("text", "text") . " "; 1497 } 1498 1499 if ($a_limit > 0) { 1500 $ilDB->setLimit($a_limit, 0); 1501 } 1502 1503 if (is_array($a_exclude) && count($a_exclude) > 0) { 1504 $and .= " AND " . $ilDB->in("id", $a_exclude, true, "integer") . " "; 1505 } 1506 1507 $ids = array(); 1508 $type = array(); 1509 1510 foreach ($a_contexts as $cont) { 1511 $ids[] = $cont["obj_id"]; 1512 $type[$cont["obj_id"]] = $cont["obj_type"]; 1513 } 1514 1515 if ($a_for_rss_use && ilNewsItem::getPrivateFeedId() == false) { 1516 $query = "SELECT * " . 1517 "FROM il_news_item " . 1518 " WHERE " . 1519 $ilDB->in("context_obj_id", $ids, false, "integer") . " " . 1520 $and . 1521 " ORDER BY creation_date DESC "; 1522 } elseif (ilNewsItem::getPrivateFeedId() != false) { 1523 $query = "SELECT il_news_item.* " . 1524 ", il_news_read.user_id as user_read " . 1525 "FROM il_news_item LEFT JOIN il_news_read " . 1526 "ON il_news_item.id = il_news_read.news_id AND " . 1527 " il_news_read.user_id = " . $ilDB->quote(ilNewsItem::getPrivateFeedId(), "integer") . 1528 " WHERE " . 1529 $ilDB->in("context_obj_id", $ids, false, "integer") . " " . 1530 $and . 1531 " ORDER BY creation_date DESC "; 1532 } else { 1533 if ($a_user_id) { 1534 $user_id = $a_user_id; 1535 } else { 1536 $user_id = $ilUser->getId(); 1537 } 1538 $query = "SELECT il_news_item.* " . 1539 ", il_news_read.user_id as user_read " . 1540 "FROM il_news_item LEFT JOIN il_news_read " . 1541 "ON il_news_item.id = il_news_read.news_id AND " . 1542 " il_news_read.user_id = " . $ilDB->quote($user_id, "integer") . 1543 " WHERE " . 1544 $ilDB->in("context_obj_id", $ids, false, "integer") . " " . 1545 $and . 1546 " ORDER BY creation_date DESC "; 1547 } 1548 1549 $set = $ilDB->query($query); 1550 $result = array(); 1551 while ($rec = $ilDB->fetchAssoc($set)) { 1552 if ($type[$rec["context_obj_id"]] == $rec["context_obj_type"]) { 1553 if (!$a_for_rss_use || ilNewsItem::getPrivateFeedId() != false || ($rec["visibility"] == NEWS_PUBLIC || 1554 ($rec["priority"] == 0 && 1555 ilBlockSetting::_lookup( 1556 "news", 1557 "public_notifications", 1558 0, 1559 $rec["context_obj_id"] 1560 )))) { 1561 $result[$rec["id"]] = $rec; 1562 } 1563 } 1564 } 1565 1566 return $result; 1567 } 1568 1569 1570 /** 1571 * Set item read. 1572 * @deprecated will move to ilNewsData 1573 */ 1574 public static function _setRead($a_user_id, $a_news_id) 1575 { 1576 global $DIC; 1577 1578 $ilDB = $DIC->database(); 1579 $ilAppEventHandler = $DIC["ilAppEventHandler"]; 1580 1581 $ilDB->replace( 1582 "il_news_read", 1583 array( 1584 "user_id" => array("integer", $a_user_id), 1585 "news_id" => array("integer", $a_news_id) 1586 ), 1587 array() 1588 ); 1589 1590 /* 1591 $ilDB->manipulate("DELETE FROM il_news_read WHERE ". 1592 "user_id = ".$ilDB->quote($a_user_id, "integer"). 1593 " AND news_id = ".$ilDB->quote($a_news_id, "integer")); 1594 $ilDB->manipulate("INSERT INTO il_news_read (user_id, news_id) VALUES (". 1595 $ilDB->quote($a_user_id, "integer").",". 1596 $ilDB->quote($a_news_id, "integer").")");*/ 1597 1598 $ilAppEventHandler->raise( 1599 "Services/News", 1600 "readNews", 1601 array("user_id" => $a_user_id, "news_ids" => array($a_news_id)) 1602 ); 1603 } 1604 1605 /** 1606 * Set item unread. 1607 * @deprecated will move to ilNewsData 1608 */ 1609 public static function _setUnread($a_user_id, $a_news_id) 1610 { 1611 global $DIC; 1612 1613 $ilDB = $DIC->database(); 1614 $ilAppEventHandler = $DIC["ilAppEventHandler"]; 1615 1616 $ilDB->manipulate("DELETE FROM il_news_read (user_id, news_id) VALUES (" . 1617 " WHERE user_id = " . $ilDB->quote($a_user_id, "integer") . 1618 " AND news_id = " . $ilDB->quote($a_news_id, "integer")); 1619 1620 $ilAppEventHandler->raise( 1621 "Services/News", 1622 "unreadNews", 1623 array("user_id" => $a_user_id, "news_ids" => array($a_news_id)) 1624 ); 1625 } 1626 1627 /** 1628 * Merges two sets of news 1629 * @deprecated will move to ilNewsData 1630 * @param array $n1 Array of news 1631 * @param array $n2 Array of news 1632 * 1633 * @return array Array of news 1634 */ 1635 public static function mergeNews($n1, $n2) 1636 { 1637 foreach ($n2 as $id => $news) { 1638 $n1[$id] = $news; 1639 } 1640 1641 return $n1; 1642 } 1643 1644 /** 1645 * Get default visibility for reference id 1646 * @deprecated will move to ilNewsData 1647 * @param $a_ref_id reference id 1648 */ 1649 public static function _getDefaultVisibilityForRefId($a_ref_id) 1650 { 1651 global $DIC; 1652 1653 $tree = $DIC->repositoryTree(); 1654 $ilSetting = $DIC->settings(); 1655 1656 include_once("./Services/Block/classes/class.ilBlockSetting.php"); 1657 1658 $news_set = new ilSetting("news"); 1659 $default_visibility = ($news_set->get("default_visibility") != "") 1660 ? $news_set->get("default_visibility") 1661 : "users"; 1662 1663 if ($tree->isInTree($a_ref_id)) { 1664 $path = $tree->getPathFull($a_ref_id); 1665 1666 foreach ($path as $key => $row) { 1667 if (!in_array($row["type"], array("root", "cat","crs", "fold", "grp"))) { 1668 continue; 1669 } 1670 1671 $visibility = ilBlockSetting::_lookup( 1672 "news", 1673 "default_visibility", 1674 0, 1675 $row["obj_id"] 1676 ); 1677 1678 if ($visibility != "") { 1679 $default_visibility = $visibility; 1680 } 1681 } 1682 } 1683 1684 return $default_visibility; 1685 } 1686 1687 1688 /** 1689 * Delete news item 1690 * @deprecated will move to ilNewsData 1691 */ 1692 public function delete() 1693 { 1694 $ilDB = $this->db; 1695 1696 // delete il_news_read entries 1697 $ilDB->manipulate("DELETE FROM il_news_read " . 1698 " WHERE news_id = " . $ilDB->quote($this->getId(), "integer")); 1699 1700 // delete multimedia object 1701 $mob = $this->getMobId(); 1702 1703 // delete 1704 $query = "DELETE FROM il_news_item" . 1705 " WHERE id = " . $ilDB->quote($this->getId(), "integer"); 1706 $ilDB->manipulate($query); 1707 1708 // delete mob after news, to have a "mob usage" of 0 1709 if ($mob > 0 and ilObject::_exists($mob)) { 1710 include_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php"); 1711 $mob = new ilObjMediaObject($mob); 1712 $mob->delete(); 1713 } 1714 } 1715 1716 /** 1717 * Get all news of a context 1718 * @deprecated will move to ilNewsData 1719 */ 1720 public static function getNewsOfContext( 1721 $a_context_obj_id, 1722 $a_context_obj_type, 1723 $a_context_sub_obj_id = 0, 1724 $a_context_sub_obj_type = "" 1725 ) { 1726 global $DIC; 1727 1728 $ilDB = $DIC->database(); 1729 1730 if ($a_context_obj_id == 0 || $a_context_obj_type == "") { 1731 return []; 1732 } 1733 1734 if ($a_context_sub_obj_id > 0) { 1735 $and = " AND context_sub_obj_id = " . $ilDB->quote($a_context_sub_obj_id, "integer") . 1736 " AND context_sub_obj_type = " . $ilDB->quote($a_context_sub_obj_type, "text"); 1737 } 1738 1739 // get news records 1740 $query = "SELECT * FROM il_news_item" . 1741 " WHERE context_obj_id = " . $ilDB->quote($a_context_obj_id, "integer") . 1742 " AND context_obj_type = " . $ilDB->quote($a_context_obj_type, "text") . 1743 $and; 1744 1745 $news_set = $ilDB->query($query); 1746 1747 $news_arr = []; 1748 while ($news = $ilDB->fetchAssoc($news_set)) { 1749 $news_arr[] = new ilNewsItem($news["id"]); 1750 } 1751 return $news_arr; 1752 } 1753 1754 /** 1755 * Delete all news of a context 1756 * @deprecated will move to ilNewsData 1757 */ 1758 public static function deleteNewsOfContext( 1759 $a_context_obj_id, 1760 $a_context_obj_type, 1761 $a_context_sub_obj_id = 0, 1762 $a_context_sub_obj_type = "" 1763 ) { 1764 foreach (self::getNewsOfContext( 1765 $a_context_obj_id, 1766 $a_context_obj_type, 1767 $a_context_sub_obj_id, 1768 $a_context_sub_obj_type 1769 ) as $n) { 1770 $n->delete(); 1771 } 1772 } 1773 1774 /** 1775 * Lookup News Title 1776 * @deprecated will move to ilNewsData 1777 */ 1778 public static function _lookupTitle($a_news_id) 1779 { 1780 global $DIC; 1781 1782 $ilDB = $DIC->database(); 1783 1784 $query = "SELECT title FROM il_news_item WHERE id = " . 1785 $ilDB->quote($a_news_id, "integer"); 1786 $set = $ilDB->query($query); 1787 $rec = $ilDB->fetchAssoc($set); 1788 return $rec["title"]; 1789 } 1790 1791 /** 1792 * Lookup News Visibility 1793 * @deprecated will move to ilNewsData 1794 */ 1795 public static function _lookupVisibility($a_news_id) 1796 { 1797 global $DIC; 1798 1799 $ilDB = $DIC->database(); 1800 1801 $query = "SELECT visibility FROM il_news_item WHERE id = " . 1802 $ilDB->quote($a_news_id, "integer"); 1803 $set = $ilDB->query($query); 1804 $rec = $ilDB->fetchAssoc($set); 1805 1806 return $rec["visibility"]; 1807 } 1808 1809 /** 1810 * Lookup mob id 1811 * @deprecated will move to ilNewsData 1812 */ 1813 public static function _lookupMobId($a_news_id) 1814 { 1815 global $DIC; 1816 1817 $ilDB = $DIC->database(); 1818 1819 $query = "SELECT mob_id FROM il_news_item WHERE id = " . 1820 $ilDB->quote($a_news_id, "integer"); 1821 $set = $ilDB->query($query); 1822 $rec = $ilDB->fetchAssoc($set); 1823 return $rec["mob_id"]; 1824 } 1825 1826 /** 1827 * Checks whether news are available for 1828 * @deprecated will move to ilNewsData 1829 */ 1830 public static function filterObjIdsPerNews($a_obj_ids, $a_time_period = 0, $a_starting_date = "", $a_ending_date = '', $ignore_period = false) 1831 { 1832 global $DIC; 1833 1834 $ilDB = $DIC->database(); 1835 1836 $and = ""; 1837 if ($a_time_period > 0) { 1838 $limit_ts = self::handleTimePeriod($a_time_period); 1839 $and = " AND creation_date >= " . $ilDB->quote($limit_ts, "timestamp") . " "; 1840 } 1841 1842 if ($a_starting_date != "") { 1843 $and .= " AND creation_date >= " . $ilDB->quote($a_starting_date, "timestamp"); 1844 } 1845 1846 $query = "SELECT DISTINCT(context_obj_id) AS obj_id FROM il_news_item" . 1847 " WHERE " . $ilDB->in("context_obj_id", $a_obj_ids, false, "integer") . " " . $and; 1848 //" WHERE context_obj_id IN (".implode(ilUtil::quoteArray($a_obj_ids),",").")".$and; 1849 1850 $set = $ilDB->query($query); 1851 $objs = array(); 1852 while ($rec = $ilDB->fetchAssoc($set)) { 1853 $objs[] = $rec["obj_id"]; 1854 } 1855 1856 return $objs; 1857 } 1858 1859 /** 1860 * Determine title for news item entry 1861 */ 1862 public static function determineNewsTitleByNewsId($a_news_id, $a_agg_ref_id = 0, $a_aggregation = "") 1863 { 1864 global $DIC; 1865 1866 $ilDB = $DIC->database(); 1867 1868 $query = "SELECT context_obj_type, content_is_lang_var, title FROM il_news_item WHERE id = " . 1869 $ilDB->quote($a_news_id, "integer"); 1870 $set = $ilDB->query($query); 1871 $rec = $ilDB->fetchAssoc($set); 1872 1873 return self::determineNewsTitle( 1874 $rec["context_obj_type"], 1875 $rec["title"], 1876 $rec["content_is_lang_var"], 1877 $a_agg_ref_id, 1878 $a_aggregation 1879 ); 1880 } 1881 1882 /** 1883 * Determine title for news item entry 1884 * @deprecated will move to util? 1885 */ 1886 public static function determineNewsTitle( 1887 $a_context_obj_type, 1888 $a_title, 1889 $a_content_is_lang_var, 1890 $a_agg_ref_id = 0, 1891 $a_aggregation = "" 1892 ) { 1893 global $DIC; 1894 1895 $lng = $DIC->language(); 1896 $obj_definition = $DIC["objDefinition"]; 1897 1898 if ($a_agg_ref_id > 0) { 1899 $cnt = count($a_aggregation); 1900 1901 // forums 1902 if ($a_context_obj_type == "frm") { 1903 if ($cnt > 1) { 1904 return sprintf($lng->txt("news_x_postings"), $cnt); 1905 } else { 1906 return $lng->txt("news_1_postings"); 1907 } 1908 } else { // files 1909 $up_cnt = $cr_cnt = 0; 1910 foreach ($a_aggregation as $item) { 1911 if ($item["title"] == "file_updated") { 1912 $up_cnt++; 1913 } else { 1914 $cr_cnt++; 1915 } 1916 } 1917 $sep = ""; 1918 if ($cr_cnt == 1) { 1919 $tit = $lng->txt("news_1_file_created"); 1920 $sep = "<br />"; 1921 } elseif ($cr_cnt > 1) { 1922 $tit = sprintf($lng->txt("news_x_files_created"), $cr_cnt); 1923 $sep = "<br />"; 1924 } 1925 if ($up_cnt == 1) { 1926 $tit .= $sep . $lng->txt("news_1_file_updated"); 1927 } elseif ($up_cnt > 1) { 1928 $tit .= $sep . sprintf($lng->txt("news_x_files_updated"), $up_cnt); 1929 } 1930 return $tit; 1931 } 1932 } else { 1933 if ($a_content_is_lang_var) { 1934 if ($obj_definition->isPlugin($a_context_obj_type)) { 1935 return ilObjectPlugin::lookupTxtById($a_context_obj_type, $a_title); 1936 } 1937 return $lng->txt($a_title); 1938 } else { 1939 return $a_title; 1940 } 1941 } 1942 1943 return ""; 1944 } 1945 1946 /** 1947 * Determine new content 1948 * @deprecated will move to util? 1949 */ 1950 public static function determineNewsContent($a_context_obj_type, $a_content, $a_is_lang_var) 1951 { 1952 global $DIC; 1953 1954 $lng = $DIC->language(); 1955 $obj_definition = $DIC["objDefinition"]; 1956 1957 if ($a_is_lang_var) { 1958 if ($obj_definition->isPlugin($a_context_obj_type)) { 1959 return ilObjectPlugin::lookupTxtById($a_context_obj_type, $a_content); 1960 } 1961 $lng->loadLanguageModule($a_context_obj_type); 1962 return $lng->txt($a_content); 1963 } else { 1964 return $a_content; 1965 } 1966 } 1967 1968 1969 1970 /** 1971 * Get first new id of news set related to a certain context 1972 * @deprecated will move to ilNewsData 1973 */ 1974 public static function getFirstNewsIdForContext( 1975 $a_context_obj_id, 1976 $a_context_obj_type, 1977 $a_context_sub_obj_id = "", 1978 $a_context_sub_obj_type = "" 1979 ) { 1980 global $DIC; 1981 1982 $ilDB = $DIC->database(); 1983 1984 // Determine how many rows should be deleted 1985 $query = "SELECT * " . 1986 "FROM il_news_item " . 1987 "WHERE " . 1988 "context_obj_id = " . $ilDB->quote($a_context_obj_id, "integer") . 1989 " AND context_obj_type = " . $ilDB->quote($a_context_obj_type, "text") . 1990 " AND context_sub_obj_id = " . $ilDB->quote($a_context_sub_obj_id, "integer") . 1991 " AND " . $ilDB->equals("context_sub_obj_type", $a_context_sub_obj_type, "text", true); 1992 1993 $set = $ilDB->query($query); 1994 $rec = $ilDB->fetchAssoc($set); 1995 1996 return $rec["id"]; 1997 } 1998 1999 /** 2000 * Get last news id of news set related to a certain context 2001 * @deprecated will move to ilNewsData 2002 */ 2003 public static function getLastNewsIdForContext( 2004 $a_context_obj_id, 2005 $a_context_obj_type, 2006 $a_context_sub_obj_id = "", 2007 $a_context_sub_obj_type = "", 2008 $a_only_today = false 2009 ) { 2010 global $DIC; 2011 2012 $ilDB = $DIC->database(); 2013 2014 // Determine how many rows should be deleted 2015 $query = "SELECT id, update_date " . 2016 "FROM il_news_item " . 2017 "WHERE " . 2018 "context_obj_id = " . $ilDB->quote($a_context_obj_id, "integer") . 2019 " AND context_obj_type = " . $ilDB->quote($a_context_obj_type, "text") . 2020 " AND context_sub_obj_id = " . $ilDB->quote($a_context_sub_obj_id, "integer") . 2021 " AND " . $ilDB->equals("context_sub_obj_type", $a_context_sub_obj_type, "text", true) . 2022 " ORDER BY update_date DESC"; 2023 2024 $ilDB->setLimit(1); 2025 $set = $ilDB->query($query); 2026 $rec = $ilDB->fetchAssoc($set); 2027 2028 $id = (int) $rec["id"]; 2029 if ($a_only_today) { 2030 $now = ilUtil::now(); 2031 if (substr($now, 0, 10) != substr($rec["update_date"], 0, 10)) { 2032 $id = 0; 2033 } 2034 } 2035 2036 return $id; 2037 } 2038 2039 2040 /** 2041 * Lookup media object usage(s) 2042 * @deprecated will move to ilNewsData 2043 */ 2044 public static function _lookupMediaObjectUsages($a_mob_id) 2045 { 2046 global $DIC; 2047 2048 $ilDB = $DIC->database(); 2049 2050 $query = "SELECT * " . 2051 "FROM il_news_item " . 2052 "WHERE " . 2053 " mob_id = " . $ilDB->quote($a_mob_id, "integer"); 2054 2055 $usages = array(); 2056 $set = $ilDB->query($query); 2057 while ($rec = $ilDB->fetchAssoc($set)) { 2058 $usages[$rec["id"]] = array("type" => "news", "id" => $rec["id"]); 2059 } 2060 2061 return $usages; 2062 } 2063 2064 /** 2065 * Context Object ID 2066 * @deprecated will move to ilNewsData 2067 */ 2068 public static function _lookupContextObjId($a_news_id) 2069 { 2070 global $DIC; 2071 2072 $ilDB = $DIC->database(); 2073 2074 $query = "SELECT * " . 2075 "FROM il_news_item " . 2076 "WHERE " . 2077 " id = " . $ilDB->quote($a_news_id, "integer"); 2078 $set = $ilDB->query($query); 2079 $rec = $ilDB->fetchAssoc($set); 2080 2081 return $rec["context_obj_id"]; 2082 } 2083 2084 /** 2085 * @deprecated will move to settings 2086 */ 2087 public static function _lookupDefaultPDPeriod() 2088 { 2089 $news_set = new ilSetting("news"); 2090 $per = $news_set->get("pd_period"); 2091 if ($per == 0) { 2092 $per = 30; 2093 } 2094 2095 return $per; 2096 } 2097 2098 /** 2099 * @deprecated will move to settings->user 2100 */ 2101 public static function _lookupUserPDPeriod($a_user_id) 2102 { 2103 $news_set = new ilSetting("news"); 2104 $allow_shorter_periods = $news_set->get("allow_shorter_periods"); 2105 $allow_longer_periods = $news_set->get("allow_longer_periods"); 2106 $default_per = ilNewsItem::_lookupDefaultPDPeriod(); 2107 2108 include_once("./Services/Block/classes/class.ilBlockSetting.php"); 2109 $per = ilBlockSetting::_lookup( 2110 "pdnews", 2111 "news_pd_period", 2112 $a_user_id, 2113 0 2114 ); 2115 2116 // news period information 2117 if ($per <= 0 || 2118 (!$allow_shorter_periods && ($per < $default_per)) || 2119 (!$allow_longer_periods && ($per > $default_per)) 2120 ) { 2121 $per = $default_per; 2122 } 2123 2124 return $per; 2125 } 2126 2127 /** 2128 * @deprecated will move to settings 2129 */ 2130 public static function _lookupRSSPeriod() 2131 { 2132 $news_set = new ilSetting("news"); 2133 $rss_period = $news_set->get("rss_period"); 2134 if ($rss_period == 0) { // default to two weeks 2135 $rss_period = 14; 2136 } 2137 return $rss_period; 2138 } 2139 2140 /** 2141 * @deprecated will move to settings->user 2142 */ 2143 public static function setPrivateFeedId($a_userId) 2144 { 2145 ilNewsItem::$privFeedId = $a_userId; 2146 } 2147 2148 /** 2149 * @deprecated will move to settings->user 2150 */ 2151 public static function getPrivateFeedId() 2152 { 2153 return ilNewsItem::$privFeedId; 2154 } 2155 2156 /** 2157 * Deliver mob file 2158 * 2159 * @deprecated will move to ? 2160 * @param string $a_purpose 2161 * @param bool $a_increase_download_cnt 2162 * @return bool 2163 */ 2164 public function deliverMobFile($a_purpose = "Standard", $a_increase_download_cnt = false) 2165 { 2166 $mob = $this->getMobId(); 2167 include_once("./Services/MediaObjects/classes/class.ilObjMediaObject.php"); 2168 $mob = new ilObjMediaObject($mob); 2169 $mob_dir = ilObjMediaObject::_getDirectory($mob->getId()); 2170 2171 // check purpose 2172 if (!$mob->hasPurposeItem($a_purpose)) { 2173 return false; 2174 } 2175 2176 $m_item = $mob->getMediaItem($a_purpose); 2177 if ($m_item->getLocationType() != "Reference") { 2178 $file = $mob_dir . "/" . $m_item->getLocation(); 2179 if (file_exists($file) && is_file($file)) { 2180 if ($a_increase_download_cnt) { 2181 $this->increaseDownloadCounter(); 2182 } 2183 ilUtil::deliverFile($file, $m_item->getLocation(), "", false, false, false); 2184 return true; 2185 } else { 2186 ilUtil::sendFailure("File not found!", true); 2187 return false; 2188 } 2189 } else { 2190 if ($a_increase_download_cnt) { 2191 $this->increaseDownloadCounter(); 2192 } 2193 ilUtil::redirect($m_item->getLocation()); 2194 } 2195 } 2196 2197 /** 2198 * Increase download counter 2199 * @deprecated will move to data 2200 */ 2201 public function increaseDownloadCounter() 2202 { 2203 $ilDB = $this->db; 2204 2205 $cnt = $this->getMobDownloadCounter(); 2206 $cnt++; 2207 $this->setMobDownloadCounter($cnt); 2208 $ilDB->manipulate( 2209 "UPDATE il_news_item SET " . 2210 " mob_cnt_download = " . $ilDB->quote($cnt, "integer") . 2211 " WHERE id = " . $ilDB->quote($this->getId(), "integer") 2212 ); 2213 } 2214 2215 /** 2216 * Increase play counter 2217 * 2218 * @deprecated will move to data 2219 */ 2220 public function increasePlayCounter() 2221 { 2222 $ilDB = $this->db; 2223 2224 $cnt = $this->getMobPlayCounter(); 2225 $cnt++; 2226 $this->setMobPlayCounter($cnt); 2227 $ilDB->manipulate( 2228 "UPDATE il_news_item SET " . 2229 " mob_cnt_play = " . $ilDB->quote($cnt, "integer") . 2230 " WHERE id = " . $ilDB->quote($this->getId(), "integer") 2231 ); 2232 } 2233 2234 /** 2235 * Prepare news data from cache 2236 * @deprecated will move to data 2237 * @param string $a_cres cache string 2238 * @return array news array 2239 */ 2240 public static function prepareNewsDataFromCache($a_cres) 2241 { 2242 global $DIC; 2243 2244 $ilDB = $DIC->database(); 2245 2246 $data = $a_cres; 2247 $news_ids = array_keys($data); 2248 $set = $ilDB->query("SELECT id FROM il_news_item " . 2249 " WHERE " . $ilDB->in("id", $news_ids, false, "integer")); 2250 $existing_ids = array(); 2251 while ($rec = $ilDB->fetchAssoc($set)) { 2252 $existing_ids[] = $rec["id"]; 2253 } 2254 //var_dump($existing_ids); 2255 $existing_news = array(); 2256 foreach ($data as $k => $v) { 2257 if (in_array($k, $existing_ids)) { 2258 $existing_news[$k] = $v; 2259 } 2260 } 2261 2262 //var_dump($data); 2263 //var_dump($existing_news); 2264 2265 return $existing_news; 2266 } 2267} 2268