libdir.'/filelib.php'); /*** Constants **********************************/ $WORKSHOP_EWEIGHTS = array( 0 => -4.0, 1 => -2.0, 2 => -1.5, 3 => -1.0, 4 => -0.75, 5 => -0.5, 6 => -0.25, 7 => 0.0, 8 => 0.25, 9 => 0.5, 10 => 0.75, 11=> 1.0, 12 => 1.5, 13=> 2.0, 14 => 4.0); $WORKSHOP_FWEIGHTS = array( 0 => 0, 1 => 0.1, 2 => 0.25, 3 => 0.5, 4 => 0.75, 5 => 1.0, 6 => 1.5, 7 => 2.0, 8 => 3.0, 9 => 5.0, 10 => 7.5, 11=> 10.0, 12=>50.0); $WORKSHOP_ASSESSMENT_COMPS = array ( 0 => array('name' => get_string('verylax', 'workshop'), 'value' => 1), 1 => array('name' => get_string('lax', 'workshop'), 'value' => 0.6), 2 => array('name' => get_string('fair', 'workshop'), 'value' => 0.4), 3 => array('name' => get_string('strict', 'workshop'), 'value' => 0.33), 4 => array('name' => get_string('verystrict', 'workshop'), 'value' => 0.2) ); /*** Moodle 1.7 compatibility functions ***** * ********************************************/ function workshop_context($workshop) { //TODO: add some $cm caching if needed if (is_object($workshop)) { $workshop = $workshop->id; } if (! $cm = get_coursemodule_from_instance('workshop', $workshop)) { error('Course Module ID was incorrect'); } return get_context_instance(CONTEXT_MODULE, $cm->id); } function workshop_is_teacher($workshop, $userid=NULL) { return has_capability('mod/workshop:manage', workshop_context($workshop), $userid); } function workshop_is_teacheredit($workshop, $userid=NULL) { return has_capability('mod/workshop:manage', workshop_context($workshop), $userid) and has_capability('moodle/site:accessallgroups', workshop_context($workshop), $userid); } function workshop_is_student($workshop, $userid=NULL) { return has_capability('mod/workshop:participate', workshop_context($workshop), $userid); } function workshop_get_students($workshop, $sort='u.lastaccess', $fields='u.*') { return $users = get_users_by_capability(workshop_context($workshop), 'mod/workshop:participate', $fields, $sort); } function workshop_get_teachers($workshop, $sort='u.lastaccess', $fields='u.*') { return $users = get_users_by_capability(workshop_context($workshop), 'mod/workshop:manage', $fields, $sort); } /*** Standard Moodle functions ****************** workshop_add_instance($workshop) workshop_check_dates($workshop) workshop_cron () workshop_delete_instance($id) workshop_grades($workshopid) workshop_print_recent_activity(&$logs, $isteacher=false) workshop_refresh_events($workshop) workshop_update_instance($workshop) workshop_user_complete($course, $user, $mod, $workshop) workshop_user_outline($course, $user, $mod, $workshop) **********************************************/ /////////////////////////////////////////////////////////////////////////////// function workshop_add_instance($workshop) { // Given an object containing all the necessary data, // (defined by the form in mod.html) this function // will create a new instance and return the id number // of the new instance. $workshop->timemodified = time(); $workshop->submissionstart = make_timestamp($workshop->submissionstartyear, $workshop->submissionstartmonth, $workshop->submissionstartday, $workshop->submissionstarthour, $workshop->submissionstartminute); $workshop->assessmentstart = make_timestamp($workshop->assessmentstartyear, $workshop->assessmentstartmonth, $workshop->assessmentstartday, $workshop->assessmentstarthour, $workshop->assessmentstartminute); $workshop->submissionend = make_timestamp($workshop->submissionendyear, $workshop->submissionendmonth, $workshop->submissionendday, $workshop->submissionendhour, $workshop->submissionendminute); $workshop->assessmentend = make_timestamp($workshop->assessmentendyear, $workshop->assessmentendmonth, $workshop->assessmentendday, $workshop->assessmentendhour, $workshop->assessmentendminute); $workshop->releasegrades = make_timestamp($workshop->releaseyear, $workshop->releasemonth, $workshop->releaseday, $workshop->releasehour, $workshop->releaseminute); if (!workshop_check_dates($workshop)) { return get_string('invaliddates', 'workshop'); } // set the workshop's type $wtype = 0; // 3 phases, no grading grades if ($workshop->includeself or $workshop->ntassessments) $wtype = 1; // 3 phases with grading grades if ($workshop->nsassessments) $wtype = 2; // 5 phases with grading grades $workshop->wtype = $wtype; if ($returnid = insert_record("workshop", $workshop)) { $event = NULL; $event->name = get_string('submissionstartevent','workshop', $workshop->name); $event->description = $workshop->description; $event->courseid = $workshop->course; $event->groupid = 0; $event->userid = 0; $event->modulename = 'workshop'; $event->instance = $returnid; $event->eventtype = 'submissionstart'; $event->timestart = $workshop->submissionstart; $event->timeduration = 0; add_event($event); $event->name = get_string('submissionendevent','workshop', $workshop->name); $event->eventtype = 'submissionend'; $event->timestart = $workshop->submissionend; add_event($event); $event->name = get_string('assessmentstartevent','workshop', $workshop->name); $event->eventtype = 'assessmentstart'; $event->timestart = $workshop->assessmentstart; add_event($event); $event->name = get_string('assessmentendevent','workshop', $workshop->name); $event->eventtype = 'assessmentend'; $event->timestart = $workshop->assessmentend; add_event($event); } return $returnid; } /////////////////////////////////////////////////////////////////////////////// // returns true if the dates are valid, false otherwise function workshop_check_dates($workshop) { // allow submission and assessment to start on the same date and to end on the same date // but enforce non-empty submission period and non-empty assessment period. return ($workshop->submissionstart < $workshop->submissionend and $workshop->submissionstart <= $workshop->assessmentstart and $workshop->assessmentstart < $workshop->assessmentend and $workshop->submissionend <= $workshop->assessmentend); } /////////////////////////////////////////////////////////////////////////////// function workshop_cron () { // Function to be run periodically according to the moodle cron global $CFG, $USER; // if there any ungraded assessments run the grading routine if ($workshops = get_records("workshop")) { foreach ($workshops as $workshop) { // automatically grade assessments if workshop has examples and/or peer assessments if ($workshop->gradingstrategy and ($workshop->ntassessments or $workshop->nsassessments)) { workshop_grade_assessments($workshop); } } } $timenow = time(); // Find all workshop notifications that have yet to be mailed out, and mails them $cutofftime = $timenow - $CFG->maxeditingtime; // look for new assessments if ($assessments = workshop_get_unmailed_assessments($cutofftime)) { foreach ($assessments as $assessment) { echo "Processing workshop assessment $assessment->id\n"; // only process the entry once if (! set_field("workshop_assessments", "mailed", "1", "id", "$assessment->id")) { echo "Could not update the mailed field for id $assessment->id\n"; } if (! $submission = get_record("workshop_submissions", "id", "$assessment->submissionid")) { echo "Could not find submission $assessment->submissionid\n"; continue; } if (! $workshop = get_record("workshop", "id", $submission->workshopid)) { echo "Could not find workshop id $submission->workshopid\n"; continue; } if (! $course = get_record("course", "id", $workshop->course)) { error("Could not find course id $workshop->course"); continue; } if (! $cm = get_coursemodule_from_instance("workshop", $workshop->id, $course->id)) { error("Course Module ID was incorrect"); continue; } if (! $submissionowner = get_record("user", "id", "$submission->userid")) { echo "Could not find user $submission->userid\n"; continue; } if (! $assessmentowner = get_record("user", "id", "$assessment->userid")) { echo "Could not find user $assessment->userid\n"; continue; } if (! workshop_is_student($workshop, $submissionowner->id) and !workshop_is_teacher($workshop, $submissionowner->id)) { continue; // Not an active participant } if (! workshop_is_student($workshop, $assessmentowner->id) and !workshop_is_teacher($workshop, $assessmentowner->id)) { continue; // Not an active participant } // don't sent self assessment if ($submissionowner->id == $assessmentowner->id) { continue; } $strworkshops = get_string("modulenameplural", "workshop"); $strworkshop = get_string("modulename", "workshop"); // it's an assessment, tell the submission owner $USER->lang = $submissionowner->lang; $sendto = $submissionowner; // "Your assignment \"$submission->title\" has been assessed by" if (workshop_is_student($workshop, $assessmentowner->id)) { $msg = get_string("mail1", "workshop", $submission->title)." a $course->student.\n"; } else { $msg = get_string("mail1", "workshop", $submission->title). " ".fullname($assessmentowner)."\n"; } // "The comments and grade can be seen in the workshop assignment '$workshop->name' // I have taken the following line out because the info is repeated below. // $msg .= get_string("mail2", "workshop", $workshop->name)."\n\n"; $postsubject = "$course->shortname: $strworkshops: ".format_string($workshop->name,true); $posttext = "$course->shortname -> $strworkshops -> ".format_string($workshop->name,true)."\n"; $posttext .= "---------------------------------------------------------------------\n"; $posttext .= $msg; // "The comments and grade can be seen in ..." $posttext .= get_string("mail2", "workshop", format_string($workshop->name,true).", $CFG->wwwroot/mod/workshop/view.php?id=$cm->id")."\n"; $posttext .= "---------------------------------------------------------------------\n"; if ($sendto->mailformat == 1) { // HTML $posthtml = "

". "wwwroot/course/view.php?id=$course->id\">$course->shortname ->". "wwwroot/mod/workshop/index.php?id=$course->id\">$strworkshops ->". "wwwroot/mod/workshop/view.php?id=$cm->id\">".format_string($workshop->name,true)."

"; $posthtml .= "
"; $posthtml .= "

$msg

"; $posthtml .= "

".get_string("mail2", "workshop", " wwwroot/mod/workshop/view.php?id=$cm->id\">".format_string($workshop->name,true)."")."


