4include_once
"Services/Cron/classes/class.ilCronJob.php";
5include_once
"./Modules/Forum/classes/class.ilForumMailNotification.php";
62 return "frm_notification";
69 return $lng->txt(
"cron_forum_notification");
76 return $lng->txt(
"cron_forum_notification_crob_desc");
112 $this->logger->debug(
'Sending ping to cron manager ...');
124 $this->logger =
$GLOBALS[
'DIC']->logger()->frm();
128 $lng->loadLanguageModule(
'forum');
130 $this->logger->info(
'Started forum notification job ...');
132 if(!($last_run_datetime =
$ilSetting->get(
'cron_forum_notification_last_date')))
134 $last_run_datetime =
null;
137 $this->num_sent_messages = 0;
138 $cj_start_date =
date(
'Y-m-d H:i:s');
140 if($last_run_datetime !=
null &&
141 checkDate(
date(
'm', strtotime($last_run_datetime)),
date(
'd', strtotime($last_run_datetime)),
date(
'Y', strtotime($last_run_datetime))))
143 $threshold = max(strtotime($last_run_datetime), strtotime(
'-' . (
int)$this->
settings->get(
'max_notification_age', 30) .
' days', time()));
147 $threshold = strtotime(
'-' . (
int)$this->
settings->get(
'max_notification_age', 30) .
' days', time());
150 $this->logger->info(
sprintf(
'Threshold for forum event determination is: %s',
date(
'Y-m-d H:i:s', $threshold)));
152 $threshold_date =
date(
'Y-m-d H:i:s', $threshold);
153 $new_posts_condition =
'
154 frm_posts.pos_status = %s AND (
155 (frm_posts.pos_date >= %s AND frm_posts.pos_date = frm_posts.pos_activation_date) OR
156 (frm_posts.pos_activation_date >= %s AND frm_posts.pos_date < frm_posts.pos_activation_date)
158 $types = array(
'integer',
'timestamp',
'timestamp');
159 $values = array(1, $threshold_date, $threshold_date);
163 SELECT frm_threads.thr_subject thr_subject,
164 frm_data.top_name top_name,
165 frm_data.top_frm_fk obj_id,
166 frm_notification.user_id user_id,
167 frm_threads.thr_pk thread_id,
169 FROM frm_notification, frm_posts, frm_threads, frm_data
170 WHERE frm_posts.pos_thr_fk = frm_threads.thr_pk AND '.$new_posts_condition.
'
171 AND ((frm_threads.thr_top_fk = frm_data.top_pk AND frm_data.top_frm_fk = frm_notification.frm_id)
172 OR (frm_threads.thr_pk = frm_notification.thread_id
173 AND frm_data.top_pk = frm_threads.thr_top_fk) )
174 AND frm_posts.pos_display_user_id != frm_notification.user_id
175 ORDER BY frm_posts.pos_date ASC',
183 $this->logger->info(
sprintf(
'Sending notifications for %s "new posting" events ...', $numRows));
185 $this->logger->info(
sprintf(
'Sent notifications for new postings ...'));
191 $updated_condition =
'
192 frm_posts.pos_cens = %s AND frm_posts.pos_status = %s AND
193 (frm_posts.pos_update > frm_posts.pos_date AND frm_posts.pos_update >= %s) ';
194 $types = array(
'integer',
'integer',
'timestamp');
195 $values = array(0, 1, $threshold_date);
198 SELECT frm_threads.thr_subject thr_subject,
199 frm_data.top_name top_name,
200 frm_data.top_frm_fk obj_id,
201 frm_notification.user_id user_id,
202 frm_threads.thr_pk thread_id,
204 FROM frm_notification, frm_posts, frm_threads, frm_data
205 WHERE frm_posts.pos_thr_fk = frm_threads.thr_pk AND '.$updated_condition.
'
206 AND ((frm_threads.thr_top_fk = frm_data.top_pk AND frm_data.top_frm_fk = frm_notification.frm_id)
207 OR (frm_threads.thr_pk = frm_notification.thread_id
208 AND frm_data.top_pk = frm_threads.thr_top_fk) )
209 AND frm_posts.pos_display_user_id != frm_notification.user_id
210 ORDER BY frm_posts.pos_date ASC',
218 $this->logger->info(
sprintf(
'Sending notifications for %s "updated posting" events ...', $numRows));
220 $this->logger->info(
sprintf(
'Sent notifications for updated postings ...'));
226 $censored_condition =
'
227 frm_posts.pos_cens = %s AND frm_posts.pos_status = %s AND
228 (frm_posts.pos_cens_date >= %s AND frm_posts.pos_cens_date > frm_posts.pos_activation_date ) ';
229 $types = array(
'integer',
'integer',
'timestamp');
230 $values = array(1, 1, $threshold_date);
233 SELECT frm_threads.thr_subject thr_subject,
234 frm_data.top_name top_name,
235 frm_data.top_frm_fk obj_id,
236 frm_notification.user_id user_id,
237 frm_threads.thr_pk thread_id,
239 FROM frm_notification, frm_posts, frm_threads, frm_data
240 WHERE frm_posts.pos_thr_fk = frm_threads.thr_pk AND '.$censored_condition.
'
241 AND ((frm_threads.thr_top_fk = frm_data.top_pk AND frm_data.top_frm_fk = frm_notification.frm_id)
242 OR (frm_threads.thr_pk = frm_notification.thread_id
243 AND frm_data.top_pk = frm_threads.thr_top_fk) )
244 AND (frm_posts.pos_display_user_id != frm_notification.user_id)
245 ORDER BY frm_posts.pos_date ASC',
253 $this->logger->info(
sprintf(
'Sending notifications for %s "censored posting" events ...', $numRows));
255 $this->logger->info(
sprintf(
'Sent notifications for new censored ...'));
261 $uncensored_condition =
'
262 frm_posts.pos_cens = %s AND frm_posts.pos_status = %s AND
263 (frm_posts.pos_cens_date >= %s AND frm_posts.pos_cens_date > frm_posts.pos_activation_date ) ';
264 $types = array(
'integer',
'integer',
'timestamp');
265 $values = array(0, 1, $threshold_date);
268 SELECT frm_threads.thr_subject thr_subject,
269 frm_data.top_name top_name,
270 frm_data.top_frm_fk obj_id,
271 frm_notification.user_id user_id,
272 frm_threads.thr_pk thread_id,
274 FROM frm_notification, frm_posts, frm_threads, frm_data
275 WHERE frm_posts.pos_thr_fk = frm_threads.thr_pk AND '.$uncensored_condition.
'
276 AND ((frm_threads.thr_top_fk = frm_data.top_pk AND frm_data.top_frm_fk = frm_notification.frm_id)
277 OR (frm_threads.thr_pk = frm_notification.thread_id
278 AND frm_data.top_pk = frm_threads.thr_top_fk) )
279 AND frm_posts.pos_display_user_id != frm_notification.user_id
280 ORDER BY frm_posts.pos_date ASC',
288 $this->logger->info(
sprintf(
'Sending notifications for %s "uncensored posting" events ...', $numRows));
290 $this->logger->info(
sprintf(
'Sent notifications for uncensored postings ...'));
296 $res = $ilDB->queryF(
'
297 SELECT frm_posts_deleted.thread_title thr_subject,
298 frm_posts_deleted.forum_title top_name,
299 frm_posts_deleted.obj_id obj_id,
300 frm_notification.user_id user_id,
301 frm_posts_deleted.pos_display_user_id,
302 frm_posts_deleted.pos_usr_alias,
303 frm_posts_deleted.deleted_id,
304 frm_posts_deleted.post_date pos_date,
305 frm_posts_deleted.post_title pos_subject,
306 frm_posts_deleted.post_message pos_message
308 FROM frm_notification, frm_posts_deleted
310 WHERE ( frm_posts_deleted.obj_id = frm_notification.frm_id
311 OR frm_posts_deleted.thread_id = frm_notification.thread_id)
312 AND frm_posts_deleted.pos_display_user_id != frm_notification.user_id
313 AND frm_posts_deleted.is_thread_deleted = %s
314 ORDER BY frm_posts_deleted.post_date ASC',
315 array(
'integer'), array(1));
319 $this->logger->info(
sprintf(
'Sending notifications for %s "deleted threads" events ...', $numRows));
321 if(count(self::$deleted_ids_cache) > 0)
323 $ilDB->manipulate(
'DELETE FROM frm_posts_deleted WHERE '.
$ilDB->in(
'deleted_id', self::$deleted_ids_cache,
false,
'integer'));
324 $this->logger->info(
'Deleted obsolete entries of table "frm_posts_deleted" ...');
326 $this->logger->info(
sprintf(
'Sent notifications for deleted threads ...'));
332 $res = $ilDB->queryF(
'
333 SELECT frm_posts_deleted.thread_title thr_subject,
334 frm_posts_deleted.forum_title top_name,
335 frm_posts_deleted.obj_id obj_id,
336 frm_notification.user_id user_id,
337 frm_posts_deleted.pos_display_user_id,
338 frm_posts_deleted.pos_usr_alias,
339 frm_posts_deleted.deleted_id,
340 frm_posts_deleted.post_date pos_date,
341 frm_posts_deleted.post_title pos_subject,
342 frm_posts_deleted.post_message pos_message
344 FROM frm_notification, frm_posts_deleted
346 WHERE ( frm_posts_deleted.obj_id = frm_notification.frm_id
347 OR frm_posts_deleted.thread_id = frm_notification.thread_id)
348 AND frm_posts_deleted.pos_display_user_id != frm_notification.user_id
349 AND frm_posts_deleted.is_thread_deleted = %s
350 ORDER BY frm_posts_deleted.post_date ASC',
351 array(
'integer'), array(0));
356 $this->logger->info(
sprintf(
'Sending notifications for %s "deleted postings" events ...', $numRows));
358 if(count(self::$deleted_ids_cache) > 0)
360 $ilDB->manipulate(
'DELETE FROM frm_posts_deleted WHERE '.
$ilDB->in(
'deleted_id', self::$deleted_ids_cache,
false,
'integer'));
361 $this->logger->info(
'Deleted entries from table "frm_posts_deleted" ...');
363 $this->logger->info(
sprintf(
'Sent notifications for deleted postings ...'));
366 $ilSetting->set(
'cron_forum_notification_last_date', $cj_start_date);
368 $mess =
'Sent '.$this->num_sent_messages.
' messages.';
370 $this->logger->info($mess);
371 $this->logger->info(
'Finished forum notification job');
374 if($this->num_sent_messages)
389 if(!array_key_exists($a_obj_id, self::$ref_ids_by_obj_id))
394 return (array)self::$ref_ids_by_obj_id[$a_obj_id];
402 protected function getFirstAccessibleRefIdBUserAndObjId($a_user_id, $a_obj_id)
409 if(!array_key_exists($a_user_id, self::$accessible_ref_ids_by_user))
411 self::$accessible_ref_ids_by_user[$a_user_id] = array();
414 if(!array_key_exists($a_obj_id, self::$accessible_ref_ids_by_user[$a_user_id]))
416 $accessible_ref_id = 0;
419 if($ilAccess->checkAccessOfUser($a_user_id,
'read',
'',
$ref_id))
425 self::$accessible_ref_ids_by_user[$a_user_id][$a_obj_id] = $accessible_ref_id;
428 return (
int)self::$accessible_ref_ids_by_user[$a_user_id][$a_obj_id];
435 public function sendCronForumNotification(
$res, $notification_type)
442 include_once
'./Modules/Forum/classes/class.ilForumCronNotificationDataProvider.php';
443 include_once
'./Modules/Forum/classes/class.ilForumMailNotification.php';
451 self::$deleted_ids_cache[
$row[
'deleted_id']] =
$row[
'deleted_id'];
454 $ref_id = $this->getFirstAccessibleRefIdBUserAndObjId(
$row[
'user_id'],
$row[
'obj_id']);
458 'The recipient with id %s has no "read" permission for object with id %s',
468 self::$providerObject[
$row[
'pos_pk']]->addRecipient(
$row[
'user_id']);
476 $usrIdsToPreload = array();
477 foreach (self::$providerObject as
$provider) {
482 $usrIdsToPreload[
$provider->getPosDisplayUserId()] =
$provider->getPosDisplayUserId();
485 $usrIdsToPreload[
$provider->getPostUpdateUserId()] =
$provider->getPostUpdateUserId();
489 require_once
'Modules/Forum/classes/class.ilForumAuthorInformationCache.php';
490 ilForumAuthorInformationCache::preloadUserObjects(array_unique($usrIdsToPreload));
493 foreach(self::$providerObject as
$provider)
495 if ($i > 0 && ($i % self::KEEP_ALIVE_CHUNK_SIZE) == 0) {
499 $recipients = array_unique(
$provider->getCronRecipients());
502 'Trying to send forum notifications for posting id "%s", type "%s" and recipients: %s',
503 $provider->getPostId(), $notification_type, implode(
', ', $recipients)
507 $mailNotification->setIsCronjob(
true);
508 $mailNotification->setType($notification_type);
509 $mailNotification->setRecipients($recipients);
511 $mailNotification->send();
513 $this->num_sent_messages += count(
$provider->getCronRecipients());
514 $this->logger->info(
sprintf(
"Sent notifications ... "));
528 if(isset(self::$providerObject[$post_id]))
542 self::$providerObject[
$row[
'pos_pk']] = $tmp_provider;
543 self::$providerObject[
$row[
'pos_pk']]->addRecipient(
$row[
'user_id']);
551 self::$providerObject = array();
569 $a_fields[
'cron_forum_notification'] = $a_is_active ?
570 $lng->txt(
'enabled') :
571 $lng->txt(
'disabled');
584 if((
bool)$a_currently_active)
604 $lng->loadLanguageModule(
'forum');
606 $max_notification_age =
new ilNumberInputGUI(
$lng->txt(
'frm_max_notification_age'),
'max_notification_age');
607 $max_notification_age->setSize(5);
608 $max_notification_age->setSuffix(
$lng->txt(
'frm_max_notification_age_unit'));
609 $max_notification_age->setRequired(
true);
610 $max_notification_age->allowDecimals(
false);
611 $max_notification_age->setMinValue(1);
612 $max_notification_age->setInfo(
$lng->txt(
'frm_max_notification_age_info'));
613 $max_notification_age->setValue($this->
settings->get(
'max_notification_age', 30));
615 $a_form->
addItem($max_notification_age);
624 $this->
settings->set(
'max_notification_age', $a_form->
getInput(
'max_notification_age'));
memory_get_usage(true)/1024/1024)
sprintf('%.4f', $callTime)
date( 'd-M-Y', $objPHPExcel->getProperties() ->getCreated())
An exception for terminatinating execution or to throw for unit testing.
Cron job result data container.
Cron job application base class.
addToExternalSettingsForm($a_form_id, array &$a_fields, $a_is_active)
Add external settings to form.
const SCHEDULE_TYPE_IN_HOURS
addCustomSettingsToForm(ilPropertyFormGUI $a_form)
Add custom settings to form.
static ping($a_job_id)
Keep cron job alive.
Class ilForumCronNotificationDataProvider.
getDefaultScheduleType()
Get schedule type.
activationWasToggled($a_currently_active)
getDescription()
Get description.
const KEEP_ALIVE_CHUNK_SIZE
saveCustomSettings(ilPropertyFormGUI $a_form)
static $ref_ids_by_obj_id
getDefaultScheduleValue()
Get schedule value.
getRefIdsByObjId($a_obj_id)
static $accessible_ref_ids_by_user
hasAutoActivation()
Is to be activated on "installation".
hasFlexibleSchedule()
Can the schedule be configured?
existsProviderObject($post_id)
static $deleted_ids_cache
const TYPE_POST_UNCENSORED
const TYPE_THREAD_DELETED
static _getAllReferences($a_id)
get all reference ids of object
$GLOBALS['loaded']
Global hash that tracks already loaded includes.