19declare(strict_types=1);
63 $this->
lng = $lng ??
$DIC->language();
64 $this->ilDB = $database ??
$DIC->database();
72 return 'frm_notification';
77 return $this->
lng->txt(
'cron_forum_notification');
82 return $this->
lng->txt(
'cron_forum_notification_crob_desc');
112 $this->
logger->debug(
'Sending ping to cron manager ...');
113 $this->cronManager->ping($this->
getId());
114 $this->
logger->debug(sprintf(
'Current memory usage: %s', memory_get_usage(
true)));
121 $this->
logger = $DIC->logger()->frm();
122 $this->tree =
$DIC->repositoryTree();
126 $this->
lng->loadLanguageModule(
'forum');
128 $this->
logger->info(
'Started forum notification job ...');
130 if (!($last_run_datetime = $this->
settings->get(
'cron_forum_notification_last_date'))) {
131 $last_run_datetime =
null;
134 $this->num_sent_messages = 0;
135 $cj_start_date = date(
'Y-m-d H:i:s');
137 if ((
string) $this->
settings->get(
'max_notification_age',
'') ===
'') {
138 $this->
logger->info(sprintf(
139 'No maximum notification age set, %s days will be used to determine the ' .
140 'left interval when querying the relevant forum events.',
141 self::DEFAULT_MAX_NOTIFICATION_AGE_IN_DAYS
145 if ($last_run_datetime !==
null &&
147 (
int) date(
'm', strtotime($last_run_datetime)),
148 (
int) date(
'd', strtotime($last_run_datetime)),
149 (
int) date(
'Y', strtotime($last_run_datetime))
152 strtotime($last_run_datetime),
153 strtotime(
'-' . (
int) $this->
settings->get(
'max_notification_age', (
string) self::DEFAULT_MAX_NOTIFICATION_AGE_IN_DAYS) .
' days')
156 $threshold = strtotime(
'-' . (
int) $this->
settings->get(
'max_notification_age', (
string) self::DEFAULT_MAX_NOTIFICATION_AGE_IN_DAYS) .
' days');
159 $this->
logger->info(sprintf(
'Threshold for forum event determination is: %s', date(
'Y-m-d H:i:s', $threshold)));
161 $threshold_date = date(
'Y-m-d H:i:s', $threshold);
175 $this->
settings->set(
'cron_forum_notification_last_date', $cj_start_date);
177 $mess =
'Sent ' . $this->num_sent_messages .
' messages.';
179 $this->
logger->info($mess);
180 $this->
logger->info(
'Finished forum notification job');
183 if ($this->num_sent_messages) {
185 $result->setMessage($mess);
188 $result->setStatus($status);
198 if (!array_key_exists($a_obj_id, self::$ref_ids_by_obj_id)) {
202 return self::$ref_ids_by_obj_id[$a_obj_id];
208 $ilAccess =
$DIC->access();
210 if (!array_key_exists($a_user_id, self::$accessible_ref_ids_by_user)) {
211 self::$accessible_ref_ids_by_user[$a_user_id] = [];
214 if (!array_key_exists($a_obj_id, self::$accessible_ref_ids_by_user[$a_user_id])) {
215 $accessible_ref_id = 0;
217 if ($ilAccess->checkAccessOfUser($a_user_id,
'read',
'',
$ref_id)) {
222 self::$accessible_ref_ids_by_user[$a_user_id][$a_obj_id] = $accessible_ref_id;
225 return (
int) self::$accessible_ref_ids_by_user[$a_user_id][$a_obj_id];
237 self::$deleted_ids_cache[$row[
'deleted_id']] = $row[
'deleted_id'];
240 if (defined(
'ANONYMOUS_USER_ID') && (
int) $row[
'user_id'] ===
ANONYMOUS_USER_ID) {
248 'The recipient with id %s has no "read" permission for object with id %s',
259 $row[
'closest_container'] =
null;
264 $provider_id = isset($row[
'deleted_id']) ? -((
int) $row[
'deleted_id']) : (
int) $row[
'pos_pk'];
266 self::$providerObject[$provider_id .
'_' . $notification_type]->addRecipient((
int) $row[
'user_id']);
272 $usrIdsToPreload = [];
273 foreach (self::$providerObject as
$provider) {
278 $usrIdsToPreload[
$provider->getPosDisplayUserId()] =
$provider->getPosDisplayUserId();
281 $usrIdsToPreload[
$provider->getPostUpdateUserId()] =
$provider->getPostUpdateUserId();
288 foreach (self::$providerObject as
$provider) {
289 if (
$i > 0 && (
$i % self::KEEP_ALIVE_CHUNK_SIZE) === 0) {
293 $recipients = array_unique(
$provider->getCronRecipients());
297 'Trying to send forum notifications for posting id "%s", type "%s" and recipients: %s',
300 implode(
', ', $recipients)
305 $mailNotification->setIsCronjob(
true);
306 $mailNotification->setType($notification_type);
307 $mailNotification->setRecipients($recipients);
309 $mailNotification->send();
311 $this->num_sent_messages += count(
$provider->getCronRecipients());
312 $this->
logger->info(
'Sent notifications ... ');
324 public function determineClosestContainer(
int $frm_ref_id): ?
ilObject
326 if (isset(self::$container_by_frm_ref_id[$frm_ref_id])) {
327 return self::$container_by_frm_ref_id[$frm_ref_id];
330 $ref_id = $this->tree->checkForParentType($frm_ref_id,
'crs');
332 $ref_id = $this->tree->checkForParentType($frm_ref_id,
'grp');
338 self::$container_by_frm_ref_id[$frm_ref_id] =
$container;
347 return isset(self::$providerObject[$provider_id .
'_' . $notification_type]);
356 self::$providerObject[$provider_id .
'_' . $notification_type] = $tmp_provider;
357 self::$providerObject[$provider_id .
'_' . $notification_type]->addRecipient((
int) $row[
'user_id']);
362 self::$providerObject = [];
367 switch ($a_form_id) {
369 $a_fields[
'cron_forum_notification'] = $a_is_active ?
370 $this->
lng->txt(
'enabled') :
371 $this->
lng->txt(
'disabled');
380 if ($a_currently_active) {
384 $setting->
set(
'forum_notification', (
string) $value);
389 $this->
lng->loadLanguageModule(
'forum');
392 $this->
lng->txt(
'frm_max_notification_age'),
393 'max_notification_age'
395 $max_notification_age->setSize(5);
396 $max_notification_age->setSuffix($this->
lng->txt(
'frm_max_notification_age_unit'));
397 $max_notification_age->setRequired(
true);
398 $max_notification_age->allowDecimals(
false);
399 $max_notification_age->setMinValue(1);
400 $max_notification_age->setInfo($this->
lng->txt(
'frm_max_notification_age_info'));
401 $max_notification_age->setValue(
403 'max_notification_age',
404 (
string) self::DEFAULT_MAX_NOTIFICATION_AGE_IN_DAYS
408 $a_form->
addItem($max_notification_age);
414 'max_notification_age',
416 $this->refinery->byTrying([
417 $this->refinery->kindlyTo()->int(),
418 $this->refinery->in()->series([
419 $this->refinery->kindlyTo()->float(),
420 $this->refinery->kindlyTo()->int()
423 $this->refinery->kindlyTo()->string()
424 ])->transform($a_form->
getInput(
'max_notification_age'))
433 frm_posts.pos_status = %s AND (
434 (frm_posts.pos_date >= %s AND frm_posts.pos_date = frm_posts.pos_activation_date) OR
435 (frm_posts.pos_activation_date >= %s AND frm_posts.pos_date < frm_posts.pos_activation_date)
438 $values = [1, $threshold_date, $threshold_date];
440 $res = $this->ilDB->queryF(
456 frm_notification.interested_events & %s AND
457 frm_posts.pos_cens = %s AND frm_posts.pos_status = %s AND
458 (frm_posts.pos_update > frm_posts.pos_date AND frm_posts.pos_update >= %s) ';
467 $res = $this->ilDB->queryF(
483 frm_notification.interested_events & %s AND
484 frm_posts.pos_cens = %s AND frm_posts.pos_status = %s AND
485 (frm_posts.pos_cens_date >= %s AND frm_posts.pos_cens_date > frm_posts.pos_activation_date ) ';
494 $res = $this->ilDB->queryF(
510 frm_notification.interested_events & %s AND
511 frm_posts.pos_cens = %s AND frm_posts.pos_status = %s AND
512 (frm_posts.pos_cens_date >= %s AND frm_posts.pos_cens_date > frm_posts.pos_activation_date ) ';
521 $res = $this->ilDB->queryF(
529 'uncensored posting',
536 $res = $this->ilDB->queryF(
544 'frm_threads_deleted',
552 $res = $this->ilDB->queryF(
568 $numRows = $this->ilDB->numRows(
$res);
570 $this->
logger->info(sprintf(
'Sending notifications for %s "%s" events ...', $numRows, $actionName));
572 $this->
logger->info(sprintf(
'Sent notifications for %s ...', $actionName));
581 string $actionDescription,
582 int $notificationType
584 $numRows = $this->ilDB->numRows(
$res);
586 $this->
logger->info(sprintf(
'Sending notifications for %s "%s" events ...', $numRows, $actionDescription));
588 if (count(self::$deleted_ids_cache) > 0) {
589 $this->ilDB->manipulate(
590 'DELETE FROM frm_posts_deleted WHERE ' . $this->ilDB->in(
592 self::$deleted_ids_cache,
597 $this->
logger->info(
'Deleted obsolete entries of table "' . $action .
'" ...');
599 $this->
logger->info(sprintf(
'Sent notifications for %s ...', $actionDescription));
608 SELECT frm_threads.thr_subject thr_subject,
609 frm_data.top_name top_name,
610 frm_data.top_frm_fk obj_id,
611 frm_notification.user_id user_id,
612 frm_threads.thr_pk thread_id,
614 FROM frm_notification, frm_posts, frm_threads, frm_data, frm_posts_tree
615 WHERE frm_posts.pos_thr_fk = frm_threads.thr_pk AND ' . $condition .
'
616 AND ((frm_threads.thr_top_fk = frm_data.top_pk AND frm_data.top_frm_fk = frm_notification.frm_id)
617 OR (frm_threads.thr_pk = frm_notification.thread_id
618 AND frm_data.top_pk = frm_threads.thr_top_fk) )
619 AND frm_posts.pos_author_id != frm_notification.user_id
620 AND frm_posts_tree.pos_fk = frm_posts.pos_pk AND frm_posts_tree.parent_pos != 0
621 ORDER BY frm_posts.pos_date ASC';
627 SELECT frm_posts_deleted.thread_title thr_subject,
628 frm_posts_deleted.forum_title top_name,
629 frm_posts_deleted.obj_id obj_id,
630 frm_notification.user_id user_id,
631 frm_posts_deleted.pos_display_user_id,
632 frm_posts_deleted.pos_usr_alias,
633 frm_posts_deleted.deleted_id,
634 frm_posts_deleted.post_date pos_date,
635 frm_posts_deleted.post_title pos_subject,
636 frm_posts_deleted.post_message pos_message,
637 frm_posts_deleted.deleted_by
639 FROM frm_notification, frm_posts_deleted
641 WHERE ( frm_posts_deleted.obj_id = frm_notification.frm_id
642 OR frm_posts_deleted.thread_id = frm_notification.thread_id)
643 AND frm_posts_deleted.pos_display_user_id != frm_notification.user_id
644 AND frm_posts_deleted.is_thread_deleted = %s
645 AND frm_notification.interested_events & %s
646 ORDER BY frm_posts_deleted.post_date ASC';
const SCHEDULE_TYPE_IN_HOURS
@depracated This will be replaced with an ENUM in ILIAS 9
Class ilForumCronNotificationDataProvider.
ILIAS Refinery Factory $refinery
static array $accessible_ref_ids_by_user
__construct(ilDBInterface $database=null, ilForumNotificationCache $notificationCache=null, ilLanguage $lng=null, ilSetting $settings=null, \ILIAS\Refinery\Factory $refinery=null, ilCronManager $cronManager=null)
const KEEP_ALIVE_CHUNK_SIZE
saveCustomSettings(ilPropertyFormGUI $a_form)
getRefIdsByObjId(int $a_obj_id)
sendNotificationForDeletedThreads()
addCustomSettingsToForm(ilPropertyFormGUI $a_form)
createSelectOfDeletionNotificationsSql()
const DEFAULT_MAX_NOTIFICATION_AGE_IN_DAYS
existsProviderObject(int $provider_id, int $notification_type)
ilForumNotificationCache $notificationCache
static array $providerObject
getFirstAccessibleRefIdBUserAndObjId(int $a_user_id, int $a_obj_id)
sendNotificationForUncensoredPosts(string $threshold_date)
addProviderObject(int $provider_id, array $row, int $notification_type)
sendDeleteNotifications(ilDBStatement $res, string $action, string $actionDescription, int $notificationType)
static array $container_by_frm_ref_id
getDefaultScheduleValue()
activationWasToggled(ilDBInterface $db, ilSetting $setting, bool $a_currently_active)
Important: This method is (also) called from the setup process, where the constructor of an ilCronJob...
sendNotificationForUpdatedPosts(string $threshold_date)
ilCronManager $cronManager
static array $deleted_ids_cache
sendCronForumNotification(ilDBStatement $res, int $notification_type)
addToExternalSettingsForm(int $a_form_id, array &$a_fields, bool $a_is_active)
hasAutoActivation()
Is to be activated on "installation", does only work for ILIAS core cron jobs.
sendNotificationForCensoredPosts(string $threshold_date)
sendNotificationForDeletedPosts()
sendNotification(ilDBStatement $res, string $actionName, int $notificationType)
static array $ref_ids_by_obj_id
sendNotificationForNewPosts(string $threshold_date)
createForumPostSql(string $condition)
const TYPE_POST_UNCENSORED
const TYPE_THREAD_DELETED
Class ilForumNotificationCache.
Component logger with individual log levels by component id.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static getInstanceByRefId(int $ref_id, bool $stop_on_error=true)
get an instance of an Ilias object by reference id
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static _getAllReferences(int $id)
get all reference ids for object ID
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
set(string $a_key, string $a_val)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
fetchAssoc(ilDBStatement $statement)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Class ChatMainBarProvider \MainMenu\Provider.