"; } else { $posthtml = ""; } if (!$teacher = get_teacher($course->id)) { echo "Error: can not find teacher for course $course->id!\n"; } if (! email_to_user($sendto, $teacher, $postsubject, $posttext, $posthtml)) { echo "Error: workshop cron: Could not send out mail for id $submission->id to user $sendto->id ($sendto->email)\n"; } } } // look for new assessments of resubmissions if ($assessments = workshop_get_unmailed_resubmissions($cutofftime)) { $timenow = time(); foreach ($assessments as $assessment) { echo "Processing workshop assessment $assessment->id\n"; // only process the entry once if (! set_field("workshop_assessments", "mailed", "1", "id", "$assessment->id")) { echo "Could not update the mailed field for id $assessment->id\n"; } if (! $submission = get_record("workshop_submissions", "id", "$assessment->submissionid")) { echo "Could not find submission $assessment->submissionid\n"; continue; } if (! $workshop = get_record("workshop", "id", $submission->workshopid)) { echo "Could not find workshop id $submission->workshopid\n"; continue; } if (! $course = get_record("course", "id", $workshop->course)) { error("Could not find course id $workshop->course"); continue; } if (! $cm = get_coursemodule_from_instance("workshop", $workshop->id, $course->id)) { error("Course Module ID was incorrect"); continue; } if (! $submissionowner = get_record("user", "id", "$submission->userid")) { echo "Could not find user $submission->userid\n"; continue; } if (! $assessmentowner = get_record("user", "id", "$assessment->userid")) { echo "Could not find user $assessment->userid\n"; continue; } if (! workshop_is_student($workshop, $submissionowner->id) and !workshop_is_teacher($workshop, $submissionowner->id)) { continue; // Not an active participant } if (! workshop_is_student($workshop, $assessmentowner->id) and !workshop_is_teacher($workshop, $assessmentowner->id)) { continue; // Not an active participant } $strworkshops = get_string("modulenameplural", "workshop"); $strworkshop = get_string("modulename", "workshop"); // it's a resubission assessment, tell the assessment owner to (re)assess $USER->lang = $assessmentowner->lang; $sendto = $assessmentowner; // "The assignment \"$submission->title\" is a revised piece of work. " $msg = get_string("mail8", "workshop", $submission->title)."\n"; // "Please assess it in the workshop assignment '$workshop->name' // $msg .= get_string("mail9", "workshop", $workshop->name)."\n\n"; $postsubject = "$course->shortname: $strworkshops: ".format_string($workshop->name,true); $posttext = "$course->shortname -> $strworkshops -> ".format_string($workshop->name,true)."\n"; $posttext .= "---------------------------------------------------------------------\n"; $posttext .= $msg; // "Please assess it in ..." $posttext .= get_string("mail9", "workshop", format_string($workshop->name,true).", $CFG->wwwroot/mod/workshop/view.php?id=$cm->id")."\n"; $posttext .= "---------------------------------------------------------------------\n"; if ($sendto->mailformat == 1) { // HTML $posthtml = "

". "wwwroot/course/view.php?id=$course->id\">$course->shortname ->". "wwwroot/mod/workshop/index.php?id=$course->id\">$strworkshops ->". "wwwroot/mod/workshop/view.php?id=$cm->id\">".format_string($workshop->name,true)."

"; $posthtml .= "
"; $posthtml .= "

$msg

"; $posthtml .= "

".get_string("mail9", "workshop", " wwwroot/mod/workshop/view.php?id=$cm->id\">".format_string($workshop->name,true)."").'


'; } else { $posthtml = ""; } if (!$teacher = get_teacher($course->id)) { echo "Error: can not find teacher for course $course->id!\n"; } if (! email_to_user($sendto, $teacher, $postsubject, $posttext, $posthtml)) { echo "Error: workshop cron: Could not send out mail for id $submission->id to user $sendto->id ($sendto->email)\n"; } } } // look for new comments if ($comments = workshop_get_unmailed_comments($cutofftime)) { $timenow = time(); foreach ($comments as $comment) { echo "Processing workshop comment $comment->id\n"; // only process the entry once if (! set_field("workshop_comments", "mailed", "1", "id", "$comment->id")) { echo "Could not update the mailed field for comment id $comment->id\n"; } if (! $assessment = get_record("workshop_assessments", "id", "$comment->assessmentid")) { echo "Could not find assessment $comment->assessmentid\n"; continue; } if (! $submission = get_record("workshop_submissions", "id", "$assessment->submissionid")) { echo "Could not find submission $assessment->submissionid\n"; continue; } if (! $workshop = get_record("workshop", "id", $submission->workshopid)) { echo "Could not find workshop id $submission->workshopid\n"; continue; } if (! $course = get_record("course", "id", $workshop->course)) { error("Could not find course id $workshop->course"); continue; } if (! $cm = get_coursemodule_from_instance("workshop", $workshop->id, $course->id)) { error("Course Module ID was incorrect"); continue; } if (! $submissionowner = get_record("user", "id", "$submission->userid")) { echo "Could not find user $submission->userid\n"; continue; } if (! $assessmentowner = get_record("user", "id", "$assessment->userid")) { echo "Could not find user $assessment->userid\n"; continue; } if (! workshop_is_student($workshop, $submissionowner->id) and !workshop_is_teacher($workshop, $submissionowner->id)) { continue; // Not an active participant } if (! workshop_is_student($workshop, $assessmentowner->id) and !workshop_is_teacher($workshop, $assessmentowner->id)) { continue; // Not an active participant } $strworkshops = get_string("modulenameplural", "workshop"); $strworkshop = get_string("modulename", "workshop"); // see if the submission owner needs to be told if ($comment->userid != $submission->userid) { $USER->lang = $submissionowner->lang; $sendto = $submissionowner; // "A comment has been added to the assignment \"$submission->title\" by if (workshop_is_student($workshop, $assessmentowner->id)) { $msg = get_string("mail4", "workshop", $submission->title)." a $course->student.\n"; } else { $msg = get_string("mail4", "workshop", $submission->title)." ".fullname($assessmentowner)."\n"; } // "The new comment can be seen in the workshop assignment '$workshop->name' // $msg .= get_string("mail5", "workshop", $workshop->name)."\n\n"; $postsubject = "$course->shortname: $strworkshops: ".format_string($workshop->name,true); $posttext = "$course->shortname -> $strworkshops -> ".format_string($workshop->name,true)."\n"; $posttext .= "---------------------------------------------------------------------\n"; $posttext .= $msg; // "The new comment can be seen in ..." $posttext .= get_string("mail5", "workshop", format_string($workshop->name,true).", $CFG->wwwroot/mod/workshop/view.php?id=$cm->id")."\n"; $posttext .= "---------------------------------------------------------------------\n"; if ($sendto->mailformat == 1) { // HTML $posthtml = "

