From 75f87a57956fd4168929908d5dc428c84d6b8b3d Mon Sep 17 00:00:00 2001
From: Damyon Wiese '.
- ''.format_string($this->get_course()->shortname, true, array('context' => $this->get_course_context())).' ->'.
- ''.$this->get_module_name().' ->'.
- ''.format_string($this->get_instance()->name, true, array('context' => $this->context)).'
It is available on the web site.';
+$string['gradersubmissionupdatedsmall'] = '{$a->username} has updated their submission for assignment {$a->assignment}.';
$string['enabled'] = 'Enabled';
$string['errornosubmissions'] = 'There are no submissions to download';
$string['errorquickgradingvsadvancedgrading'] = 'The grades were not saved because this assignment is currently using advanced grading';
$string['errorrecordmodified'] = 'The grades were not saved because someone has modified one or more records more recently than when you loaded the page.';
-$string['feedbackcomments'] = 'Feedback comments';
$string['feedback'] = 'Feedback';
+$string['feedbackavailabletext'] = '{$a->username} has posted some feedback on your
+assignment submission for \'{$a->assignment}\'
+
+You can see it appended to your assignment submission:
+
+ {$a->url}';
+$string['feedbackavailablehtml'] = '{$a->username} has posted some feedback on your
+assignment submission for \'{$a->assignment}\'
+You can see it appended to your assignment submission.';
+$string['feedbackavailablesmall'] = '{$a->username} has given feedback for assignment {$a->assignment}';
$string['feedbackplugins'] = 'Feedback plugins';
$string['feedbackpluginforgradebook'] = 'Feedback plugin that will push comments to the gradebook';
+$string['feedbackpluginforgradebook_help'] = 'Only one assignment feedback plugin can push feedback into the gradebook.';
$string['feedbackplugin'] = 'Feedback plugin';
$string['feedbacksettings'] = 'Feedback settings';
$string['filesubmissions'] = 'File submissions';
@@ -139,7 +150,8 @@ $string['locksubmissionforstudent'] = 'Prevent any more submissions for student:
$string['locksubmissions'] = 'Lock submissions';
$string['manageassignfeedbackplugins'] = 'Manage assignment feedback plugins';
$string['manageassignsubmissionplugins'] = 'Manage assignment submission plugins';
-$string['messageprovider:assign_updates'] = 'Assignment notifications';
+$string['messageprovider:assign_student_notification'] = 'Assignment student notifications';
+$string['messageprovider:assign_grader_notification'] = 'Assignment grader notifications';
$string['modulename'] = 'Assignment';
$string['modulename_help'] = 'The assignment activity module enables a teacher to assess students’ learning by setting work and then reviewing it and providing feedback and grades.
@@ -160,6 +172,7 @@ $string['notgradedyet'] = 'Not graded yet';
$string['notsubmittedyet'] = 'Not submitted yet';
$string['notifications'] = 'Notifications';
$string['nousersselected'] = 'No users selected';
+$string['notification'] = 'Notification';
$string['numberofdraftsubmissions'] = 'Drafts';
$string['numberofparticipants'] = 'Participants';
$string['numberofsubmittedassignments'] = 'Submitted';
@@ -186,9 +199,13 @@ $string['reviewed'] = 'Reviewed';
$string['savechanges'] = 'Save changes';
$string['saveallchanges'] = 'Save all changes';
$string['savenext'] = 'Save and show next';
-$string['sendnotifications'] = 'Send notifications to graders';
+$string['sendnotifications'] = 'Notify graders about submissions';
$string['sendnotifications_help'] = 'If enabled, graders (usually teachers) receive a message whenever a student submits an assignment, early, on time and late. Message methods are configurable.';
$string['selectlink'] = 'Select...';
+$string['sendlatenotifications'] = 'Notify graders about late submissions';
+$string['sendlatenotifications_help'] = 'If enabled, graders (usually teachers) receive a message whenever a student submits an assignment late. Message methods are configurable.';
+$string['sendsubmissionreceipts'] = 'Send submission receipt to students';
+$string['sendsubmissionreceipts_help'] = 'This switch will enable submission receipts for students. Students will receive a notification every time they successfully submit an assignment';
$string['settings'] = 'Assignment settings';
$string['showrecentsubmissions'] = 'Show recent submissions';
$string['submissiondrafts'] = 'Require students click submit button';
@@ -196,6 +213,16 @@ $string['submissiondrafts_help'] = 'If enabled, students will have to click a Su
$string['submissionnotready'] = 'This assignment is not ready to submit:';
$string['submissionplugins'] = 'Submission plugins';
$string['submissionreceipts'] = 'Send submission receipts';
+$string['submissionreceipttext'] = 'You have submitted an
+assignment submission for \'{$a->assignment}\'
+
+You can see the status of your assignment submission:
+
+ {$a->url}';
+$string['submissionreceipthtml'] = 'You have submitted an
+assignment submission for \'{$a->assignment}\'
+You can the status of your assignment submission.';
+$string['submissionreceiptsmall'] = 'You have submitted your assignment submission for {$a->assignment}';
$string['submissionslocked'] = 'This assignment is not accepting submissions';
$string['submissionslockedshort'] = 'Submission changes not allowed';
$string['submissions'] = 'Submissions';
diff --git a/mod/assign/lib.php b/mod/assign/lib.php
index 61c97730223..b9e71a1c9bf 100644
--- a/mod/assign/lib.php
+++ b/mod/assign/lib.php
@@ -674,7 +674,8 @@ function assign_cron() {
global $CFG;
require_once($CFG->dirroot . '/mod/assign/locallib.php');
- //assignment::cron();
+ assign::cron();
+
$plugins = get_plugin_list('assignsubmission');
foreach ($plugins as $name => $plugin) {
diff --git a/mod/assign/locallib.php b/mod/assign/locallib.php
index 0e55f453d3c..6e4460fad1a 100644
--- a/mod/assign/locallib.php
+++ b/mod/assign/locallib.php
@@ -419,6 +419,7 @@ class assign {
$update->preventlatesubmissions = $formdata->preventlatesubmissions;
$update->submissiondrafts = $formdata->submissiondrafts;
$update->sendnotifications = $formdata->sendnotifications;
+ $update->sendlatenotifications = $formdata->sendlatenotifications;
$update->duedate = $formdata->duedate;
$update->allowsubmissionsfromdate = $formdata->allowsubmissionsfromdate;
$update->grade = $formdata->grade;
@@ -636,6 +637,7 @@ class assign {
$update->preventlatesubmissions = $formdata->preventlatesubmissions;
$update->submissiondrafts = $formdata->submissiondrafts;
$update->sendnotifications = $formdata->sendnotifications;
+ $update->sendlatenotifications = $formdata->sendlatenotifications;
$update->duedate = $formdata->duedate;
$update->allowsubmissionsfromdate = $formdata->allowsubmissionsfromdate;
$update->grade = $formdata->grade;
@@ -1068,7 +1070,6 @@ class assign {
return false;
}
-
/**
* Cron function to be run periodically according to the moodle cron
* Finds all assignment notifications that have yet to be mailed out, and mails them
@@ -1076,8 +1077,93 @@ class assign {
* @return bool
*/
static function cron() {
- global $CFG, $USER, $DB;
+ global $CFG, $DB;
+ // used to cache DB lookups
+ $croncache = array();
+
+ // only ever send a max of one days worth of updates
+ $yesterday = time() - (24 * 3600);
+ $timenow = time();
+
+ // email students about new feedback
+ $submissions = $DB->get_records_sql("SELECT s.*, a.course, a.name, g.*, g.id as gradeid, g.timemodified as lastmodified
+ FROM {assign} a
+ JOIN {assign_grades} g ON g.assignment = a.id
+ LEFT JOIN {assign_submission} s ON s.assignment = a.id AND s.userid = g.userid
+ WHERE g.timemodified >= :yesterday
+ AND g.timemodified <= :today
+ AND g.mailed = 0", array('yesterday'=>$yesterday, 'today'=>$timenow));
+
+ mtrace('Processing ' . count($submissions) . ' assignment submissions ...');
+
+ foreach ($submissions as $submission) {
+
+ mtrace("Processing assignment submission $submission->id ...");
+
+ // do not cache user lookups - could be too many
+ if (! $user = $DB->get_record("user", array("id"=>$submission->userid))) {
+ mtrace("Could not find user $submission->userid");
+ continue;
+ }
+
+ // use a cache to prevent the same DB queries happening over and over
+ if (! $course = array_search('course_' . $submission->course, $croncache)) {
+ if (! $course = $DB->get_record("course", array("id"=>$submission->course))) {
+ mtrace("Could not find course $submission->course");
+ continue;
+ }
+ $croncache['course_' . $submission->course] = $course;
+ }
+
+ /// Override the language and timezone of the "current" user, so that
+ /// mail is customised for the receiver.
+ cron_setup_user($user, $course);
+
+ // context lookups are already cached
+ $coursecontext = context_course::instance($submission->course);
+ $courseshortname = format_string($course->shortname, true, array('context' => $coursecontext));
+ if (!is_enrolled($coursecontext, $user->id)) {
+ mtrace(fullname($user)." not an active participant in " . $courseshortname);
+ continue;
+ }
+
+ if (! $grader = $DB->get_record("user", array("id"=>$submission->grader))) {
+ mtrace("Could not find grader $submission->grader");
+ continue;
+ }
+
+
+ if (! $mod = array_search('mod_' . $submission->assignment, $croncache)) {
+ if (! $mod = get_coursemodule_from_instance("assign", $submission->assignment, $course->id)) {
+ mtrace("Could not find course module for assignment id $submission->assignment");
+ continue;
+ }
+ $croncache['mod_' . $submission->assignment] = $mod;
+ }
+
+ // context lookups are already cached
+ $contextmodule = context_module::instance($mod->id);
+
+ if (! $mod->visible) { /// Hold mail notification for hidden assignments until later
+ continue;
+ }
+
+ // need to send this to the student
+ self::send_assignment_notification($grader, $user, 'feedbackavailable', 'assign_student_notification', $submission->lastmodified, $mod, $contextmodule, $course, get_string('modulename', 'assign'), $submission->name);
+
+ $grade = new stdClass();
+ $grade->id = $submission->gradeid;
+ $grade->mailed = 1;
+ $DB->update_record('assign_grades', $grade);
+
+ mtrace('Done');
+ }
+ mtrace('Done processing ' . count($submissions) . ' assignment submissions');
+
+ cron_setup_user();
+ // free up memory
+ unset($croncache);
return true;
}
@@ -2162,19 +2248,19 @@ class assign {
/**
* Returns a list of teachers that should be grading given submission
*
- * @param stdClass $user
+ * @param int $userid
* @return array
*/
- private function get_graders(stdClass $user) {
+ private function get_graders($userid) {
//potential graders
- $potentialgraders = get_users_by_capability($this->context, 'mod/assign:grade', '', '', '', '', '', '', false, false);
+ $potentialgraders = get_enrolled_users($this->context, "mod/assign:grade");
$graders = array();
if (groups_get_activity_groupmode($this->get_course_module()) == SEPARATEGROUPS) { // Separate groups are being used
- if ($groups = groups_get_all_groups($this->get_course()->id, $user->id)) { // Try to find all groups
+ if ($groups = groups_get_all_groups($this->get_course()->id, $userid)) { // Try to find all groups
foreach ($groups as $group) {
foreach ($potentialgraders as $grader) {
- if ($grader->id == $user->id) {
+ if ($grader->id == $userid) {
continue; // do not send self
}
if (groups_is_member($group->id, $grader->id)) {
@@ -2185,7 +2271,7 @@ class assign {
} else {
// user not in group, try to find graders without group
foreach ($potentialgraders as $grader) {
- if ($grader->id == $user->id) {
+ if ($grader->id == $userid) {
continue; // do not send self
}
if (!groups_has_membership($this->get_course_module(), $grader->id)) {
@@ -2195,7 +2281,7 @@ class assign {
}
} else {
foreach ($potentialgraders as $grader) {
- if ($grader->id == $user->id) {
+ if ($grader->id == $userid) {
continue; // do not send self
}
// must be enrolled
@@ -2208,88 +2294,158 @@ class assign {
}
/**
- * Creates the text content for emails to grader
+ * Format a notification based on it's type
*
- * @param array $info The info used by the 'emailgradermail' language string
- * @return string
+ * @param string $messagetype
+ * @param stdClass $info
+ * @param stdClass $course
+ * @param stdClass $context
+ * @param string $modulename
+ * @param string $assignmentname
*/
- private function format_email_grader_text($info) {
- $posttext = format_string($this->get_course()->shortname, true, array('context' => $this->get_course_context())).' -> '.
- $this->get_module_name().' -> '.
- format_string($this->get_instance()->name, true, array('context' => $this->context))."\n";
+ private static function format_notification_message_text($messagetype, $info, $course, $context, $modulename, $assignmentname) {
+ $posttext = format_string($course->shortname, true, array('context' => $context->get_course_context())).' -> '.
+ $modulename.' -> '.
+ format_string($assignmentname, true, array('context' => $context))."\n";
$posttext .= '---------------------------------------------------------------------'."\n";
- $posttext .= get_string("emailgradermail", "assign", $info)."\n";
+ $posttext .= get_string($messagetype . 'text', "assign", $info)."\n";
$posttext .= "\n---------------------------------------------------------------------\n";
return $posttext;
}
- /**
- * Creates the html content for emails to graders
+ /**
+ * Format a notification based on it's type
*
- * @param array $info The info used by the 'emailgradermailhtml' language string
- * @return string
+ * @param string $messagetype
+ * @param stdClass $info
*/
- private function format_email_grader_html($info) {
+ private static function format_notification_message_html($messagetype, $info, $course, $context, $modulename, $coursemodule, $assignmentname) {
global $CFG;
$posthtml = '
'.get_string('emailgradermailhtml', 'assign', $info).'
'; + $posthtml .= ''.get_string($messagetype . 'html', 'assign', $info).'
'; $posthtml .= '