ILIAS  release_5-1 Revision 5.0.0-5477-g43f3e3fab5f
class.ilForumCronNotification.php
Go to the documentation of this file.
1<?php
2/* Copyright (c) 1998-2009 ILIAS open source, Extended GPL, see docs/LICENSE */
3
4include_once "Services/Cron/classes/class.ilCronJob.php";
5include_once "./Modules/Forum/classes/class.ilForumMailNotification.php";
6
14{
16
20 protected $settings;
21
25 public static $providerObject = array();
26
30 protected static $deleted_ids_cache = array();
31
35 protected static $ref_ids_by_obj_id = array();
36
40 protected static $accessible_ref_ids_by_user = array();
41
45 protected $num_sent_messages = 0;
46
50 public function __construct()
51 {
52 $this->settings = new ilSetting('frma');
53 }
54
55 public function getId()
56 {
57 return "frm_notification";
58 }
59
60 public function getTitle()
61 {
62 global $lng;
63
64 return $lng->txt("cron_forum_notification");
65 }
66
67 public function getDescription()
68 {
69 global $lng;
70
71 return $lng->txt("cron_forum_notification_crob_desc");
72 }
73
74 public function getDefaultScheduleType()
75 {
77 }
78
79 public function getDefaultScheduleValue()
80 {
81 return 1;
82 }
83
84 public function hasAutoActivation()
85 {
86 return false;
87 }
88
89 public function hasFlexibleSchedule()
90 {
91 return true;
92 }
93
97 public function hasCustomSettings()
98 {
99 return true;
100 }
101
105 public function keepAlive()
106 {
107 \ilCronManager::ping($this->getId());
108 }
109
113 public function run()
114 {
115 global $ilDB, $ilLog, $ilSetting, $lng;
116
118
119 $lng->loadLanguageModule('forum');
120
121 if(!($last_run_datetime = $ilSetting->get('cron_forum_notification_last_date')))
122 {
123 $last_run_datetime = null;
124 }
125
126 $this->num_sent_messages = 0;
127 $cj_start_date = date('Y-m-d H:i:s');
128
129 if($last_run_datetime != null &&
130 checkDate(date('m', strtotime($last_run_datetime)), date('d', strtotime($last_run_datetime)), date('Y', strtotime($last_run_datetime))))
131 {
132 $threshold = max(strtotime($last_run_datetime), strtotime('-' . (int)$this->settings->get('max_notification_age', 30) . ' days', time()));
133 }
134 else
135 {
136 $threshold = strtotime('-' . (int)$this->settings->get('max_notification_age', 30) . ' days', time());
137 }
138
139 $threshold_date = date('Y-m-d H:i:s', $threshold);
140 $new_posts_condition = '
141 frm_posts.pos_status = %s AND (
142 (frm_posts.pos_date >= %s AND frm_posts.pos_date = frm_posts.pos_activation_date) OR
143 (frm_posts.pos_activation_date >= %s AND frm_posts.pos_date < frm_posts.pos_activation_date)
144 ) ';
145 $types = array('integer', 'timestamp', 'timestamp');
146 $values = array(1, $threshold_date, $threshold_date);
147
148 /*** new posts ***/
149 $res = $ilDB->queryf('
150 SELECT frm_threads.thr_subject thr_subject,
151 frm_data.top_name top_name,
152 frm_data.top_frm_fk obj_id,
153 frm_notification.user_id user_id,
154 frm_threads.thr_pk thread_id,
155 frm_posts.*
156 FROM frm_notification, frm_posts, frm_threads, frm_data
157 WHERE frm_posts.pos_thr_fk = frm_threads.thr_pk AND '.$new_posts_condition.'
158 AND ((frm_threads.thr_top_fk = frm_data.top_pk AND frm_data.top_frm_fk = frm_notification.frm_id)
159 OR (frm_threads.thr_pk = frm_notification.thread_id
160 AND frm_data.top_pk = frm_threads.thr_top_fk) )
161 AND frm_posts.pos_display_user_id != frm_notification.user_id
162 ORDER BY frm_posts.pos_date ASC',
163 $types,
164 $values
165 );
166
167 $numRows = $ilDB->numRows($res);
168 if($numRows > 0)
169 {
170 $this->sendCronForumNotification($res, ilForumMailNotification::TYPE_POST_NEW);
171 }
172
173 $this->keepAlive();
174
175 /*** updated posts ***/
176 $updated_condition = '
177 frm_posts.pos_cens = %s AND frm_posts.pos_status = %s AND
178 (frm_posts.pos_update > frm_posts.pos_date AND frm_posts.pos_update >= %s ) ';
179 $types = array('integer', 'integer', 'timestamp');
180 $values = array(0, 1, $threshold_date);
181
182 $res = $ilDB->queryf('
183 SELECT frm_threads.thr_subject thr_subject,
184 frm_data.top_name top_name,
185 frm_data.top_frm_fk obj_id,
186 frm_notification.user_id user_id,
187 frm_threads.thr_pk thread_id,
188 frm_posts.*
189 FROM frm_notification, frm_posts, frm_threads, frm_data
190 WHERE frm_posts.pos_thr_fk = frm_threads.thr_pk AND '.$updated_condition.'
191 AND ((frm_threads.thr_top_fk = frm_data.top_pk AND frm_data.top_frm_fk = frm_notification.frm_id)
192 OR (frm_threads.thr_pk = frm_notification.thread_id
193 AND frm_data.top_pk = frm_threads.thr_top_fk) )
194 AND frm_posts.pos_display_user_id != frm_notification.user_id
195 ORDER BY frm_posts.pos_date ASC',
196 $types,
197 $values
198 );
199
200 $numRows = $ilDB->numRows($res);
201 if($numRows > 0)
202 {
203 $this->sendCronForumNotification($res, ilForumMailNotification::TYPE_POST_UPDATED);
204 }
205
206 /*** censored posts ***/
207 $censored_condition = '
208 frm_posts.pos_cens = %s AND frm_posts.pos_status = %s AND
209 (frm_posts.pos_cens_date >= %s AND frm_posts.pos_cens_date > frm_posts.pos_activation_date ) ';
210 $types = array('integer', 'integer', 'timestamp');
211 $values = array(1, 1, $threshold_date );
212
213 $res = $ilDB->queryf('
214 SELECT frm_threads.thr_subject thr_subject,
215 frm_data.top_name top_name,
216 frm_data.top_frm_fk obj_id,
217 frm_notification.user_id user_id,
218 frm_threads.thr_pk thread_id,
219 frm_posts.*
220 FROM frm_notification, frm_posts, frm_threads, frm_data
221 WHERE frm_posts.pos_thr_fk = frm_threads.thr_pk AND '.$censored_condition.'
222 AND ((frm_threads.thr_top_fk = frm_data.top_pk AND frm_data.top_frm_fk = frm_notification.frm_id)
223 OR (frm_threads.thr_pk = frm_notification.thread_id
224 AND frm_data.top_pk = frm_threads.thr_top_fk) )
225 AND (frm_posts.pos_display_user_id != frm_notification.user_id)
226 ORDER BY frm_posts.pos_date ASC',
227 $types,
228 $values
229 );
230
231 $numRows = $ilDB->numRows($res);
232 if($numRows > 0)
233 {
234 $this->sendCronForumNotification($res, ilForumMailNotification::TYPE_POST_CENSORED);
235 }
236
237 $this->keepAlive();
238
239 /*** uncensored posts ***/
240 $uncensored_condition = '
241 frm_posts.pos_cens = %s AND frm_posts.pos_status = %s AND
242 ( frm_posts.pos_cens_date >= %s AND frm_posts.pos_cens_date > frm_posts.pos_activation_date )';
243 $types = array('integer', 'integer', 'timestamp');
244 $values = array(0, 1, $threshold_date);
245
246 $res = $ilDB->queryf('
247 SELECT frm_threads.thr_subject thr_subject,
248 frm_data.top_name top_name,
249 frm_data.top_frm_fk obj_id,
250 frm_notification.user_id user_id,
251 frm_threads.thr_pk thread_id,
252 frm_posts.*
253 FROM frm_notification, frm_posts, frm_threads, frm_data
254 WHERE frm_posts.pos_thr_fk = frm_threads.thr_pk AND '.$uncensored_condition.'
255 AND ((frm_threads.thr_top_fk = frm_data.top_pk AND frm_data.top_frm_fk = frm_notification.frm_id)
256 OR (frm_threads.thr_pk = frm_notification.thread_id
257 AND frm_data.top_pk = frm_threads.thr_top_fk) )
258 AND frm_posts.pos_display_user_id != frm_notification.user_id
259 ORDER BY frm_posts.pos_date ASC',
260 $types,
261 $values
262 );
263
264 $numRows = $ilDB->numRows($res);
265 if($numRows > 0)
266 {
267 $this->sendCronForumNotification($res, ilForumMailNotification::TYPE_POST_UNCENSORED);
268 }
269
270 $this->keepAlive();
271
272 /*** deleted threads ***/
273 $res = $ilDB->queryF('
274 SELECT frm_posts_deleted.thread_title thr_subject,
275 frm_posts_deleted.forum_title top_name,
276 frm_posts_deleted.obj_id obj_id,
277 frm_notification.user_id user_id,
278 frm_posts_deleted.pos_display_user_id,
279 frm_posts_deleted.pos_usr_alias,
280 frm_posts_deleted.deleted_id,
281 frm_posts_deleted.post_date pos_date,
282 frm_posts_deleted.post_title pos_subject,
283 frm_posts_deleted.post_message pos_message
284
285 FROM frm_notification, frm_posts_deleted
286
287 WHERE ( frm_posts_deleted.obj_id = frm_notification.frm_id
288 OR frm_posts_deleted.thread_id = frm_notification.thread_id)
289 AND frm_posts_deleted.pos_display_user_id != frm_notification.user_id
290 AND frm_posts_deleted.is_thread_deleted = %s
291 ORDER BY frm_posts_deleted.post_date ASC',
292 array('integer'), array(1));
293 $numRows = $ilDB->numRows($res);
294 if($numRows > 0)
295 {
296 $this->sendCronForumNotification($res, ilForumMailNotification::TYPE_THREAD_DELETED);
297 if(count(self::$deleted_ids_cache) > 0)
298 {
299 $ilDB->manipulate('DELETE FROM frm_posts_deleted WHERE '. $ilDB->in('deleted_id', self::$deleted_ids_cache, false, 'integer'));
300 $ilLog->write(__METHOD__ . ':DELETED ENTRIES: frm_posts_deleted');
301 }
302 }
303
304 $this->keepAlive();
305
306 /*** deleted posts ***/
307 $res = $ilDB->queryF('
308 SELECT frm_posts_deleted.thread_title thr_subject,
309 frm_posts_deleted.forum_title top_name,
310 frm_posts_deleted.obj_id obj_id,
311 frm_notification.user_id user_id,
312 frm_posts_deleted.pos_display_user_id,
313 frm_posts_deleted.pos_usr_alias,
314 frm_posts_deleted.deleted_id,
315 frm_posts_deleted.post_date pos_date,
316 frm_posts_deleted.post_title pos_subject,
317 frm_posts_deleted.post_message pos_message
318
319 FROM frm_notification, frm_posts_deleted
320
321 WHERE ( frm_posts_deleted.obj_id = frm_notification.frm_id
322 OR frm_posts_deleted.thread_id = frm_notification.thread_id)
323 AND frm_posts_deleted.pos_display_user_id != frm_notification.user_id
324 AND frm_posts_deleted.is_thread_deleted = %s
325 ORDER BY frm_posts_deleted.post_date ASC',
326 array('integer'), array(0));
327
328 $numRows = $ilDB->numRows($res);
329 if($numRows > 0)
330 {
331 $this->sendCronForumNotification($res, ilForumMailNotification::TYPE_POST_DELETED);
332 if(count(self::$deleted_ids_cache) > 0)
333 {
334 $ilDB->manipulate('DELETE FROM frm_posts_deleted WHERE '. $ilDB->in('deleted_id', self::$deleted_ids_cache, false, 'integer'));
335 $ilLog->write(__METHOD__ . ':DELETED ENTRIES: frm_posts_deleted');
336 }
337 }
338
339 $ilSetting->set('cron_forum_notification_last_date', $cj_start_date);
340
341 $mess = 'Sent '.$this->num_sent_messages.' messages.';
342 $ilLog->write(__METHOD__.': '.$mess);
343
344 $result = new ilCronJobResult();
345 if($this->num_sent_messages)
346 {
348 $result->setMessage($mess);
349 };
350 $result->setStatus($status);
351 return $result;
352 }
353
358 protected function getRefIdsByObjId($a_obj_id)
359 {
360 if(!array_key_exists($a_obj_id, self::$ref_ids_by_obj_id))
361 {
362 self::$ref_ids_by_obj_id[$a_obj_id] = ilObject::_getAllReferences($a_obj_id);
363 }
364
365 return (array)self::$ref_ids_by_obj_id[$a_obj_id];
366 }
367
373 protected function getFirstAccessibleRefIdBUserAndObjId($a_user_id, $a_obj_id)
374 {
378 global $ilAccess;
379
380 if(!array_key_exists($a_user_id, self::$accessible_ref_ids_by_user))
381 {
382 self::$accessible_ref_ids_by_user[$a_user_id] = array();
383 }
384
385 if(!array_key_exists($a_obj_id, self::$accessible_ref_ids_by_user[$a_user_id]))
386 {
387 $accessible_ref_id = 0;
388 foreach($this->getRefIdsByObjId($a_obj_id) as $ref_id)
389 {
390 if($ilAccess->checkAccessOfUser($a_user_id, 'read', '', $ref_id))
391 {
392 $accessible_ref_id = $ref_id;
393 break;
394 }
395 }
396 self::$accessible_ref_ids_by_user[$a_user_id][$a_obj_id] = $accessible_ref_id;
397 }
398
399 return (int)self::$accessible_ref_ids_by_user[$a_user_id][$a_obj_id];
400 }
401
406 public function sendCronForumNotification($res, $notification_type)
407 {
412 global $ilDB, $ilLog;
413
414 include_once './Modules/Forum/classes/class.ilForumCronNotificationDataProvider.php';
415 include_once './Modules/Forum/classes/class.ilForumMailNotification.php';
416
417 while($row = $ilDB->fetchAssoc($res))
418 {
419 if($notification_type == ilForumMailNotification::TYPE_POST_DELETED
420 || $notification_type == ilForumMailNotification::TYPE_THREAD_DELETED)
421 {
422 // important! save the deleted_id to cache before proceeding getFirstAccessibleRefIdBUserAndObjId !
423 self::$deleted_ids_cache[$row['deleted_id']] = $row['deleted_id'];
424 }
425
426 $ref_id = $this->getFirstAccessibleRefIdBUserAndObjId($row['user_id'], $row['obj_id']);
427 if($ref_id < 1)
428 {
429 $ilLog->write(__METHOD__.': User-Id: '.$row['user_id'].' has no read permission for object id: '.$row['obj_id']);
430 continue;
431 }
432
433 $row['ref_id'] = $ref_id;
434
435 if($this->existsProviderObject($row['pos_pk']))
436 {
437 self::$providerObject[$row['pos_pk']]->addRecipient($row['user_id']);
438 }
439 else
440 {
441 $this->addProviderObject($row);
442 }
443 }
444
445 $i = 0;
446 foreach(self::$providerObject as $provider)
447 {
448 $mailNotification = new ilForumMailNotification($provider);
449 $mailNotification->setIsCronjob(true);
450 $mailNotification->setType($notification_type);
451 $mailNotification->setRecipients(array_unique($provider->getCronRecipients()));
452
453 $mailNotification->send();
454
455 if ($i > 0 && ($i % self::KEEP_ALIVE_CHUNK_SIZE) == 0) {
456 $this->keepAlive();
457 }
458
459 $this->num_sent_messages += count($provider->getCronRecipients());
460 $ilLog->write(__METHOD__.':SUCCESSFULLY SEND: NotificationType: '.$notification_type.' -> Recipients: '. implode(', ',$provider->getCronRecipients()));
461
462 ++$i;
463 }
464
465 $this->resetProviderCache();
466 }
467
472 public function existsProviderObject($post_id)
473 {
474 if(isset(self::$providerObject[$post_id]))
475 {
476 return true;
477 }
478 return false;
479 }
480
484 private function addProviderObject($row)
485 {
486 $tmp_provider = new ilForumCronNotificationDataProvider($row);
487
488 self::$providerObject[$row['pos_pk']] = $tmp_provider;
489 self::$providerObject[$row['pos_pk']]->addRecipient($row['user_id']);
490 }
491
495 private function resetProviderCache()
496 {
497 self::$providerObject = array();
498 }
499
505 public function addToExternalSettingsForm($a_form_id, array &$a_fields, $a_is_active)
506 {
510 global $lng;
511
512 switch($a_form_id)
513 {
515 $a_fields['cron_forum_notification'] = $a_is_active ?
516 $lng->txt('enabled') :
517 $lng->txt('disabled');
518 break;
519 }
520 }
521
525 public function activationWasToggled($a_currently_active)
526 {
527 global $ilSetting;
528
529 // propagate cron-job setting to object setting
530 if((bool)$a_currently_active)
531 {
532 $ilSetting->set('forum_notification', 2);
533 }
534 else
535 {
536 $ilSetting->set('forum_notification', 1);
537 }
538 }
539
543 public function addCustomSettingsToForm(ilPropertyFormGUI $a_form)
544 {
548 global $lng;
549
550 $lng->loadLanguageModule('forum');
551
552 $max_notification_age = new ilNumberInputGUI($lng->txt('frm_max_notification_age'), 'max_notification_age');
553 $max_notification_age->setSize(5);
554 $max_notification_age->setSuffix($lng->txt('frm_max_notification_age_unit'));
555 $max_notification_age->setRequired(true);
556 $max_notification_age->allowDecimals(false);
557 $max_notification_age->setMinValue(1);
558 $max_notification_age->setInfo($lng->txt('frm_max_notification_age_info'));
559 $max_notification_age->setValue($this->settings->get('max_notification_age', 30));
560
561 $a_form->addItem($max_notification_age);
562 }
563
568 public function saveCustomSettings(ilPropertyFormGUI $a_form)
569 {
570 $this->settings->set('max_notification_age', $a_form->getInput('max_notification_age'));
571 return true;
572 }
573}
$result
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.
saveCustomSettings(ilPropertyFormGUI $a_form)
getDefaultScheduleValue()
Get schedule value.
hasAutoActivation()
Is to be activated on "installation".
hasFlexibleSchedule()
Can the schedule be configured?
This class represents a number property in a property form.
static _getAllReferences($a_id)
get all reference ids of object
This class represents a property form user interface.
addItem($a_item)
Add Item (Property, SectionHeader).
getInput($a_post_var, $ensureValidation=true)
Returns the value of a HTTP-POST variable, identified by the passed id.
ILIAS Setting Class.
global $lng
Definition: privfeed.php:40
global $ilSetting
Definition: privfeed.php:40
$ref_id
Definition: sahs_server.php:39
global $ilDB