ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
class.ilExAssignmentReminder.php
Go to the documentation of this file.
1<?php
2/* Copyright (c) 1998-2018 ILIAS open source, Extended GPL, see docs/LICENSE */
3
15{
16 const SUBMIT_REMINDER = "submit";
17 const GRADE_REMINDER = "grade";
18 const FEEDBACK_REMINDER = "peer";
19
20 protected $db;
21 protected $tree;
22 protected $now;
23
24 protected $rmd_status;
25 protected $rmd_start;
26 protected $rmd_end;
27 protected $rmd_frequency;
28 protected $rmd_last_send;
29 protected $rmd_tpl_id;
30
31 protected $ass_id;
32 protected $exc_id;
33 protected $rmd_type;
34
35 protected $log;
36
37 //todo remove the params as soon as possible.
38 public function __construct($a_exc_id = "", $a_ass_id = "", $a_type = "")
39 {
40 global $DIC;
41 $this->db = $DIC->database();
42 $this->tree = $DIC->repositoryTree();
43 $this->access = $DIC->access();
44 $this->log = ilLoggerFactory::getLogger("exc");
45
46 if ($a_ass_id) {
47 $this->ass_id = $a_ass_id;
48 }
49 if ($a_exc_id) {
50 $this->exc_id = $a_exc_id;
51 }
52 if ($a_type) {
53 $this->rmd_type = $a_type;
54 }
55 if ($a_exc_id and $a_ass_id and $a_type) {
56 $this->read();
57 }
58 }
59
60 public function getReminderType()
61 {
62 return $this->rmd_type;
63 }
64
69 public function setReminderStatus($a_status)
70 {
71 $this->rmd_status = $a_status;
72 }
73
78 public function getReminderStatus()
79 {
80 return $this->rmd_status;
81 }
82
87 public function setReminderStart($a_num_days)
88 {
89 $this->rmd_start = $a_num_days;
90 }
91
96 public function getReminderStart()
97 {
98 return $this->rmd_start;
99 }
100
105 public function setReminderEnd($a_date)
106 {
107 $this->rmd_end = $a_date;
108 }
109
114 public function getReminderEnd()
115 {
116 return $this->rmd_end;
117 }
118
123 public function setReminderFrequency($a_num_days)
124 {
125 $this->rmd_frequency = $a_num_days;
126 }
127
132 public function getReminderFrequency()
133 {
135 }
136
137 public function setReminderLastSend($a_timestamp)
138 {
139 $this->rmd_last_send = $a_timestamp;
140 }
141
142 public function getReminderLastSend()
143 {
145 }
146
147 public function setReminderMailTemplate($a_tpl_id)
148 {
149 $this->rmd_tpl_id = $a_tpl_id;
150 }
151
152 public function getReminderMailTemplate()
153 {
154 return $this->rmd_tpl_id;
155 }
156
157 public function save()
158 {
159 $this->db->insert("exc_ass_reminders", array(
160 "type" => array("text", $this->rmd_type),
161 "ass_id" => array("integer", $this->ass_id),
162 "exc_id" => array("integer", $this->exc_id),
163 "status" => array("integer", $this->getReminderStatus()),
164 "start" => array("integer", $this->getReminderStart()),
165 "end" => array("integer", $this->getReminderEnd()),
166 "freq" => array("integer", $this->getReminderFrequency()),
167 "last_send" => array("integer", $this->getReminderLastSend()),
168 "template_id" => array("integer", $this->getReminderMailTemplate())
169 ));
170 }
171
172 public function update()
173 {
174 $this->db->update(
175 "exc_ass_reminders",
176 array(
177 "status" => array("integer", $this->getReminderStatus()),
178 "start" => array("integer", $this->getReminderStart()),
179 "end" => array("integer", $this->getReminderEnd()),
180 "freq" => array("integer", $this->getReminderFrequency()),
181 "last_send" => array("integer", $this->getReminderLastSend()),
182 "template_id" => array("integer", $this->getReminderMailTemplate())
183 ),
184 array(
185 "type" => array("text", $this->rmd_type),
186 "exc_id" => array("integer", $this->exc_id),
187 "ass_id" => array("integer", $this->ass_id)
188 )
189 );
190 }
191
192
193 public function read()
194 {
195 $set = $this->db->query("SELECT status, start, freq, end, last_send, template_id" .
196 " FROM exc_ass_reminders" .
197 " WHERE type ='" . $this->rmd_type . "'" .
198 " AND ass_id = " . $this->ass_id .
199 " AND exc_id = " . $this->exc_id);
200
201 $rec = $this->db->fetchAssoc($set);
202 if (is_array($rec)) {
203 $this->initFromDB($rec);
204 }
205 }
206
211 protected function initFromDB(array $a_set)
212 {
213 $this->setReminderStatus($a_set["status"]);
214 $this->setReminderStart($a_set["start"]);
215 $this->setReminderEnd($a_set["end"]);
216 $this->setReminderFrequency($a_set["freq"]);
217 $this->setReminderLastSend($a_set["last_send"]);
218 $this->setReminderMailTemplate($a_set["template_id"]);
219 }
220
221
222 // Specific Methods to be used via Cron Job.
228 public function getReminders($a_type = "")
229 {
230 $now = time();
231 $today = date("Y-m-d");
232
233 $this->log->debug("Get reminders $a_type.");
234
235 //remove time from the timestamp (86400 = 24h)
236 //$now = floor($now/86400)*86400;
237 $and_type = "";
238 if ($a_type == self::SUBMIT_REMINDER || $a_type == self::GRADE_REMINDER || $a_type == self::FEEDBACK_REMINDER) {
239 $and_type = " AND type = '" . $a_type . "'";
240 }
241
242 $query = "SELECT last_send_day, ass_id, exc_id, status, start, freq, end, type, last_send, template_id" .
243 " FROM exc_ass_reminders" .
244 " WHERE status = 1" .
245 " AND start <= " . $now .
246 " AND end > " . ($now - 86400) .
247 $and_type;
248
249
250 $result = $this->db->query($query);
251
252 $array_data = array();
253 while ($rec = $this->db->fetchAssoc($result)) {
254 $rem = array(
255 "ass_id" => $rec["ass_id"],
256 "exc_id" => $rec["exc_id"],
257 "start" => $rec["start"],
258 "end" => $rec["end"],
259 "freq" => $rec["freq"],
260 "type" => $rec["type"],
261 "last_send" => $rec["last_send"],
262 "last_send_day" => $rec["last_send_day"],
263 "template_id" => $rec["template_id"]
264 );
265
266 $end_day = date("Y-m-d", $rec["end"]);
267
268 //frequency
269 $next_send = "";
270 if ($rec["last_send_day"] != "") {
271 $date = new DateTime($rec["last_send_day"]);
272 $date->add(new DateInterval('P' . $rec["freq"] . 'D'));
273 $next_send = $date->format('Y-m-d');
274 }
275 $this->log->debug("ass: " . $rec["ass_id"] . ", last send: " . $rec["last_send_day"] .
276 ", freq: " . $rec["freq"] . ", end_day: $end_day, today: " . $today . ", next send: $next_send");
277 if ($rec["last_send_day"] == "" || $next_send <= $today) {
278 if ($end_day >= $today) {
279 $this->log->debug("included");
280 array_push($array_data, $rem);
281 }
282 }
283 }
284
285 return $array_data;
286 }
287
288
294 public function parseSubmissionReminders($a_reminders)
295 {
296 $reminders = $a_reminders;
297 $users_to_remind = array();
298
299 foreach ($reminders as $rem) {
300 $ass_id = $rem["ass_id"];
301 $ass_obj = new ilExAssignment($ass_id);
302
303 $exc_id = $rem["exc_id"];
304
306 foreach ($exc_refs as $exc_ref) {
307
308 // check if we have an upper course
309 if ($course_ref_id = $this->tree->checkForParentType($exc_ref, 'crs')) {
310 $obj = new ilObjCourse($course_ref_id);
311 $participants_class = "ilCourseParticipants";
312 $parent_ref_id = $course_ref_id;
313 $parent_obj_type = 'crs';
314
315 // check if we have an upper group
316 } elseif ($group_ref_id = $parent_ref_id = $this->tree->checkForParentType($exc_ref, 'grp')) {
317 $obj = new ilObjGroup($group_ref_id);
318 $participants_class = "ilGroupParticipants";
319 $parent_ref_id = $group_ref_id;
320 $parent_obj_type = 'grp';
321 } else {
322 continue;
323 }
324
325 // get participants
326 $parent_obj_id = $obj->getId();
327 $participants_ids = $participants_class::getInstance($parent_ref_id)->getMembers();
328
329 foreach ($participants_ids as $member_id) {
330 $this->log->debug("submission reminder: ass: $ass_id, member: $member_id.");
331
332 // check read permission
333 if ($this->access->checkAccessOfUser($member_id, "read", "", $exc_ref)) {
335
336 $deadline_day = date("Y-m-d", $state->getOfficialDeadline());
337 $today = date("Y-m-d");
338 $date = new DateTime($deadline_day);
339 $date->sub(new DateInterval('P' . $rem["start"] . 'D'));
340 $send_from = $date->format('Y-m-d');
341 $this->log->debug("today: $today, send from: $send_from, start: " . $rem["start"] . ", submission allowed: " . $state->isSubmissionAllowed());
342
343 // check if user can submit and difference in days is smaller than reminder start
344 if ($state->isSubmissionAllowed() && $send_from <= $today) {
345 $submission = new ilExSubmission($ass_obj, $member_id);
346
347 // check if user has submitted anything
348 if (!$submission->getLastSubmission()) {
349 $member_data = array(
350 "parent_type" => $parent_obj_type,
351 "parent_id" => $parent_obj_id,
352 "exc_id" => $exc_id,
353 "exc_ref" => $exc_ref,
354 "ass_id" => $ass_id,
355 "member_id" => $member_id,
356 "reminder_type" => $rem["type"],
357 "template_id" => $rem["template_id"]
358 );
359 array_push($users_to_remind, $member_data);
360 }
361 }
362 }
363 }
364 }
365 }
366 return $users_to_remind;
367 }
368
369 public function parseGradeReminders($a_reminders)
370 {
371 $reminders = $a_reminders;
372 $users_to_remind = array();
373
374 $has_pending_to_grade = false;
375
376 foreach ($reminders as $rem) {
377 //$this->log->debug("---- parse grade reminder with values -> ",$rem);
378 $ass_obj = new ilExAssignment($rem["ass_id"]);
379 $members_data = $ass_obj->getMemberListData();
380
381 //$this->log->debug("--- get members list data => ",$members_data);
382 foreach ($members_data as $member_id => $assignment_data) {
383 if ($assignment_data["status"] == ilExerciseManagementGUI::GRADE_NOT_GRADED) {
384 //at least there is one submission pending to grade.
385 $has_pending_to_grade = true;
386 continue;
387 }
388 }
389
390 /* //DEBUG
391 if($has_pending_to_grade){
392 $this->log->debug("SOMEONE HAS TO BE GRADED");
393 } else {
394 $this->log->debug("There is nothing to Grade");
395 }
396 */
397
398 if ($has_pending_to_grade) {
399 //get tutor of this exercise.
400 include_once "./Services/Notification/classes/class.ilNotification.php";
401
403
404 foreach ($users as $user_id) {
405 $exc_refs = ilObject::_getAllReferences($rem["exc_id"]);
406 $unike_usr_id = array();
407 foreach ($exc_refs as $exc_ref) {
408 if ($this->access->checkAccessOfUser($user_id, "write", "", $exc_ref)) {
409 if (!in_array($user_id, $unike_usr_id)) {
410 $member_data = array(
411 "exc_id" => $rem["exc_id"],
412 "exc_ref" => $exc_ref,
413 "ass_id" => $rem["ass_id"],
414 "member_id" => $user_id,
415 "reminder_type" => $rem["type"],
416 "template_id" => $rem["template_id"]
417 );
418 array_push($users_to_remind, $member_data);
419 array_push($unike_usr_id, $user_id);
420 }
421 }
422 }
423 }
424 }
425 }
426
427 return $users_to_remind;
428 }
429
430 public function parsePeerReminders($a_reminders)
431 {
432 $reminders = $a_reminders;
433 $users_to_remind = array();
434
435 foreach ($reminders as $reminder) {
436 $giver_ids = array_unique(ilExPeerReview::lookupGiversWithPendingFeedback($reminder["ass_id"]));
437 foreach ($giver_ids as $giver_id) {
438 $state = ilExcAssMemberState::getInstanceByIds($reminder["ass_id"], $giver_id);
439 $days_diff = (($state->getPeerReviewDeadline() - time()) / (60 * 60 * 24));
440
441 if ($state->isPeerReviewAllowed() && $days_diff < $reminder["start"]) {
442 $exc_refs = ilObject::_getAllReferences($reminder["exc_id"]);
443 foreach ($exc_refs as $exc_ref) {
444 if ($this->access->checkAccessOfUser($giver_id, "read", "", $exc_ref)) {
445 $member_data = array(
446 "exc_id" => $reminder["exc_id"],
447 "exc_ref" => $exc_ref,
448 "ass_id" => $reminder["ass_id"],
449 "member_id" => $giver_id,
450 "reminder_type" => $reminder["type"],
451 "template_id" => $reminder["template_id"]
452 );
453 array_push($users_to_remind, $member_data);
454 }
455 }
456 }
457 }
458 }
459
460 return $users_to_remind;
461 }
462
466 public function checkReminders()
467 {
468 $submit_reminders = $this->getReminders(self::SUBMIT_REMINDER);
469 $parsed_submit_reminders = $this->parseSubmissionReminders($submit_reminders);
470
471 $grade_reminders = $this->getReminders(self::GRADE_REMINDER);
472 $parsed_grade_reminders = $this->parseGradeReminders($grade_reminders);
473
474 $peer_reminders = $this->getReminders(self::FEEDBACK_REMINDER);
475 $parsed_peer_reminders = $this->parsePeerReminders($peer_reminders);
476
477 /* //DEBUG
478 $this->log->debug("ALL SUBMIT REMINDERS");
479 $this->log->dump($submit_reminders);
480 $this->log->debug("PARSED SUBMIT REMINDERS");
481 $this->log->dump($parsed_submit_reminders);
482 $this->log->debug("GRADE REMINDERS ARRAY");
483 $this->log->dump($grade_reminders);
484 $this->log->debug("PARSED GRADE REMINDERS");
485 $this->log->dump($parsed_grade_reminders);
486 $this->log->debug("PEER REMINDERS ARRAY");
487 $this->log->dump($peer_reminders);
488 $this->log->debug("PARSED PEER REMINDERS");
489 $this->log->dump($parsed_peer_reminders);
490 */
491
492 $reminders = array_merge($parsed_submit_reminders, $parsed_grade_reminders, $parsed_peer_reminders);
493
494 $reminders_sent = $this->sendReminders($reminders);
495
496 return $reminders_sent;
497 }
498
503 protected function sendReminders($reminders)
504 {
505 global $DIC;
506
507 $tpl = null;
508
509 foreach ($reminders as $reminder) {
510 $template_id = $reminder['template_id'];
511
512 $rmd_type = $reminder["reminder_type"];
513 $this->log->debug("Sending reminder type = " . $rmd_type);
514
515 //if the template exists (can be deleted via Administration/Mail)
516 if ($template_id) {
518 $templateService = $DIC['mail.texttemplates.service'];
519 $tpl = $templateService->loadTemplateForId((int) $template_id);
520 }
521
522 if ($tpl) {
523 $this->log->debug("** send reminder WITH template.");
524 $subject = $tpl->getSubject();
525
526 $placeholder_params = array(
527 "exc_id" => $reminder["exc_id"],
528 "exc_ref" => $reminder["exc_ref"],
529 "ass_id" => $reminder["ass_id"],
530 "member_id" => $reminder["member_id"]
531 );
532 $message = $this->sentReminderPlaceholders($tpl->getMessage(), $placeholder_params, $rmd_type);
533 } else {
534 $this->log->debug("** send reminder WITHOUT template.");
535
536 $ass_title = ilExAssignment::lookupTitle($reminder["ass_id"]);
537 $exc_title = ilObjExercise::_lookupTitle($reminder["exc_id"]);
538
539 // use language of recipient to compose message
540 include_once "./Services/Language/classes/class.ilLanguageFactory.php";
541 $ulng = ilLanguageFactory::_getLanguageOfUser($reminder["member_id"]);
542 $ulng->loadLanguageModule('exc');
543
544 $link = ilLink::_getLink($reminder["exc_ref"], "exc", array(), "_" . $reminder["ass_id"]);
545
546 $message = sprintf($ulng->txt('exc_reminder_salutation'), ilObjUser::_lookupFullname($reminder["member_id"])) . "\n\n";
547
548 $this->log->debug("send: MAIL TYPE = " . $rmd_type . ", user: " . $reminder["member_id"] . ", ass: " . $reminder["ass_id"]);
549
550 switch ($rmd_type) {
551 case "submit":
552 $subject = sprintf($ulng->txt('exc_reminder_submit_subject'), $ass_title);
553 $message .= $ulng->txt('exc_reminder_submit_body') . ":\n\n";
554 break;
555
556 case "grade":
557 $subject = sprintf($ulng->txt('exc_reminder_grade_subject'), $ass_title);
558 $message .= $ulng->txt('exc_reminder_grade_body') . ":\n\n";
559 break;
560
561 case "peer":
562 $subject = sprintf($ulng->txt('exc_reminder_peer_subject'), $ass_title);
563 $message .= $ulng->txt('exc_reminder_peer_body') . ":\n\n";
564 break;
565 }
566
567 $message .= $ulng->txt('obj_exc') . ": " . $exc_title . "\n";
568 $message .= $ulng->txt('obj_ass') . ": " . $ass_title . "\n";
569 $message .= "\n" . $ulng->txt('exc_reminder_link') . ": " . $link;
570 }
571 $mail_obj = new ilMail(ANONYMOUS_USER_ID);
572 $mail_obj->appendInstallationSignature(true);
573 $mail_obj->sendMail(
574 ilObjUser::_lookupLogin($reminder["member_id"]),
575 "",
576 "",
577 $subject,
578 $message,
579 array(),
580 array("system")
581 );
582 }
583
584 $this->updateRemindersLastDate($reminders);
585 return sizeof($reminders);
586 }
587
588 //see ilObjSurvey.
589 protected function sentReminderPlaceholders($a_message, $a_reminder_data, $a_reminder_type)
590 {
591 // see ilMail::replacePlaceholders()
592 try {
593 switch ($a_reminder_type) {
594 case \ilExAssignmentReminder::SUBMIT_REMINDER:
596 break;
597 case \ilExAssignmentReminder::GRADE_REMINDER:
599 break;
600 case \ilExAssignmentReminder::FEEDBACK_REMINDER:
602 break;
603 default:
604 exit();
605 }
606
607 $user = new \ilObjUser($a_reminder_data["member_id"]);
608
609 $processor = new \ilMailTemplatePlaceholderResolver($context, $a_message);
610 $a_message = $processor->resolve($user, $a_reminder_data);
611 } catch (\Exception $e) {
612 \ilLoggerFactory::getLogger('mail')->error(__METHOD__ . ' has been called with invalid context.');
613 }
614
615 return $a_message;
616 }
617
622 protected function updateRemindersLastDate($a_reminders)
623 {
624 $today = date("Y-m-d");
625 foreach ($a_reminders as $reminder) {
626 $sql = "UPDATE exc_ass_reminders" .
627 " SET last_send = " . $this->db->quote(time(), 'integer') .
628 " , last_send_day = " . $this->db->quote($today, 'date') .
629 " WHERE type = " . $this->db->quote($reminder["reminder_type"], 'text') .
630 " AND ass_id = " . $this->db->quote($reminder["ass_id"], 'integer') .
631 " AND exc_id = " . $this->db->quote($reminder["exc_id"], 'integer');
632
633 $this->db->manipulate($sql);
634 }
635 }
636
641 public function deleteReminders($a_ass_id)
642 {
643 $sql = "DELETE FROM exc_ass_reminders" .
644 " WHERE ass_id = " . $a_ass_id;
645
646 $this->db->manipulate($sql);
647 }
648}
$result
$tpl
Definition: ilias.php:10
if(!array_key_exists('stateid', $_REQUEST)) $state
Handle linkback() response from LinkedIn.
Definition: linkback.php:10
$users
Definition: authpage.php:44
exit
Definition: backend.php:16
An exception for terminatinating execution or to throw for unit testing.
TODO: import/export reminder data with the exercise/assignment.
setReminderFrequency($a_num_days)
Set frequency in days.
setReminderEnd($a_date)
Set the ending of the reminder.
getReminders($a_type="")
Get reminders available by date/frequence.
setReminderStatus($a_status)
Set reminder for users without submission.
getReminderFrequency()
get submit reminder frequency in days.
initFromDB(array $a_set)
Import DB record.
getReminderStart()
Get num days before the deadline to start sending notifications.
setReminderStart($a_num_days)
Set num days before the deadline to start sending notifications.
getReminderEnd()
get the ending of the reminder
parseSubmissionReminders($a_reminders)
Filter the reminders by object(crs,grp) by active status and if have members.
sentReminderPlaceholders($a_message, $a_reminder_data, $a_reminder_type)
getReminderStatus()
Get the reminder status.
__construct($a_exc_id="", $a_ass_id="", $a_type="")
deleteReminders($a_ass_id)
remove reminders from DB when the parent assignment is deleted.
updateRemindersLastDate($a_reminders)
Update reminders last_send value with the current timestamp.
Exercise assignment.
static lookupTitle($a_id)
Lookup title.
static lookupGiversWithPendingFeedback($a_ass_id)
Exercise submission //TODO: This class has to much static methods related to delivered "files".
static getInstanceByIds($a_ass_id, $a_user_id=0)
Get instance by IDs (recommended for consumer code)
static _getLanguageOfUser($a_usr_id)
Get language object of user.
static getLogger($a_component_id)
Get component logger.
static getNotificationsForObject($type, $id, $page_id=null, $ignore_threshold=false)
Get all users for given object.
Class ilObjCourse.
Class ilObjGroup.
static _lookupLogin($a_user_id)
lookup login
static _lookupFullname($a_user_id)
Lookup Full Name.
static _lookupTitle($a_id)
lookup object title
static _getAllReferences($a_id)
get all reference ids of object
catch(Exception $e) $message
$user
Definition: migrateto20.php:57
$query
global $DIC
Definition: saml.php:7
$context
Definition: webdav.php:25
$a_type
Definition: workflow.php:92
$template_id