". "wwwroot/course/view.php?id=$course->id\">$course->shortname ->". "wwwroot/mod/workshop/index.php?id=$course->id\">$strworkshops ->". "wwwroot/mod/workshop/view.php?id=$cm->id\">".format_string($workshop->name,true)."

"; $posthtml .= "
"; $posthtml .= "

$msg

"; $posthtml .= "

".get_string("mail5", "workshop", " wwwroot/mod/workshop/view.php?id=$cm->id\">".format_string($workshop->name,true)."") ."


"; } else { $posthtml = ""; } if (!$teacher = get_teacher($course->id)) { echo "Error: can not find teacher for course $course->id!\n"; } if (! email_to_user($sendto, $teacher, $postsubject, $posttext, $posthtml)) { echo "Error: workshop cron: Could not send out mail for id $submission->id to user $sendto->id ($sendto->email)\n"; } } // see if the assessor needs to to told if ($comment->userid != $assessment->userid) { $USER->lang = $assessmentowner->lang; $sendto = $assessmentowner; // "A comment has been added to the assignment \"$submission->title\" by if (workshop_is_student($workshop, $submissionowner->id)) { $msg = get_string("mail4", "workshop", $submission->title)." a $course->student.\n"; } else { $msg = get_string("mail4", "workshop", $submission->title). " ".fullname($submissionowner)."\n"; } // "The new comment can be seen in the workshop assignment '$workshop->name' // $msg .= get_string("mail5", "workshop", $workshop->name)."\n\n"; $postsubject = "$course->shortname: $strworkshops: ".format_string($workshop->name,true); $posttext = "$course->shortname -> $strworkshops -> ".format_string($workshop->name,true)."\n"; $posttext .= "---------------------------------------------------------------------\n"; $posttext .= $msg; // "The new comment can be seen in ..." $posttext .= get_string("mail5", "workshop", format_string($workshop->name,true).", $CFG->wwwroot/mod/workshop/view.php?id=$cm->id")."\n"; $posttext .= "---------------------------------------------------------------------\n"; if ($sendto->mailformat == 1) { // HTML $posthtml = "

". "wwwroot/course/view.php?id=$course->id\">$course->shortname ->". "wwwroot/mod/workshop/index.php?id=$course->id\">$strworkshops ->". "wwwroot/mod/workshop/view.php?id=$cm->id\">".format_string($workshop->name,true)."

"; $posthtml .= "
"; $posthtml .= "

$msg

"; $posthtml .= "

".get_string("mail5", "workshop", " wwwroot/mod/workshop/view.php?id=$cm->id\">".format_string($workshop->name,true)."") ."


