Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions components/ILIAS/Forum/Forum.php
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
<?php

/**
* This file is part of ILIAS, a powerful learning management system
* published by ILIAS open source e-Learning e.V.
*
* ILIAS is licensed with the GPL-3.0,
* see https://www.gnu.org/licenses/gpl-3.0.en.html
* You should have received a copy of said license along with the
* source code, too.
*
* If this is not the case or you just want to try ILIAS, you'll find
* us at:
* https://www.ilias.de
* https://github.com/ILIAS-eLearning
*
*********************************************************************/

declare(strict_types=1);

use ILIAS\Notifications\Interfaces\PushProviderInterface;
use ILIAS\Notifications\Model\ilNotificationLink;
use ILIAS\Notifications\Model\ilNotificationParameter;
use ILIAS\Notifications\Provider\NotificationsPushProvider;

final class ilForumPushProvider implements PushProviderInterface
{
public const string IDENTIFIER = 'forum';

private ?NotificationsPushProvider $push_provider = null;

public function getIdentifier(): string
{
return self::IDENTIFIER;
}

public function getName(ilLanguage $lng): string
{
$lng->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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,9 @@ public static function sendNotification(
);
}

$pushProvider = new ilForumPushProvider();
$recipients = $pushProvider->filterMailRecipients($recipients, $provider, $notificationTypes, $logger);

Comment on lines +549 to +551

@mjansenDatabay mjansenDatabay Sep 8, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we please move this step to the bottom of the method, after the notification delivery?

Update: Ah okay, you are filtering the recipients, and therefore cannot change the order.

$mailNotification = new ilForumMailEventNotificationSender($provider, $logger);
$mailNotification->setType($notificationTypes);
$mailNotification->setRecipients($recipients);
Expand Down
1 change: 1 addition & 0 deletions lang/ilias_de.lang
Original file line number Diff line number Diff line change
Expand Up @@ -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?
Expand Down
1 change: 1 addition & 0 deletions lang/ilias_en.lang
Original file line number Diff line number Diff line change
Expand Up @@ -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?
Expand Down
Loading