From d6f671722e95f97668970b89dc70aca61b71e539 Mon Sep 17 00:00:00 2001 From: iszmais Date: Mon, 7 Sep 2026 14:43:08 +0200 Subject: [PATCH] add push notifications to the forum --- components/ILIAS/Forum/Forum.php | 2 + .../class.ilForumPushProvider.php | 211 ++++++++++++++++++ .../classes/class.ilForumAppEventListener.php | 3 + lang/ilias_de.lang | 1 + lang/ilias_en.lang | 1 + 5 files changed, 218 insertions(+) create mode 100644 components/ILIAS/Forum/classes/Notification/class.ilForumPushProvider.php diff --git a/components/ILIAS/Forum/Forum.php b/components/ILIAS/Forum/Forum.php index 0d79bcdc6cc0..1821c782628a 100644 --- a/components/ILIAS/Forum/Forum.php +++ b/components/ILIAS/Forum/Forum.php @@ -40,5 +40,7 @@ public function init( new Component\Resource\ComponentJS($this, "autosave_forum.js"); $contribute[Component\Resource\PublicAsset::class] = fn() => new Component\Resource\ComponentCSS($this, "forum_table.css"); + $contribute[\ILIAS\Notifications\Interfaces\PushProviderInterface::class] = static fn() => + new \ilForumPushProvider(); } } diff --git a/components/ILIAS/Forum/classes/Notification/class.ilForumPushProvider.php b/components/ILIAS/Forum/classes/Notification/class.ilForumPushProvider.php new file mode 100644 index 000000000000..694a658b69eb --- /dev/null +++ b/components/ILIAS/Forum/classes/Notification/class.ilForumPushProvider.php @@ -0,0 +1,211 @@ +loadLanguageModule('forum'); + + return $lng->txt('forum'); + } + + public function getDescription(ilLanguage $lng): string + { + $lng->loadLanguageModule('forum'); + + return $lng->txt('forums_forum_push_notification_desc'); + } + + /** + * @param int[] $recipients + * @return int[] + */ + public function filterMailRecipients( + array $recipients, + ilForumNotificationMailData $provider, + int $notification_type, + ilLogger $logger + ): array { + global $DIC; + + if (!$DIC->settings()->get('forum_notification', '0')) { + return []; + } + + $mail_recipients = []; + + foreach ($recipients as $recipient_id) { + if ($this->sendPush($recipient_id, $provider, $notification_type)) { + $logger->debug(sprintf('Push notification sent to user "%s".', $recipient_id)); + continue; + } + + $mail_recipients[] = $recipient_id; + } + + return $mail_recipients; + } + + private function sendPush( + int $recipient_id, + ilForumNotificationMailData $provider, + int $notification_type + ): bool { + $user = ilObjectFactory::getInstanceByObjId($recipient_id, false); + if (!$user instanceof ilObjUser) { + return false; + } + + $lng = ilLanguageFactory::_getLanguageOfUser($recipient_id); + $lng->loadLanguageModule('forum'); + + $content = $this->buildPushContent($provider, $notification_type, $lng); + if ($content === null) { + return false; + } + + return $this->getPushProvider()->push( + $user, + $content['title'], + $content['description'], + $this->buildPushLink($provider) + ); + } + + /** + * @return array{title: string, description: string}|null + */ + private function buildPushContent( + ilForumNotificationMailData $provider, + int $notification_type, + ilLanguage $lng + ): ?array { + $subject_key = $this->getSubjectLanguageKey($notification_type); + if ($subject_key === null) { + return null; + } + + $container_text = ''; + if ($provider->providesClosestContainer()) { + $container_text = ' (' . + $lng->txt('frm_noti_obj_' . $provider->closestContainer()->getType()) . + ' "' . $provider->closestContainer()->getTitle() . '")'; + } + + $title = sprintf( + $lng->txt($subject_key), + $provider->getForumTitle(), + $container_text, + $provider->getThreadTitle() + ); + + $description = match ($notification_type) { + ilForumMailNotification::TYPE_THREAD_DELETED => sprintf( + $lng->txt('thread_deleted_by'), + $provider->getDeletedBy(), + $provider->getForumTitle() + ), + ilForumMailNotification::TYPE_POST_NEW => sprintf( + $lng->txt('frm_noti_new_post'), + $provider->getForumTitle() + ), + ilForumMailNotification::TYPE_POST_ACTIVATION => $lng->txt('forums_post_activation_mail'), + ilForumMailNotification::TYPE_POST_ANSWERED => $lng->txt('forum_post_replied'), + ilForumMailNotification::TYPE_POST_UPDATED => sprintf( + $lng->txt('post_updated_by'), + $provider->getPostUpdateUserName($lng), + $provider->getForumTitle() + ), + ilForumMailNotification::TYPE_POST_CENSORED => sprintf( + $lng->txt('post_censored_by'), + $provider->getPostUpdateUserName($lng), + $provider->getForumTitle() + ), + ilForumMailNotification::TYPE_POST_UNCENSORED => sprintf( + $lng->txt('post_uncensored_by'), + $provider->getPostUpdateUserName($lng) + ), + ilForumMailNotification::TYPE_POST_DELETED => sprintf( + $lng->txt('post_deleted_by'), + $provider->getDeletedBy(), + $provider->getForumTitle() + ), + default => null, + }; + + if ($description === null) { + return null; + } + + return [ + 'title' => $title, + 'description' => $description, + ]; + } + + private function getSubjectLanguageKey(int $notification_type): ?string + { + return match ($notification_type) { + ilForumMailNotification::TYPE_THREAD_DELETED => 'frm_noti_subject_del_thread', + ilForumMailNotification::TYPE_POST_NEW => 'frm_noti_subject_new_post', + ilForumMailNotification::TYPE_POST_ACTIVATION => 'frm_noti_subject_act_post', + ilForumMailNotification::TYPE_POST_ANSWERED => 'frm_noti_subject_answ_post', + ilForumMailNotification::TYPE_POST_UPDATED => 'frm_noti_subject_upt_post', + ilForumMailNotification::TYPE_POST_CENSORED => 'frm_noti_subject_cens_post', + ilForumMailNotification::TYPE_POST_UNCENSORED => 'frm_noti_subject_uncens_post', + ilForumMailNotification::TYPE_POST_DELETED => 'frm_noti_subject_del_post', + default => null, + }; + } + + private function buildPushLink(ilForumNotificationMailData $provider): ilNotificationLink + { + $url = rtrim(ilUtil::_getHttpPath(), '/') . '/goto.php?target=frm_' . implode('_', [ + $provider->getRefId(), + $provider->getThreadId(), + $provider->getPostId(), + ]) . '&client_id=' . CLIENT_ID; + + return new ilNotificationLink( + new ilNotificationParameter('forums_notification_show_post', [], 'forum'), + $url + ); + } + + private function getPushProvider(): NotificationsPushProvider + { + return $this->push_provider ??= new NotificationsPushProvider($this); + } +} diff --git a/components/ILIAS/Forum/classes/class.ilForumAppEventListener.php b/components/ILIAS/Forum/classes/class.ilForumAppEventListener.php index f5a6380be8bc..58f4a119059a 100755 --- a/components/ILIAS/Forum/classes/class.ilForumAppEventListener.php +++ b/components/ILIAS/Forum/classes/class.ilForumAppEventListener.php @@ -546,6 +546,9 @@ public static function sendNotification( ); } + $pushProvider = new ilForumPushProvider(); + $recipients = $pushProvider->filterMailRecipients($recipients, $provider, $notificationTypes, $logger); + $mailNotification = new ilForumMailEventNotificationSender($provider, $logger); $mailNotification->setType($notificationTypes); $mailNotification->setRecipients($recipients); diff --git a/lang/ilias_de.lang b/lang/ilias_de.lang index 3f34cb3c9192..a0ea1a9c1933 100644 --- a/lang/ilias_de.lang +++ b/lang/ilias_de.lang @@ -10111,6 +10111,7 @@ forum#:#forums_enable_notification#:#Benachrichtigung für dieses Thema starten forum#:#forums_forum_notification#:#Foren-Benachrichtigungen versenden forum#:#forums_forum_notification_desc#:#Wenn aktiviert, sendet ILIAS Mails an die Benutzer, die bei ausgewählten Foren-Themen über neue Beiträge benachrichtigt werden wollen. forum#:#forums_forum_notification_disabled#:#Sie werden nicht mehr über neue Beiträge in diesem Forum benachrichtigt. +forum#:#forums_forum_push_notification_desc#:#Foren-Benachrichtigungen werden als Push-Benachrichtigungen statt per E-Mail versendet. Wenn die Push-Benachrichtigung nicht zugestellt werden kann, wird stattdessen eine E-Mail versendet. forum#:#forums_info_censor2_post#:#Sind Sie sicher, dass die Zensur für diesen Beitrag aufgehoben werden soll? forum#:#forums_info_censor_post#:#Geben Sie eine Begründung für die Zensur an. forum#:#forums_info_delete_draft#:#Sind Sie sicher, dass Sie diesen Entwurf löschen möchten? diff --git a/lang/ilias_en.lang b/lang/ilias_en.lang index 43e3390b4702..198bdf68fe5b 100644 --- a/lang/ilias_en.lang +++ b/lang/ilias_en.lang @@ -10085,6 +10085,7 @@ forum#:#forums_enable_notification#:#Enable Notification for this Thread forum#:#forums_forum_notification#:#Send Forum Notifications forum#:#forums_forum_notification_desc#:#If enabled, all users, who want to be informed about new posts in specified forum threads, will get notifications by mail. forum#:#forums_forum_notification_disabled#:#You will no longer be notified about new posts in this forum. +forum#:#forums_forum_push_notification_desc#:#Forum notifications are sent as push notifications instead of e-mail. If the push notification cannot be delivered, an e-mail will be sent instead. forum#:#forums_info_censor2_post#:#Revoke Censorship? forum#:#forums_info_censor_post#:#Please provide a reason for hiding this post. forum#:#forums_info_delete_draft#:#Are you sure, you want to delete this draft?