"; } else { $posthtml = ""; } if (!$teacher = get_teacher($course->id)) { echo "Error: can not find teacher for course $course->id!\n"; } if (! email_to_user($sendto, $teacher, $postsubject, $posttext, $posthtml)) { echo "Error: workshop cron: Could not send out mail for id $submission->id to user $sendto->id ($sendto->email)\n"; } if (! set_field("workshop_comments", "mailed", "1", "id", "$comment->id")) { echo "Could not update the mailed field for comment id $comment->id\n"; } } } } return true; } /////////////////////////////////////////////////////////////////////////////// function workshop_delete_instance($id) { // Given an ID of an instance of this module, // this function will permanently delete the instance // and any data that depends on it. if (! $workshop = get_record("workshop", "id", "$id")) { return false; } // delete all the associated records in the workshop tables, start positive... $result = true; if (! delete_records("workshop_comments", "workshopid", "$workshop->id")) { $result = false; } if (! delete_records("workshop_stockcomments", "workshopid", "$workshop->id")) { $result = false; } if (! delete_records("workshop_grades", "workshopid", "$workshop->id")) { $result = false; } if (! delete_records("workshop_elements", "workshopid", "$workshop->id")) { $result = false; } if (! delete_records("workshop_assessments", "workshopid", "$workshop->id")) { $result = false; } if (! delete_records("workshop_submissions", "workshopid", "$workshop->id")) { $result = false; } if (! delete_records("workshop", "id", "$workshop->id")) { $result = false; } if (! delete_records('event', 'modulename', 'workshop', 'instance', $workshop->id)) { $result = false; } return $result; } /////////////////////////////////////////////////////////////////////////////// function workshop_grades($workshopid) { /// Must return an array of grades, indexed by user, and a max grade. /// only returns grades once assessment has started /// returns nothing if workshop is not graded global $CFG; $return = null; if ($workshop = get_record("workshop", "id", $workshopid)) { if (($workshop->assessmentstart < time()) and $workshop->gradingstrategy) { if ($students = workshop_get_students($workshop)) { foreach ($students as $student) { if ($workshop->wtype) { $gradinggrade = workshop_gradinggrade($workshop, $student); } else { // ignore grading grades for simple assignments $gradinggrade = 0; } $bestgrade = 0; if ($submissions = workshop_get_user_submissions($workshop, $student)) { foreach ($submissions as $submission) { if (!$submission->late) { $grade = workshop_submission_grade($workshop, $submission); } else { $grade = 0.01; } if ($grade > $bestgrade) { $bestgrade = $grade; } } } $return->grades[$student->id] = $gradinggrade + $bestgrade; } } } // set maximum grade if graded if ($workshop->gradingstrategy) { if ($workshop->wtype) { $return->maxgrade = $workshop->grade + $workshop->gradinggrade; } else { // ignore grading grades for simple assignemnts $return->maxgrade = $workshop->grade; } } } return $return; } ////////////////////////////////////////////////////////////////////////////////////// function workshop_is_recent_activity($course, $isteacher, $timestart) {//jlw1 added for adding mark to courses with activity in My Moodle global $CFG; // have a look for agreed assessments for this user (agree) $agreecontent = false; if (!$isteacher) { // teachers only need to see submissions if ($logs = workshop_get_agree_logs($course, $timestart)) { // got some, see if any belong to a visible module foreach ($logs as $log) { // Create a temp valid module structure (only need courseid, moduleid) $tempmod->course = $course->id; $tempmod->id = $log->workshopid; //Obtain the visible property from the instance if (instance_is_visible("workshop",$tempmod)) { $agreecontent = true; break; } } } } return false; } /////////////////////////////////////////////////////////////////////////////// // // NOTE: $isteacher usage should be converted to use roles. // TODO: Fix this function. // function workshop_print_recent_activity($course, $viewfullanmes, $timestart) { global $CFG; $isteacher = has_capability('mod/workshop:manage', get_context_instance(CONTEXT_COURSE, $course->id)); $modinfo = get_fast_modinfo($course); // have a look for agreed assessments for this user (agree) $agreecontent = false; if (!$isteacher) { // teachers only need to see submissions if ($logs = workshop_get_agree_logs($course, $timestart)) { $agreecontent = true; print_headline(get_string("workshopagreedassessments", "workshop").":"); foreach ($logs as $log) { if (!workshop_is_teacher($workshop, $log->userid)) { // don't break anonymous rule $log->firstname = $course->student; $log->lastname = ''; } print_recent_activity_note($log->time, $log, $log->name, $CFG->wwwroot.'/mod/workshop/'.$log->url); } } } // have a look for new assessments for this user (assess) $assesscontent = false; if (!$isteacher) { // teachers only need to see submissions if ($logs = workshop_get_assess_logs($course, $timestart)) { // got some, see if any belong to a visible module foreach ($logs as $id=>$log) { $cm = $modinfo->instances['workshop'][$log->workshopid]; if (!$cm->uservisible) { unset($logs[$id]); continue; } } // if we got some "live" ones then output them if ($logs) { $assesscontent = true; print_headline(get_string("workshopassessments", "workshop").":"); foreach ($logs as $log) { if (!workshop_is_teacher($tempmod->id, $log->userid)) { // don't break anonymous rule $log->firstname = $course->student; // Keep anonymous $log->lastname = ''; } print_recent_activity_note($log->time, $log, $log->name, $CFG->wwwroot.'/mod/workshop/'.$log->url); } } } } // have a look for new comments for this user (comment) $commentcontent = false; if (!$isteacher) { // teachers only need to see submissions if ($logs = workshop_get_comment_logs($course, $timestart)) { // got some, see if any belong to a visible module foreach ($logs as $id=>$log) { $cm = $modinfo->instances['workshop'][$log->workshopid]; if (!$cm->uservisible) { unset($logs[$id]); continue; } } // if we got some "live" ones then output them if ($logs) { $commentcontent = true; print_headline(get_string("workshopcomments", "workshop").":"); foreach ($logs as $log) { $log->firstname = $course->student; // Keep anonymous $log->lastname = ''; print_recent_activity_note($log->time, $log, $log->name, $CFG->wwwroot.'/mod/workshop/'.$log->url); } } } } // have a look for new assessment gradings for this user (grade) $gradecontent = false; if ($logs = workshop_get_grade_logs($course, $timestart)) { // got some, see if any belong to a visible module foreach ($logs as $id=>$log) { $cm = $modinfo->instances['workshop'][$log->workshopid]; if (!$cm->uservisible) { unset($logs[$id]); continue; } } // if we got some "live" ones then output them if ($logs) { $gradecontent = true; print_headline(get_string("workshopfeedback", "workshop").":"); foreach ($logs as $log) { $log->firstname = $course->teacher; // Keep anonymous $log->lastname = ''; print_recent_activity_note($log->time, $log, $log->name, $CFG->wwwroot.'/mod/workshop/'.$log->url); } } } // have a look for new submissions (only show to teachers) (submit) $submitcontent = false; if ($isteacher) { if ($logs = workshop_get_submit_logs($course, $timestart)) { // got some, see if any belong to a visible module foreach ($logs as $id=>$log) { $cm = $modinfo->instances['workshop'][$log->workshopid]; if (!$cm->uservisible) { unset($logs[$id]); continue; } } // if we got some "live" ones then output them if ($logs) { $submitcontent = true; print_headline(get_string("workshopsubmissions", "workshop").":"); foreach ($logs as $log) { print_recent_activity_note($log->time, $log, $log->name, $CFG->wwwroot.'/mod/workshop/'.$log->url); } } } } return $agreecontent or $assesscontent or $commentcontent or $gradecontent or $submitcontent; } /////////////////////////////////////////////////////////////////////////////// function workshop_refresh_events($courseid = 0) { // This standard function will check all instances of this module // and make sure there are up-to-date events created for each of them. // If courseid = 0, then every workshop event in the site is checked, else // only workshop events belonging to the course specified are checked. // This function is used, in its new format, by restore_refresh_events() if ($courseid == 0) { if (! $workshops = get_records("workshop")) { return true; } } else { if (! $workshops = get_records("workshop", "course", $courseid)) { return true; } } $moduleid = get_field('modules', 'id', 'name', 'workshop'); foreach ($workshops as $workshop) { $dates = array( 'submissionstart' => $workshop->submissionstart, 'submissionend' => $workshop->submissionend, 'assessmentstart' => $workshop->assessmentstart, 'assessmentend' => $workshop->assessmentend ); foreach ($dates as $type => $date) { if ($date) { if ($event = get_record('event', 'modulename', 'workshop', 'instance', $workshop->id, 'eventtype', $type)) { $event->name = addslashes(get_string($type.'event','workshop', $workshop->name)); $event->description = addslashes($workshop->description); $event->eventtype = $type; $event->timestart = $date; update_event($event); } else { $event->courseid = $workshop->course; $event->modulename = 'workshop'; $event->instance = $workshop->id; $event->name = addslashes(get_string($type.'event','workshop', $workshop->name)); $event->description = addslashes($workshop->description); $event->eventtype = $type; $event->timestart = $date; $event->timeduration = 0; $event->visible = get_field('course_modules', 'visible', 'module', $moduleid, 'instance', $workshop->id); add_event($event); } } } } return true; } /////////////////////////////////////////////////////////////////////////////// function workshop_update_instance($workshop) { // Given an object containing all the necessary data, // (defined by the form in mod.html) this function // will update an existing instance with new data. global $CFG; $workshop->timemodified = time(); $workshop->submissionstart = make_timestamp($workshop->submissionstartyear, $workshop->submissionstartmonth, $workshop->submissionstartday, $workshop->submissionstarthour, $workshop->submissionstartminute); $workshop->assessmentstart = make_timestamp($workshop->assessmentstartyear, $workshop->assessmentstartmonth, $workshop->assessmentstartday, $workshop->assessmentstarthour, $workshop->assessmentstartminute); $workshop->submissionend = make_timestamp($workshop->submissionendyear, $workshop->submissionendmonth, $workshop->submissionendday, $workshop->submissionendhour, $workshop->submissionendminute); $workshop->assessmentend = make_timestamp($workshop->assessmentendyear, $workshop->assessmentendmonth, $workshop->assessmentendday, $workshop->assessmentendhour, $workshop->assessmentendminute); $workshop->releasegrades = make_timestamp($workshop->releaseyear, $workshop->releasemonth, $workshop->releaseday, $workshop->releasehour, $workshop->releaseminute); if (!workshop_check_dates($workshop)) { return get_string('invaliddates', 'workshop'); } // set the workshop's type $wtype = 0; // 3 phases, no grading grades if ($workshop->includeself or $workshop->ntassessments) $wtype = 1; // 3 phases with grading grades if ($workshop->nsassessments) $wtype = 2; // 5 phases with grading grades $workshop->wtype = $wtype; // encode password if necessary if (!empty($workshop->password)) { $workshop->password = md5($workshop->password); } else { unset($workshop->password); } $workshop->id = $workshop->instance; if ($returnid = update_record("workshop", $workshop)) { $dates = array( 'submissionstart' => $workshop->submissionstart, 'submissionend' => $workshop->submissionend, 'assessmentstart' => $workshop->assessmentstart, 'assessmentend' => $workshop->assessmentend ); $moduleid = get_field('modules', 'id', 'name', 'workshop'); foreach ($dates as $type => $date) { if ($event = get_record('event', 'modulename', 'workshop', 'instance', $workshop->id, 'eventtype', $type)) { $event->name = get_string($type.'event','workshop', $workshop->name); $event->description = $workshop->description; $event->eventtype = $type; $event->timestart = $date; update_event($event); } else if ($date) { $event = NULL; $event->name = get_string($type.'event','workshop', $workshop->name); $event->description = $workshop->description; $event->courseid = $workshop->course; $event->groupid = 0; $event->userid = 0; $event->modulename = 'workshop'; $event->instance = $workshop->instance; $event->eventtype = $type; $event->timestart = $date; $event->timeduration = 0; $event->visible = get_field('course_modules', 'visible', 'module', $moduleid, 'instance', $workshop->id); add_event($event); } } } if (time() > $workshop->assessmentstart) { // regrade all the submissions... set_field("workshop_submissions", "nassessments", 0, "workshopid", $workshop->id); workshop_grade_assessments($workshop); } return $returnid; } /////////////////////////////////////////////////////////////////////////////// function workshop_user_complete($course, $user, $mod, $workshop) { if ($submission = workshop_get_student_submission($workshop, $user)) { if ($basedir = workshop_file_area($workshop, $user)) { if ($files = get_directory_list($basedir)) { $countfiles = count($files).' '.get_string('submissions', 'workshop'); foreach ($files as $file) { $countfiles .= "; $file"; } } } print_simple_box_start(); echo $submission->description.'
'; if (!empty($countfiles)) { echo $countfiles,'
'; } workshop_print_feedback($course, $submission); print_simple_box_end(); } else { print_string('notsubmittedyet', 'workshop'); } } ////////////////////////////////////////////////////////////////////////////////////// function workshop_print_feedback($course, $submission) { global $CFG, $RATING; if (! $feedbacks = get_records('workshop_assessments', 'submissionid', $submission->id)) { return; } $strgrade = get_string('grade'); $strnograde = get_string('nograde'); foreach ($feedbacks as $feedback) { if (! $user = get_record('user', 'id', $feedback->userid)) { /// Weird error but we'll just ignore it and continue with other feedback continue; } echo ''; echo ''; echo ''; echo ''; echo ''; echo '
'; print_user_picture($user->id, $course->id, $user->picture); echo ''.fullname($user).''; echo ''.userdate($feedback->timegraded).''; echo '
 '; if ($feedback->grade) { echo $strgrade.': '.$feedback->grade; } else { echo $strnograde; } echo ''.format_text($feedback->generalcomment).''; echo ''.format_text($feedback->teachercomment).''; echo '
