19 declare(strict_types=1);
63 $this->
lng = $lng ?? $DIC->language();
64 $this->ilDB = $database ?? $DIC->database();
66 $this->
refinery = $refinery ?? $DIC->refinery();
67 $this->cronManager = $cronManager ?? $DIC->cron()->manager();
72 return 'frm_notification';
77 return $this->
lng->txt(
'cron_forum_notification');
82 return $this->
lng->txt(
'cron_forum_notification_crob_desc');
87 return self::SCHEDULE_TYPE_IN_HOURS;
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];
231 $ilDB = $DIC->database();
237 self::$deleted_ids_cache[$row[
'deleted_id']] = $row[
'deleted_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) {
274 if ($provider->getPosAuthorId()) {
275 $usrIdsToPreload[$provider->getPosAuthorId()] = $provider->getPosAuthorId();
277 if ($provider->getPosDisplayUserId()) {
278 $usrIdsToPreload[$provider->getPosDisplayUserId()] = $provider->getPosDisplayUserId();
280 if ($provider->getPostUpdateUserId()) {
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',
298 $provider->getPostId(),
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',
417 $this->refinery->kindlyTo()->int(),
419 $this->
refinery->kindlyTo()->float(),
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';
existsProviderObject(int $provider_id, int $notification_type)
fetchAssoc(ilDBStatement $statement)
Class ChatMainBarProvider .
__construct(ilDBInterface $database=null, ilForumNotificationCache $notificationCache=null, ilLanguage $lng=null, ilSetting $settings=null, \ILIAS\Refinery\Factory $refinery=null, ilCronManager $cronManager=null)
set(string $a_key, string $a_val)
static _getAllReferences(int $id)
get all reference ids for object ID
Class ilForumCronNotificationDataProvider.
sendNotificationForDeletedThreads()
static array $deleted_ids_cache
sendNotificationForUncensoredPosts(string $threshold_date)
sendDeleteNotifications(ilDBStatement $res, string $action, string $actionDescription, int $notificationType)
ILIAS Refinery Factory $refinery
createSelectOfDeletionNotificationsSql()
const TYPE_THREAD_DELETED
const KEEP_ALIVE_CHUNK_SIZE
addProviderObject(int $provider_id, array $row, int $notification_type)
addCustomSettingsToForm(ilPropertyFormGUI $a_form)
const DEFAULT_MAX_NOTIFICATION_AGE_IN_DAYS
ilCronManager $cronManager
sendNotificationForCensoredPosts(string $threshold_date)
static array $ref_ids_by_obj_id
ilForumNotificationCache $notificationCache
getDefaultScheduleValue()
static getInstanceByRefId(int $ref_id, bool $stop_on_error=true)
get an instance of an Ilias object by reference id
activationWasToggled(ilDBInterface $db, ilSetting $setting, bool $a_currently_active)
Class ilForumNotificationCache.
static array $accessible_ref_ids_by_user
sendNotificationForNewPosts(string $threshold_date)
saveCustomSettings(ilPropertyFormGUI $a_form)
getRefIdsByObjId(int $a_obj_id)
addToExternalSettingsForm(int $a_form_id, array &$a_fields, bool $a_is_active)
static array $container_by_frm_ref_id
sendCronForumNotification(ilDBStatement $res, int $notification_type)
getFirstAccessibleRefIdBUserAndObjId(int $a_user_id, int $a_obj_id)
sendNotificationForUpdatedPosts(string $threshold_date)
sendNotification(ilDBStatement $res, string $actionName, int $notificationType)
const TYPE_POST_UNCENSORED
createForumPostSql(string $condition)
static array $providerObject
sendNotificationForDeletedPosts()