diff --git a/components/ILIAS/Container/News/class.ilContainerNewsSettingsGUI.php b/components/ILIAS/Container/News/class.ilContainerNewsSettingsGUI.php index 62518cf5095a..14d10f75aaa8 100755 --- a/components/ILIAS/Container/News/class.ilContainerNewsSettingsGUI.php +++ b/components/ILIAS/Container/News/class.ilContainerNewsSettingsGUI.php @@ -138,7 +138,6 @@ public function initForm(): ilPropertyFormGUI $block_id = $this->ctrl->getContextObjId(); - // Visibility by date $hide_news_per_date = ilBlockSetting::_lookup( ilNewsForContextBlockGUI::$block_type, "hide_news_per_date", @@ -151,32 +150,60 @@ public function initForm(): ilPropertyFormGUI 0, $block_id ); + $hide_news_mode = ilBlockSetting::_lookup( + ilNewsForContextBlockGUI::$block_type, + "hide_news_mode", + 0, + $block_id + ) ?? ($hide_news_date != "" ? "per_date" : "global"); + $news_co_period = ilBlockSetting::_lookup( + ilNewsForContextBlockGUI::$block_type, + "news_co_period", + 0, + $block_id + ) ?? ""; if ($hide_news_date != "") { $hide_news_date = explode(" ", $hide_news_date); } - // Hide news before a date (courses, groups and categories) + // Hide news: none, per date, or by period (courses, groups and categories) if ($this->has_hide_by_date) { - //Hide news per date - $hnpd = new ilCheckboxInputGUI( - $this->lng->txt("news_hide_news_per_date"), - "hide_news_per_date" - ); - $hnpd->setInfo($this->lng->txt("news_hide_news_per_date_info")); - $hnpd->setChecked((bool) $hide_news_per_date); + $radio = new ilRadioGroupInputGUI($this->lng->txt("news_hide_news_mode"), "hide_news_mode"); + $radio->setValue($hide_news_mode); + $opt_global = new ilRadioOption($this->lng->txt("news_hide_news_global"), "global"); + $radio->addOption($opt_global); + + $opt_none = new ilRadioOption($this->lng->txt("news_hide_news_none"), "none"); + $radio->addOption($opt_none); + + $opt_per_date = new ilRadioOption($this->lng->txt("news_hide_news_per_date"), "per_date"); + $opt_per_date->setInfo($this->lng->txt("news_hide_news_per_date_info")); $dt_prop = new ilDateTimeInputGUI($this->lng->txt("news_hide_news_date"), "hide_news_date"); $dt_prop->setRequired(true); - if (is_array($hide_news_date)) { + if (is_array($hide_news_date) && count($hide_news_date) >= 2) { $dt_prop->setDate(new ilDateTime($hide_news_date[0] . ' ' . ($hide_news_date[1] ?? "12:00:00"), IL_CAL_DATETIME)); } - $dt_prop->setShowTime(true); - - $hnpd->addSubItem($dt_prop); - - $form->addItem($hnpd); + $opt_per_date->addSubItem($dt_prop); + $radio->addOption($opt_per_date); + + $opt_by_period = new ilRadioOption($this->lng->txt("news_hide_news_by_period"), "by_period"); + $opt_by_period->setInfo($this->lng->txt("news_hide_news_by_period_info")); + $per_sel = new ilSelectInputGUI($this->lng->txt("news_co_period"), "news_co_period"); + $per_sel->setRequired(true); + $per_sel->setInfo($this->lng->txt("news_co_period_info")); + $per_sel->setOptions([ + 7 => "1 {$this->lng->txt("week")}", + 30 => "1 {$this->lng->txt("month")}", + 366 => "1 {$this->lng->txt("year")}" + ]); + $per_sel->setValue($news_co_period); + $opt_by_period->addSubItem($per_sel); + $radio->addOption($opt_by_period); + + $form->addItem($radio); } // public notifications (forums) @@ -216,15 +243,45 @@ public function save(): void //save contextblock settings $context_block_settings = [ "public_feed" => $form->getInput("notifications_public_feed") ?? "", - "default_visibility" => $form->getInput("default_visibility"), - "hide_news_per_date" => $form->getInput("hide_news_per_date"), - "hide_news_date" => $form->getInput("hide_news_date") + "default_visibility" => $form->getInput("default_visibility") ]; if ($this->has_public_notification) { $context_block_settings["public_notifications"] = $form->getInput('public_notifications'); } + if ($this->has_hide_by_date) { + $context_block_settings["hide_news_mode"] = $form->getInput("hide_news_mode"); + switch ($context_block_settings["hide_news_mode"]) { + case "per_date": + $hd = $form->getItemByPostVar("hide_news_date"); + if ($hd instanceof ilDateTimeInputGUI) { + $hide_date = $hd->getDate(); + if (!$hide_date instanceof ilDateTime) { + $hd->setAlert($this->lng->txt("msg_input_is_required")); + $form->setValuesByPost(); + $this->tpl->setContent($form->getHTML()); + return; + } + $context_block_settings["hide_news_per_date"] = "1"; + $context_block_settings["hide_news_date"] = $hide_date->get(IL_CAL_DATETIME); + } + $context_block_settings["news_co_period"] = ""; + break; + case "by_period": + $context_block_settings["hide_news_per_date"] = "0"; + $context_block_settings["hide_news_date"] = ""; + $context_block_settings["news_co_period"] = $form->getInput("news_co_period"); + break; + case "global": + default: + $context_block_settings["hide_news_per_date"] = "0"; + $context_block_settings["hide_news_date"] = ""; + $context_block_settings["news_co_period"] = ""; + break; + } + } + ilNewsForContextBlockGUI::writeSettings($context_block_settings); if (in_array(ilObject::_lookupType($this->object->getId()), ['crs', 'grp'])) { diff --git a/components/ILIAS/News/classes/class.ilNewsItem.php b/components/ILIAS/News/classes/class.ilNewsItem.php index 717e7d657eb1..df1115e25bbf 100755 --- a/components/ILIAS/News/classes/class.ilNewsItem.php +++ b/components/ILIAS/News/classes/class.ilNewsItem.php @@ -1749,6 +1749,11 @@ public static function _lookupDefaultPDPeriod(): int return $per; } + public static function _lookupDefaultCOPeriod(): int + { + return (int) (new ilSetting("news"))->get("co_period") ?: 30; + } + /** * @deprecated will move to settings->user */ diff --git a/components/ILIAS/News/classes/class.ilObjNewsSettingsGUI.php b/components/ILIAS/News/classes/class.ilObjNewsSettingsGUI.php index 0885b34a03c9..8313e826138b 100755 --- a/components/ILIAS/News/classes/class.ilObjNewsSettingsGUI.php +++ b/components/ILIAS/News/classes/class.ilObjNewsSettingsGUI.php @@ -181,6 +181,12 @@ public function getSettingsForm(): ilPropertyFormGUI $per_sel->setValue((string) ilNewsItem::_lookupDefaultPDPeriod()); $form->addItem($per_sel); + $per_sel = new ilSelectInputGUI($lng->txt("news_co_period"), "news_co_period"); + $per_sel->setInfo($lng->txt("news_co_period_info")); + $per_sel->setOptions([-1 => $lng->txt("news_hide_news_none")] + $per_opts); + $per_sel->setValue((string) ilNewsItem::_lookupDefaultCOPeriod()); + $form->addItem($per_sel); + // Allow user to choose lower values $sp_prop = new ilCheckboxInputGUI( $lng->txt("news_allow_shorter_periods"), @@ -291,6 +297,7 @@ public function saveSettings(): void $news_set->set("max_items", $form->getInput("news_max_items")); $news_set->set("acc_cache_mins", $form->getInput("news_acc_cache_mins")); $news_set->set("pd_period", $form->getInput("news_pd_period")); + $news_set->set("co_period", $form->getInput("news_co_period")); $news_set->set("default_visibility", $form->getInput("news_default_visibility")); $news_set->set("allow_shorter_periods", $form->getInput("allow_shorter_periods")); $news_set->set("allow_longer_periods", $form->getInput("allow_longer_periods")); diff --git a/components/ILIAS/News/src/Domain/NewsCollectionService.php b/components/ILIAS/News/src/Domain/NewsCollectionService.php index 5d2bb7040d6f..cf4bba18de2c 100644 --- a/components/ILIAS/News/src/Domain/NewsCollectionService.php +++ b/components/ILIAS/News/src/Domain/NewsCollectionService.php @@ -24,6 +24,7 @@ use ILIAS\News\Data\NewsCollection; use ILIAS\News\Data\NewsContext; use ILIAS\News\Data\NewsCriteria; +use ILIAS\News\Data\NewsItem; use ILIAS\News\Persistence\NewsCache; use ILIAS\News\Persistence\NewsRepository; @@ -216,22 +217,91 @@ private function appendStartDateFilter(array $contexts, NewsCriteria $criteria): $date_filter = []; foreach ($contexts as $context) { - if ( - !in_array($context->getObjType(), ['grp', 'crs']) || - !\ilBlockSetting::_lookup('news', 'hide_news_per_date', 0, $context->getObjId()) - ) { - continue; + $start_date = $this->getContainerStartDateForContext( + $context->getObjId(), + $context->getObjType() ?? '' + ); + if ($start_date instanceof \DateTimeImmutable) { + $date_filter[$context->getObjId()] = $start_date; + } + } + + return $criteria->withStartDates($date_filter); + } + + /** + * Return the start date for container (crs/grp) news filtering, or null if no filter applies. + */ + private function getContainerStartDateForContext(int $context_obj_id, string $context_type, bool $dashboard = false): ?\DateTimeImmutable + { + if (!in_array($context_type, ['grp', 'crs', 'cat'], true)) { + return null; + } + + $hide_news_date_setting = \ilBlockSetting::_lookup('news', 'hide_news_date', 0, $context_obj_id); + $hide_news_mode = \ilBlockSetting::_lookup('news', 'hide_news_mode', 0, $context_obj_id) + ?? ($hide_news_date_setting != "" ? "per_date" : "global"); + + if ($dashboard) { + $pd_period = \ilNewsItem::_lookupDefaultPDPeriod(); + + switch ($hide_news_mode) { + case 'none': + case 'global': + return new \DateTimeImmutable("-{$pd_period} days"); + case 'per_date': + $hide_date = new \DateTimeImmutable(\ilBlockSetting::_lookup('news', 'hide_news_date', 0, $context_obj_id)); + $pd_period_datetime = new \DateTimeImmutable("-{$pd_period} days"); + return $pd_period_datetime > $hide_date ? $pd_period_datetime : $hide_date; + case 'by_period': + $hide_period = \ilBlockSetting::_lookup('news', 'news_co_period', 0, $context_obj_id); + $hide_period = $hide_period <= 0 ? $pd_period : $hide_period; + $hide_period = min($hide_period, $pd_period); + return new \DateTimeImmutable("-{$hide_period} days"); + default: + return null; } + } + + switch ($hide_news_mode) { + case 'global': + $co_period = \ilNewsItem::_lookupDefaultCOPeriod(); + return $co_period > 0 ? new \DateTimeImmutable("-{$co_period} days") : null; + case 'per_date': + $hide_date = \ilBlockSetting::_lookup('news', 'hide_news_date', 0, $context_obj_id); + return !empty($hide_date) ? new \DateTimeImmutable($hide_date) : null; + case 'by_period': + $hide_period = \ilBlockSetting::_lookup('news', 'news_co_period', 0, $context_obj_id); + return !empty($hide_period) ? new \DateTimeImmutable("-{$hide_period} days") : null; + case 'none': + default: + return null; + } + } + + /** + * Filter collection by container (crs/grp) hide_news_mode settings: exclude items + * whose context has a start date and the item's creation date is before it. + */ + private function filterByContainerDateSettings(NewsCollection $collection, bool $dashboard = false): NewsCollection + { + if ($collection instanceof \ILIAS\News\Data\LazyNewsCollection) { + $collection->load(); + } - $hide_date = \ilBlockSetting::_lookup('news', 'hide_news_date', 0, $context->getObjId()); - if (empty($hide_date)) { + $exclude_ids = []; + foreach ($collection->getNewsItems() as $item) { + if (!$item instanceof NewsItem) { continue; } - $date_filter[$context->getObjId()] = new \DateTimeImmutable($hide_date); + $start_date = $this->getContainerStartDateForContext($item->getContextObjId(), $item->getContextObjType(), $dashboard); + if ($start_date instanceof \DateTimeImmutable && $item->getCreationDate() < $start_date) { + $exclude_ids[] = $item->getId(); + } } - return $criteria->withStartDates($date_filter); + return $collection->exclude($exclude_ids); } /** diff --git a/lang/ilias_de.lang b/lang/ilias_de.lang index 476a103a5fe0..5a2e2835e3e7 100644 --- a/lang/ilias_de.lang +++ b/lang/ilias_de.lang @@ -13063,6 +13063,8 @@ news#:#news_block_information#:#Der Block "Neuigkeiten" zeigt chronologisch alle news#:#news_block_news_for_context#:#Neuigkeiten news#:#news_cache#:#Neuigkeiten-Cache (Minuten) news#:#news_cache_info#:#Aktualisierung des Blocks "Neuigkeiten" alle x-Minuten. '0' bedeutet jederzeit. Werte größer Null erhöhen die Performanz entsprechend. Allerdings können Links in Einzelfällen auf nicht mehr zugängliche Objekte verweisen. +news#:#news_co_period#:#Zeitraum für Neuigkeitenanzeige in Container-Objekten +news#:#news_co_period_info#:#Zeitraum, der für Neuigkeiten in Container-Objekten berücksichtigt wird. Bei Performanzproblemen sollten niedrigere Werte gewählt werden. news#:#news_default_visibility#:#Voreinstellung Zugriff news#:#news_edit_news_settings#:#Einstellungen news#:#news_enable_internal_news#:#Interne Neuigkeiten aktivieren @@ -13081,7 +13083,12 @@ news#:#news_get_priv_feed_info#:#Sie haben ein Passwort für Ihren privaten News news#:#news_get_priv_feed_title#:#URL Ihres privaten Newsfeeds news#:#news_hide_news_block#:#Block "Neuigkeiten" verbergen news#:#news_hide_news_block_info#:#Verberge Block in der Lerneransicht. Der Block "Neuigkeiten" wird nur für Benutzer mit Schreibberechtigung sichtbar sein. +news#:#news_hide_news_by_period#:#Zeitraum für Neuigkeiten +news#:#news_hide_news_by_period_info#:#Es werden nur Neuigkeiten in einem bestimmten Zeitraum angezeigt. news#:#news_hide_news_date#:#Startdatum +news#:#news_hide_news_global#:#Benutze globale Einstellung +news#:#news_hide_news_mode#:#Anzeige von Neuigkeiten einschränken +news#:#news_hide_news_none#:#Neuigkeiten nicht einschränken news#:#news_hide_news_per_date#:#Neuigkeiten ab Datum anzeigen news#:#news_hide_news_per_date_info#:#Es werden nur Neuigkeiten ab einem bestimmten Datum angezeigt. news#:#news_inactive_private_feed_info#:#Ihr privater Newsfeed ist deaktiviert. Vergeben Sie ein Passwort in den Einstellungen. diff --git a/lang/ilias_en.lang b/lang/ilias_en.lang index 512dd28c41af..930f45910c22 100644 --- a/lang/ilias_en.lang +++ b/lang/ilias_en.lang @@ -13035,6 +13035,8 @@ news#:#news_block_information#:#The News block lists all news that are re news#:#news_block_news_for_context#:#News news#:#news_cache#:#News Cache (Minutes) news#:#news_cache_info#:#Update news blocks all x minutes. ‘0’ means every time. Higher values improve performance, but news may link to non-accessible items. +news#:#news_co_period#:#Container-Objects News Period +news#:#news_co_period_info#:#Defines the time period used for news in Container-Objects. Select lower values, if you experience any performance problems. news#:#news_default_visibility#:#Default Access news#:#news_edit_news_settings#:#Edit Settings news#:#news_enable_internal_news#:#Enable Internal News @@ -13053,7 +13055,12 @@ news#:#news_get_priv_feed_info#:#This is a personal private news feed URL. The f news#:#news_get_priv_feed_title#:#Personal private Feed-URL news#:#news_hide_news_block#:#Hide News Block news#:#news_hide_news_block_info#:#Hide block in learner's view. The news block will only be visible for users with write permission. +news#:#news_hide_news_by_period#:#Show News by Period +news#:#news_hide_news_by_period_info#:#Only news that are in the given period will be displayed. news#:#news_hide_news_date#:#Starting Date +news#:#news_hide_news_global#:#Use global setting +news#:#news_hide_news_mode#:#Limit news display +news#:#news_hide_news_none#:#Do not limit news news#:#news_hide_news_per_date#:#Show News After news#:#news_hide_news_per_date_info#:#Only news that are newer than a certain date will be displayed. news#:#news_inactive_private_feed_info#:#Your private news feed is deactivated. Please set a password in the settings.