'; } } /////////////////////////////////////////////////////////////////////////////// function workshop_user_outline($course, $user, $mod, $workshop) { if ($submissions = workshop_get_user_submissions($workshop, $user)) { $result->info = count($submissions)." ".get_string("submissions", "workshop"); // workshop_get_user_submissions returns the newest one first foreach ($submissions as $submission) { $result->time = $submission->timecreated; break; } return $result; } return NULL; } ////////////////////////////////////////////////////////////////////////////////////// function workshop_get_participants($workshopid) { //Returns the users with data in one workshop //(users with records in workshop_submissions, workshop_assessments and workshop_comments, students) global $CFG; //Get students from workshop_submissions $st_submissions = get_records_sql("SELECT DISTINCT u.id, u.id FROM {$CFG->prefix}user u, {$CFG->prefix}workshop_submissions s WHERE s.workshopid = '$workshopid' and u.id = s.userid"); //Get students from workshop_assessments $st_assessments = get_records_sql("SELECT DISTINCT u.id, u.id FROM {$CFG->prefix}user u, {$CFG->prefix}workshop_assessments a WHERE a.workshopid = '$workshopid' and u.id = a.userid"); //Get students from workshop_comments $st_comments = get_records_sql("SELECT DISTINCT u.id, u.id FROM {$CFG->prefix}user u, {$CFG->prefix}workshop_comments c WHERE c.workshopid = '$workshopid' and u.id = c.userid"); //Add st_assessments to st_submissions if ($st_assessments) { foreach ($st_assessments as $st_assessment) { $st_submissions[$st_assessment->id] = $st_assessment; } } //Add st_comments to st_submissions if ($st_comments) { foreach ($st_comments as $st_comment) { $st_submissions[$st_comment->id] = $st_comment; } } //Return st_submissions array (it contains an array of unique users) return ($st_submissions); } ////////////////////////////////////////////////////////////////////////////////////// function workshop_get_recent_mod_activity(&$activities, &$index, $sincetime, $courseid, $workshop="0", $user="", $groupid="") { // Returns all workshop posts since a given time. If workshop is specified then // this restricts the results global $CFG; if ($workshop) { $workshopselect = " AND cm.id = '$workshop'"; } else { $workshopselect = ""; } if ($user) { $userselect = " AND u.id = '$user'"; } else { $userselect = ""; } $posts = get_records_sql("SELECT s.*, u.firstname, u.lastname, u.picture, cm.instance, w.name, cm.section, cm.groupmode, cm.course, cm.groupingid, cm.groupmembersonly, cm.id as cmid FROM {$CFG->prefix}workshop_submissions s, {$CFG->prefix}user u, {$CFG->prefix}course_modules cm, {$CFG->prefix}workshop w WHERE s.timecreated > '$sincetime' $workshopselect AND s.userid = u.id $userselect AND w.course = '$courseid' AND cm.instance = w.id AND cm.course = w.course AND s.workshopid = w.id ORDER BY s.id"); if (empty($posts)) { return; } foreach ($posts as $post) { if ((empty($groupid) || groups_is_member($groupid, $post->userid)) && groups_course_module_visible($post)) { $tmpactivity = new Object; $tmpactivity->type = "workshop"; $tmpactivity->defaultindex = $index; $tmpactivity->instance = $post->instance; $tmpactivity->name = $post->name; $tmpactivity->section = $post->section; $tmpactivity->content->id = $post->id; $tmpactivity->content->title = $post->title; $tmpactivity->user->userid = $post->userid; $tmpactivity->user->fullname = fullname($post); $tmpactivity->user->picture = $post->picture; $tmpactivity->cmid = $post->cmid; $tmpactivity->timestamp = $post->timecreated; $activities[] = $tmpactivity; $index++; } } return; } ////////////////////////////////////////////////////////////////////////////////////// function workshop_print_recent_mod_activity($activity, $course, $detail=false) { global $CFG; echo ''; if (!empty($activity->content->parent)) { $openformat = ""; $closeformat = ""; } else { $openformat = ""; $closeformat = ""; } echo ""; echo "
"; print_user_picture($activity->user->userid, $course, $activity->user->picture); echo "$openformat"; if ($detail) { echo "modpixpath/$activity->type/icon.gif\" ". "class=\"icon\" alt=\"".strip_tags(format_string($activity->name,true))."\" /> "; } echo "wwwroot/mod/workshop/submissions.php?" . "id=" . $activity->cmid . "&action=showsubmission&sid=".$activity->content->id."\">".$activity->content->title; echo "$closeformat"; echo "
"; echo "wwwroot/user/view.php?id=" . $activity->user->userid . "&course=" . "$course\">" . $activity->user->fullname . ""; echo " - " . userdate($activity->timestamp) . "
"; return; } ////////////////////////////////////////////////////////////////////////////////////// // Non-standard workshop functions /////////////////////////////////////////////////////////////////////////////////////////////// function workshop_compare_assessments($workshop, $assessment1, $assessment2) { global $WORKSHOP_ASSESSMENT_COMPS, $WORKSHOP_EWEIGHTS; // first get the assignment elements for maxscores... $elementsraw = get_records("workshop_elements", "workshopid", $workshop->id, "elementno ASC"); foreach ($elementsraw as $element) { $maxscore[] = $element->maxscore; // to renumber index 0,1,2... $weight[] = $WORKSHOP_EWEIGHTS[$element->weight]; // get real value and renumber index 0,1,2... } $grades = array(); for ($i = 0; $i < 2; $i++) { if ($i) { $rawgrades = get_records("workshop_grades", "assessmentid", $assessment1->id, "elementno ASC"); } else { $rawgrades = get_records("workshop_grades", "assessmentid", $assessment2->id, "elementno ASC"); } if ($rawgrades) { foreach ($rawgrades as $grade) { $grades[$i][] = $grade->grade; } } } $sumdiffs = 0; $sumweights = 0; switch ($workshop->gradingstrategy) { case 1 : // accumulative grading and... case 4 : // ...rubic grading for ($i=0; $i < $workshop->nelements; $i++) { $diff = ($grades[0][$i] - $grades[1][$i]) * $weight[$i] / $maxscore[$i]; $sumdiffs += $diff * $diff; // use squared distances $sumweights += $weight[$i]; } break; case 2 : // error banded grading // ignore maxscores here, the grades are either 0 or 1, for ($i=0; $i < $workshop->nelements; $i++) { $diff = ($grades[0][$i] - $grades[1][$i]) * $weight[$i]; $sumdiffs += $diff * $diff; // use squared distances $sumweights += $weight[$i]; } break; case 3 : // criterion grading // here we only need to look at the difference between the "zero" grade elements $diff = ($grades[0][0] - $grades[1][0]) / (count($elementsraw) - 1); $sumdiffs = $diff * $diff; $sumweights = 1; break; } // convert to a sensible grade (always out of 100) $COMP = (object)$WORKSHOP_ASSESSMENT_COMPS[$workshop->assessmentcomps]; $factor = $COMP->value; $gradinggrade = (($factor - ($sumdiffs / $sumweights)) / $factor) * 100; if ($gradinggrade < 0) { $gradinggrade = 0; } return $gradinggrade; } ////////////////////////////////////////////////////////////////////////////////////// function workshop_count_assessments($submission) { // Return the (real) assessments for this submission, $timenow = time(); return count_records_select("workshop_assessments", "submissionid = $submission->id AND timecreated < $timenow"); } ////////////////////////////////////////////////////////////////////////////////////// function workshop_count_ungraded_assessments($workshop) { // function returns the number of ungraded assessments by students global $CFG; $timenow = time(); $n = 0; // get all the cold assessments that have not been graded if ($assessments = get_records_select("workshop_assessments", "workshopid = $workshop->id AND (timecreated + $CFG->maxeditingtime) < $timenow AND timegraded = 0")) { foreach ($assessments as $assessment) { if (workshop_is_student($workshop, $assessment->userid)) { $n++; } } } return $n; } ////////////////////////////////////////////////////////////////////////////////////// function workshop_file_area($workshop, $submission) { return make_upload_directory( workshop_file_area_name($workshop, $submission) ); } ////////////////////////////////////////////////////////////////////////////////////// function workshop_file_area_name($workshop, $submission) { // Creates a directory file name, suitable for make_upload_directory() global $CFG; return "$workshop->course/$CFG->moddata/workshop/$submission->id"; } /////////////////////////////////////////////////////////////////////////////////////////////// function workshop_get_agree_logs($course, $timestart) { // get the "agree" entries for this user (the assessment owner) and add the first and last names // the last two probably wont be used... global $CFG, $USER; if (empty($USER->id)) { return false; } $timethen = time() - $CFG->maxeditingtime; return get_records_sql("SELECT l.time, l.url, u.firstname, u.lastname, a.workshopid, a.userid, e.name FROM {$CFG->prefix}log l, {$CFG->prefix}workshop e, {$CFG->prefix}workshop_submissions s, {$CFG->prefix}workshop_assessments a, {$CFG->prefix}user u WHERE l.time > $timestart AND l.time < $timethen AND l.course = $course->id AND l.module = 'workshop' AND l.action = 'agree' AND a.id = l.info AND s.id = a.submissionid AND a.userid = $USER->id AND u.id = s.userid AND e.id = a.workshopid"); } /////////////////////////////////////////////////////////////////////////////////////////////// function workshop_get_assess_logs($course, $timestart) { // get the "assess" entries for this user and add the first and last names... global $CFG, $USER; if (empty($USER->id)) { return false; } $timethen = time() - $CFG->maxeditingtime; return get_records_sql("SELECT l.time, l.url, u.firstname, u.lastname, a.workshopid, a.userid, e.name FROM {$CFG->prefix}log l, {$CFG->prefix}workshop e, {$CFG->prefix}workshop_submissions s, {$CFG->prefix}workshop_assessments a, {$CFG->prefix}user u WHERE l.time > $timestart AND l.time < $timethen AND l.course = $course->id AND l.module = 'workshop' AND l.action = 'assess' AND a.id = ".sql_cast_char2int('l.info') ." AND s.id = a.submissionid AND s.userid = $USER->id AND u.id = a.userid AND e.id = a.workshopid"); } ////////////////////////////////////////////////////////////////////////////////////// function workshop_get_assessments($submission, $all = '', $order = '') { // Return assessments for this submission ordered oldest first, newest last // new assessments made within the editing time are NOT returned unless they // belong to the user or the second argument is set to ALL global $CFG, $USER; $timenow = time(); if (!$order) { $order = "timecreated DESC"; } if ($all != 'ALL') { return get_records_select("workshop_assessments", "(submissionid = $submission->id) AND ((timecreated < $timenow - $CFG->maxeditingtime) or ((timecreated < $timenow) AND (userid = $USER->id)))", $order); } else { return get_records_select("workshop_assessments", "submissionid = $submission->id AND (timecreated < $timenow)", $order); } } /////////////////////////////////////////////////////////////////////////////////////////////// function workshop_get_comment_logs($course, $timestart) { // get the "comment" entries for this user and add the first and last names (which may not be used)... global $CFG, $USER; if (empty($USER->id)) { return false; } $timethen = time() - $CFG->maxeditingtime; return get_records_sql("SELECT l.time, l.url, u.firstname, u.lastname, a.workshopid, e.name FROM {$CFG->prefix}log l, {$CFG->prefix}workshop e, {$CFG->prefix}workshop_submissions s, {$CFG->prefix}workshop_assessments a, {$CFG->prefix}workshop_comments c, {$CFG->prefix}user u WHERE l.time > $timestart AND l.time < $timethen AND l.course = $course->id AND l.module = 'workshop' AND l.action = 'comment' AND c.id = l.info AND c.userid != $USER->id AND a.id = c.assessmentid AND s.id = a.submissionid AND (s.userid = $USER->id OR a.userid = $USER->id) AND u.id = a.userid AND e.id = a.workshopid"); } /////////////////////////////////////////////////////////////////////////////////////////////// function workshop_get_grade_logs($course, $timestart) { // get the "grade" entries for this user and add the first and last names (of submission owner, // better to get name of teacher... // ...but not available in assessment record...) global $CFG, $USER; if (empty($USER->id)) { return false; } $timethen = time() - $CFG->maxeditingtime; return get_records_sql("SELECT l.time, l.url, u.firstname, u.lastname, a.workshopid, e.name FROM {$CFG->prefix}log l, {$CFG->prefix}workshop e, {$CFG->prefix}workshop_submissions s, {$CFG->prefix}workshop_assessments a, {$CFG->prefix}user u WHERE l.time > $timestart AND l.time < $timethen AND l.course = $course->id AND l.module = 'workshop' AND l.action = 'grade' AND a.id = ".sql_cast_char2int('l.info') ." AND s.id = a.submissionid AND a.userid = $USER->id AND u.id = s.userid AND e.id = a.workshopid"); } ////////////////////////////////////////////////////////////////////////////////////// function workshop_get_student_submission($workshop, $user) { // Return a submission for a particular user global $CFG; $submission = get_record("workshop_submissions", "workshopid", $workshop->id, "userid", $user->id); if (!empty($submission->timecreated)) { return $submission; } return NULL; } ////////////////////////////////////////////////////////////////////////////////////// function workshop_get_student_submissions($workshop, $order = "title") { // Return all ENROLLED student submissions global $CFG; if ($order == "title") { $order = "s.title"; } if ($order == "name") { $order = "a.lastname, a.firstname"; } if ($order == "time") { $order = "s.timecreated ASC"; } if (!$students = workshop_get_students($workshop)) { return false; } $list = "("; foreach ($students as $student) { $list .= "$student->id,"; } $list = rtrim($list, ',').")"; return get_records_sql("SELECT s.* FROM {$CFG->prefix}workshop_submissions s, {$CFG->prefix}user a WHERE s.userid IN $list AND s.workshopid = $workshop->id AND s.timecreated > 0 AND s.userid = a.id ORDER BY $order"); } /////////////////////////////////////////////////////////////////////////////////////////////// function workshop_get_submit_logs($course, $timestart) { // get the "submit" entries and add the first and last names... global $CFG, $USER; $timethen = time() - $CFG->maxeditingtime; return get_records_sql("SELECT l.time, l.url, u.firstname, u.lastname, l.info as workshopid, e.name FROM {$CFG->prefix}log l, {$CFG->prefix}workshop e, {$CFG->prefix}user u WHERE l.time > $timestart AND l.time < $timethen AND l.course = $course->id AND l.module = 'workshop' AND l.action = 'submit' AND e.id = ".sql_cast_char2int('l.info') ." AND u.id = l.userid"); } ////////////////////////////////////////////////////////////////////////////////////// function workshop_get_unmailed_assessments($cutofftime) { /// Return list of assessments that have not been mailed out global $CFG; return get_records_sql("SELECT a.*, g.course, g.name FROM {$CFG->prefix}workshop_assessments a, {$CFG->prefix}workshop g WHERE a.mailed = 0 AND a.timecreated < $cutofftime AND g.id = a.workshopid AND g.releasegrades < $cutofftime"); } ////////////////////////////////////////////////////////////////////////////////////// function workshop_get_unmailed_comments($cutofftime) { /// Return list of comments that have not been mailed out global $CFG; return get_records_sql("SELECT c.*, g.course, g.name FROM {$CFG->prefix}workshop_comments c, {$CFG->prefix}workshop g WHERE c.mailed = 0 AND c.timecreated < $cutofftime AND g.id = c.workshopid"); } ////////////////////////////////////////////////////////////////////////////////////// function workshop_get_unmailed_graded_assessments($cutofftime) { /// Return list of graded assessments that have not been mailed out global $CFG; return get_records_sql("SELECT a.*, g.course, g.name FROM {$CFG->prefix}workshop_assessments a, {$CFG->prefix}workshop g WHERE a.mailed = 0 AND a.timegraded < $cutofftime AND a.timegraded > 0 AND g.id = a.workshopid"); } ////////////////////////////////////////////////////////////////////////////////////// function workshop_get_unmailed_resubmissions($cutofftime) { /// Return list of assessments of resubmissions that have not been mailed out global $CFG; return get_records_sql("SELECT a.*, w.course, w.name FROM {$CFG->prefix}workshop_assessments a, {$CFG->prefix}workshop w WHERE a.mailed = 0 AND a.resubmission = 1 AND w.id = a.workshopid"); } ////////////////////////////////////////////////////////////////////////////////////// function workshop_get_user_assessments($workshop, $user) { // Return all the user's assessments, newest first, oldest last (hot, warm and cold ones) return get_records_select("workshop_assessments", "workshopid = $workshop->id AND userid = $user->id", "timecreated DESC"); } ////////////////////////////////////////////////////////////////////////////////////// function workshop_get_user_submissions($workshop, $user) { // return real submissions of user newest first, oldest last. Ignores the dummy submissions // which get created to hold the final grades for users that make no submissions return get_records_select("workshop_submissions", "workshopid = $workshop->id AND userid = $user->id AND timecreated > 0", "timecreated DESC" ); } ////////////////////////////////////////////////////////////////////////////////////// function workshop_grade_assessments($workshop, $verbose=false) { global $WORKSHOP_EWEIGHTS; // timeout after 10 minutes @set_time_limit(600); $timenow = time(); // set minumim value for the variance (of the elements) $minvar = 0.05; // check when the standard deviations were calculated $oldtotalassessments = get_field("workshop_elements", "totalassessments", "workshopid", $workshop->id, "elementno", 0); $totalassessments = count_records("workshop_assessments", "workshopid", $workshop->id); // calculate the std. devs every 10 assessments for low numbers of assessments, thereafter every 100 new assessments if ((($totalassessments < 100) and (($totalassessments - $oldtotalassessments) > 10)) or (($totalassessments - $oldtotalassessments) > 100)) { // calculate the means for each submission using just the "good" assessments if ($submissions = get_records("workshop_submissions", "workshopid", $workshop->id)) { foreach ($submissions as $submission) { $nassessments[$submission->id] = 0; if ($assessments = workshop_get_assessments($submission)) { foreach ($assessments as $assessment) { // test if assessment is "good", a teacher assessment always "good", but may be weighted out if (workshop_is_teacher($workshop, $assessment->userid)) { if (!$workshop->teacherweight) { // drop teacher's assessment as weight is zero continue; } } elseif ((!$assessment->gradinggrade and $assessment->timegraded) or ($workshop->agreeassessments and !$assessment->timeagreed)) { // it's a duff assessment, or it's not been agreed continue; } if (isset($num[$submission->id])) { if (workshop_is_teacher($workshop, $assessment->userid)) { $num[$submission->id] += $workshop->teacherweight; // weight teacher's assessment } else { $num[$submission->id]++; // number of assessments } $nassessments[$submission->id]++; } else { if (workshop_is_teacher($workshop, $assessment->userid)) { $num[$submission->id] = $workshop->teacherweight; } else { $num[$submission->id] = 1; } $nassessments[$submission->id] = 1; } for ($i = 0; $i < $workshop->nelements; $i++) { $grade = get_field("workshop_grades", "grade", "assessmentid", $assessment->id, "elementno", $i); if (isset($sum[$submission->id][$i])) { if (workshop_is_teacher($workshop, $assessment->userid)) { $sum[$submission->id][$i] += $workshop->teacherweight * $grade; // teacher's grade } else { $sum[$submission->id][$i] += $grade; // student's grade } } else { if (workshop_is_teacher($workshop, $assessment->userid)) { $sum[$submission->id][$i] = $workshop->teacherweight * $grade; // teacher's grade } else { $sum[$submission->id][$i] = $grade; // students's grade } } } } } } if (!isset($num)) { // no assessments yet return; } reset($num); // calculate the means for each submission $total = 0; foreach ($num as $submissionid => $n) { if ($n) { // stop division by zero for ($i = 0; $i < $workshop->nelements; $i++) { $mean[$submissionid][$i] = $sum[$submissionid][$i] / $n; // echo "Submission: $submissionid; Element: $i; Mean: {$mean[$submissionid][$i]}
\n"; } $total += $n; // weighted total } } if ($verbose) { echo "

".get_string("numberofsubmissions", "workshop", count($num))."
\n"; echo get_string("numberofassessmentsweighted", "workshop", $total)."

\n"; } // now get an estimate of the standard deviation of each element in the assessment // this is just a rough measure, all assessments are included and teacher's assesments are not weighted $n = 0; for ($i = 0; $i < $workshop->nelements; $i++) { $var[$i] = 0; } foreach ($submissions as $submission) { if ($assessments = workshop_get_assessments($submission)) { foreach ($assessments as $assessment) { $n++; for ($i = 0; $i < $workshop->nelements; $i++) { $grade = get_field("workshop_grades", "grade", "assessmentid", $assessment->id, "elementno", $i); $temp = $mean[$submission->id][$i] - $grade; $var[$i] += $temp * $temp; } } } } for ($i = 0; $i < $workshop->nelements; $i++) { if ($n > 1) { $sd[$i] = sqrt($var[$i] / ($n - 1)); } else { $sd[$i] = 0; } set_field("workshop_elements", "stddev", $sd[$i], "workshopid", $workshop->id, "elementno", $i); set_field("workshop_elements", "totalassessments", $totalassessments, "workshopid", $workshop->id, "elementno", $i); if ($verbose) { echo get_string("standarddeviationofelement", "workshop", $i+1)." $sd[$i]
"; if ($sd[$i] <= $minvar) { print_string("standarddeviationnote", "workshop")."
\n"; } } } } } // this section looks at each submission if the number of assessments made has increased it recalculates the // grading grades for those assessments // first get the assignment elements for the weights and the stddevs... if ($elementsraw = get_records("workshop_elements", "workshopid", $workshop->id, "elementno ASC")) { foreach ($elementsraw as $element) { $weight[] = $element->weight; // to renumber index 0,1,2... $sd[] = $element->stddev; // to renumber index 0,1,2... } } unset($num); // may have been used in calculating stddevs unset($sum); // ditto if ($submissions = get_records("workshop_submissions", "workshopid", $workshop->id)) { foreach ($submissions as $submission) { // see if the number of assessments has changed $nassessments = workshop_count_assessments($submission); if ($submission->nassessments <> $nassessments) { // ...if there are three or more assessments calculate the variance of each assessment. // Use the variance to find the "best" assessment. (When there is only one or two assessments they // are not altered by this routine.) if ($verbose) { echo "Processing submission $submission->id ($nassessments asessments)...\n"; } if ($nassessments > 2) { $num = 0; // weighted number of assessments for ($i = 0; $i < $workshop->nelements; $i++) { $sum[$i] = 0; // weighted sum of grades } if ($assessments = workshop_get_assessments($submission)) { // first calculate the mean grades for each element foreach ($assessments as $assessment) { // test if assessment is "good", a teacher assessment always "good", but may be weighted out if (workshop_is_teacher($workshop, $assessment->userid)) { if (!$workshop->teacherweight) { // drop teacher's assessment as weight is zero continue; } } else if ((!$assessment->gradinggrade and $assessment->timegraded) or ($workshop->agreeassessments and !$assessment->timeagreed)) { // it's a duff assessment, or it's not been agreed continue; } if (workshop_is_teacher($workshop, $assessment->userid)) { $num += $workshop->teacherweight; // weight teacher's assessment } else { $num++; // student assessment just add one } for ($i = 0; $i < $workshop->nelements; $i++) { $grade = get_field("workshop_grades", "grade", "assessmentid", $assessment->id, "elementno", $i); if (workshop_is_teacher($workshop, $assessment->userid)) { $sum[$i] += $workshop->teacherweight * $grade; // teacher's grade } else { $sum[$i] += $grade; // student's grade } } } if ($num) { // could all the assessments be duff? for ($i = 0; $i < $workshop->nelements; $i++) { $mean[$i] = $sum[$i] / $num; if ($verbose) echo "Submission: $submission->id; Element: $i; Mean: {$mean[$i]}\n"; } } else { continue; // move to the next submission } // run through the assessments again to see which is the "best" one (the one // closest to the mean) $lowest = 10e9; foreach ($assessments as $assessment) { if ($workshop->agreeassessments and !$assessment->timeagreed) { // ignore assessments that have not been agreed continue; } $var = 0; for ($i = 0; $i < $workshop->nelements; $i++) { $grade = get_field("workshop_grades", "grade", "assessmentid", $assessment->id, "elementno", $i); if ($sd[$i] > $minvar) { $temp = ($mean[$i] - $grade) * $WORKSHOP_EWEIGHTS[$weight[$i]] / $sd[$i]; } else { $temp = 0; } $var += $temp * $temp; } // find the "best" assessment of this submission if ($lowest > $var) { $lowest = $var; $bestassessmentid = $assessment->id; } } if (!$best = get_record("workshop_assessments", "id", $bestassessmentid)) { notify("Workshop grade assessments: cannot find best assessment"); continue; } if ($verbose) { echo "Best assessment is $bestassessmentid;\n"; } foreach ($assessments as $assessment) { // don't overwrite teacher's grade if ($assessment->teachergraded) { continue; } if ($assessment->id == $bestassessmentid) { // it's the best one, set the grading grade to the maximum set_field("workshop_assessments", "gradinggrade", 100, "id", $assessment->id); set_field("workshop_assessments", "timegraded", $timenow, "id", $assessment->id); } else { // it's one of the pack, compare with the best... $gradinggrade = round(workshop_compare_assessments($workshop, $best, $assessment)); // ...and save the grade for the assessment set_field("workshop_assessments", "gradinggrade", $gradinggrade, "id", $assessment->id); set_field("workshop_assessments", "timegraded", $timenow, "id", $assessment->id); } } } } else { // there are less than 3 assessments for this submission if ($assessments = workshop_get_assessments($submission)) { foreach ($assessments as $assessment) { if (!$assessment->timegraded and !$assessment->teachergraded) { // set the grading grade to the maximum and say it's been graded set_field("workshop_assessments", "gradinggrade", 100, "id", $assessment->id); set_field("workshop_assessments", "timegraded", $timenow, "id", $assessment->id); } } } } // set the number of assessments for this submission set_field("workshop_submissions", "nassessments", $nassessments, "id", $submission->id); } } } return; } ////////////////////////////////////////////////////////////////////////////////////// function workshop_gradinggrade($workshop, $student) { // returns the current (external) grading grade of the based on their (cold) assessments // (needed as it's called by grade) global $CFG; require_once(dirname(__FILE__) . '/locallib.php'); $gradinggrade = 0; if ($assessments = workshop_get_user_assessments_done($workshop, $student)) { $n = 0; foreach ($assessments as $assessment) { $gradinggrade += $assessment->gradinggrade; $n++; } if ($n < ($workshop->ntassessments + $workshop->nsassessments)) { // the minimum students should do $n = $workshop->ntassessments + $workshop->nsassessments; } $gradinggrade = $gradinggrade / $n; } return number_format($gradinggrade * $workshop->gradinggrade / 100, 1); } ////////////////////////////////////////////////////////////////////////////////////// function workshop_submission_grade($workshop, $submission) { // returns the current (external) grade of the submission based on the "good" (cold) assessments // (needed as it's called by grade) $grade = 0; if ($assessments = workshop_get_assessments($submission)) { $n = 0; foreach ($assessments as $assessment) { if ($workshop->agreeassessments and !$assessment->timeagreed) { // ignore assessments which have not been agreed continue; } if ($assessment->gradinggrade or !$assessment->timegraded) { // a good assessment (or one that has not been graded yet) if (workshop_is_teacher($workshop, $assessment->userid)) { $timenow = time(); if ($timenow > $workshop->releasegrades) { // teacher's grade is available $grade += $workshop->teacherweight * $assessment->grade; $n += $workshop->teacherweight; } } else { $grade += $assessment->grade; $n++; } } } if ($n) { // stop division by zero $grade = $grade / $n; } } return number_format($grade * $workshop->grade / 100, 1); } ///////////////////////////////////////////////////////////////////////////// function workshop_fullname($userid, $courseid) { global $CFG; if (!$user = get_record('user', 'id', $userid)) { return ''; } return ''. fullname($user).''; } function workshop_get_view_actions() { return array('view','view all'); } function workshop_get_post_actions() { return array('agree','assess','comment','grade','newattachment','removeattachments','resubmit','submit'); } /** * Returns all other caps used in module */ function workshop_get_extra_capabilities() { return array('moodle/site:accessallgroups', 'moodle/site:viewfullnames'); } /** * Called by course/reset.php * @param $mform form passed by reference */ function workshop_reset_course_form_definition(&$mform) { $mform->addElement('header', ' workshopheader', get_string('modulenameplural', 'workshop')); $mform->addElement('checkbox', 'reset_workshop_all', get_string('resetworkshopall','workshop')); } /** * Course reset form defaults. */ function workshop_reset_course_form_defaults($course) { return array('reset_workshop_all'=>1); } /** * This function is used by the reset_course_userdata function in moodlelib. * This function will remove all issued certificates from the specified course * @param $data the data submitted from the reset course. * @return array status array */ function workshop_reset_userdata($data) { global $CFG; $status = array(); if (!empty($data->reset_workshop_all)) { $workshopids = get_records('workshop', 'course', $data->courseid, '', 'id'); if (!empty($workshopids)) { $workshopidslist = implode(',', array_keys($workshopids)); // delete all students participation info, keep assessment forms elements and stock comments delete_records_select('workshop_submissions', "workshopid IN ($workshopidslist)"); delete_records_select('workshop_grades', "workshopid IN ($workshopidslist)"); delete_records_select('workshop_comments', "workshopid IN ($workshopidslist)"); delete_records_select('workshop_assessments', "workshopid IN ($workshopidslist)"); set_field_select('workshop_elements', 'stddev', 0, "workshopid IN ($workshopidslist)"); set_field_select('workshop_elements', 'totalassessments', 0, "workshopid IN ($workshopidslist)"); } // delete module data (submissions) $basedir = $CFG->dataroot.'/'.$data->courseid.'/'.$CFG->moddata.'/workshop/'; remove_dir("$basedir"); // fill return info $status[] = array('component' => get_string('modulenameplural', 'workshop'), 'item' => get_string('resetworkshopall', 'workshop'), 'error' => false); } return $status; } ?>