3 // workshop constants and standard Moodle functions plus the workshop functions
4 // called by the standard functions
6 // see also locallib.php for other non-standard workshop functions
8 require_once($CFG->libdir
.'/filelib.php');
10 /*** Constants **********************************/
13 $WORKSHOP_EWEIGHTS = array( 0 => -4.0, 1 => -2.0, 2 => -1.5, 3 => -1.0, 4 => -0.75, 5 => -0.5, 6 => -0.25,
14 7 => 0.0, 8 => 0.25, 9 => 0.5, 10 => 0.75, 11=> 1.0, 12 => 1.5, 13=> 2.0,
17 $WORKSHOP_FWEIGHTS = array( 0 => 0, 1 => 0.1, 2 => 0.25, 3 => 0.5, 4 => 0.75, 5 => 1.0, 6 => 1.5,
18 7 => 2.0, 8 => 3.0, 9 => 5.0, 10 => 7.5, 11=> 10.0, 12=>50.0);
21 $WORKSHOP_ASSESSMENT_COMPS = array (
22 0 => array('name' => get_string('verylax', 'workshop'), 'value' => 1),
23 1 => array('name' => get_string('lax', 'workshop'), 'value' => 0.6),
24 2 => array('name' => get_string('fair', 'workshop'), 'value' => 0.4),
25 3 => array('name' => get_string('strict', 'workshop'), 'value' => 0.33),
26 4 => array('name' => get_string('verystrict', 'workshop'), 'value' => 0.2) );
29 /*** Moodle 1.7 compatibility functions *****
31 ********************************************/
32 function workshop_context($workshop) {
33 //TODO: add some $cm caching if needed
34 if (is_object($workshop)) {
35 $workshop = $workshop->id
;
37 if (! $cm = get_coursemodule_from_instance('workshop', $workshop)) {
38 error('Course Module ID was incorrect');
41 return get_context_instance(CONTEXT_MODULE
, $cm->id
);
44 function workshop_is_teacher($workshop, $userid=NULL) {
45 return has_capability('mod/workshop:manage', workshop_context($workshop), $userid);
48 function workshop_is_teacheredit($workshop, $userid=NULL) {
49 return has_capability('mod/workshop:manage', workshop_context($workshop), $userid)
50 and has_capability('moodle/site:accessallgroups', workshop_context($workshop), $userid);
53 function workshop_is_student($workshop, $userid=NULL) {
54 return has_capability('mod/workshop:participate', workshop_context($workshop), $userid);
57 function workshop_get_students($workshop, $sort='u.lastaccess', $fields='u.*') {
58 return $users = get_users_by_capability(workshop_context($workshop), 'mod/workshop:participate', $fields, $sort);
61 function workshop_get_teachers($workshop, $sort='u.lastaccess', $fields='u.*') {
62 return $users = get_users_by_capability(workshop_context($workshop), 'mod/workshop:manage', $fields, $sort);
66 /*** Standard Moodle functions ******************
67 workshop_add_instance($workshop)
68 workshop_check_dates($workshop)
70 workshop_delete_instance($id)
71 workshop_grades($workshopid)
72 workshop_print_recent_activity(&$logs, $isteacher=false)
73 workshop_refresh_events($workshop)
74 workshop_update_instance($workshop)
75 workshop_user_complete($course, $user, $mod, $workshop)
76 workshop_user_outline($course, $user, $mod, $workshop)
77 **********************************************/
79 ///////////////////////////////////////////////////////////////////////////////
80 function workshop_add_instance($workshop) {
81 // Given an object containing all the necessary data,
82 // (defined by the form in mod.html) this function
83 // will create a new instance and return the id number
84 // of the new instance.
86 $workshop->timemodified
= time();
88 $workshop->submissionstart
= make_timestamp($workshop->submissionstartyear
,
89 $workshop->submissionstartmonth
, $workshop->submissionstartday
, $workshop->submissionstarthour
,
90 $workshop->submissionstartminute
);
92 $workshop->assessmentstart
= make_timestamp($workshop->assessmentstartyear
,
93 $workshop->assessmentstartmonth
, $workshop->assessmentstartday
, $workshop->assessmentstarthour
,
94 $workshop->assessmentstartminute
);
96 $workshop->submissionend
= make_timestamp($workshop->submissionendyear
,
97 $workshop->submissionendmonth
, $workshop->submissionendday
, $workshop->submissionendhour
,
98 $workshop->submissionendminute
);
100 $workshop->assessmentend
= make_timestamp($workshop->assessmentendyear
,
101 $workshop->assessmentendmonth
, $workshop->assessmentendday
, $workshop->assessmentendhour
,
102 $workshop->assessmentendminute
);
104 $workshop->releasegrades
= make_timestamp($workshop->releaseyear
,
105 $workshop->releasemonth
, $workshop->releaseday
, $workshop->releasehour
,
106 $workshop->releaseminute
);
108 if (!workshop_check_dates($workshop)) {
109 return get_string('invaliddates', 'workshop');
112 if ($returnid = insert_record("workshop", $workshop)) {
115 $event->name
= get_string('submissionstartevent','workshop', $workshop->name
);
116 $event->description
= $workshop->description
;
117 $event->courseid
= $workshop->course
;
120 $event->modulename
= 'workshop';
121 $event->instance
= $returnid;
122 $event->eventtype
= 'submissionstart';
123 $event->timestart
= $workshop->submissionstart
;
124 $event->timeduration
= 0;
127 $event->name
= get_string('submissionendevent','workshop', $workshop->name
);
128 $event->eventtype
= 'submissionend';
129 $event->timestart
= $workshop->submissionend
;
132 $event->name
= get_string('assessmentstartevent','workshop', $workshop->name
);
133 $event->eventtype
= 'assessmentstart';
134 $event->timestart
= $workshop->assessmentstart
;
137 $event->name
= get_string('assessmentendevent','workshop', $workshop->name
);
138 $event->eventtype
= 'assessmentend';
139 $event->timestart
= $workshop->assessmentend
;
146 ///////////////////////////////////////////////////////////////////////////////
147 // returns true if the dates are valid, false otherwise
148 function workshop_check_dates($workshop) {
149 // allow submission and assessment to start on the same date and to end on the same date
150 // but enforce non-empty submission period and non-empty assessment period.
151 return ($workshop->submissionstart
< $workshop->submissionend
and
152 $workshop->submissionstart
<= $workshop->assessmentstart
and
153 $workshop->assessmentstart
< $workshop->assessmentend
and
154 $workshop->submissionend
<= $workshop->assessmentend
);
158 ///////////////////////////////////////////////////////////////////////////////
159 function workshop_cron () {
160 // Function to be run periodically according to the moodle cron
164 // if there any ungraded assessments run the grading routine
165 if ($workshops = get_records("workshop")) {
166 foreach ($workshops as $workshop) {
167 // automatically grade assessments if workshop has examples and/or peer assessments
168 if ($workshop->gradingstrategy
and ($workshop->ntassessments
or $workshop->nsassessments
)) {
169 workshop_grade_assessments($workshop);
175 // Find all workshop notifications that have yet to be mailed out, and mails them
176 $cutofftime = $timenow - $CFG->maxeditingtime
;
178 // look for new assessments
179 if ($assessments = workshop_get_unmailed_assessments($cutofftime)) {
180 foreach ($assessments as $assessment) {
182 echo "Processing workshop assessment $assessment->id\n";
184 // only process the entry once
185 if (! set_field("workshop_assessments", "mailed", "1", "id", "$assessment->id")) {
186 echo "Could not update the mailed field for id $assessment->id\n";
189 if (! $submission = get_record("workshop_submissions", "id", "$assessment->submissionid")) {
190 echo "Could not find submission $assessment->submissionid\n";
193 if (! $workshop = get_record("workshop", "id", $submission->workshopid
)) {
194 echo "Could not find workshop id $submission->workshopid\n";
197 if (! $course = get_record("course", "id", $workshop->course
)) {
198 error("Could not find course id $workshop->course");
201 if (! $cm = get_coursemodule_from_instance("workshop", $workshop->id
, $course->id
)) {
202 error("Course Module ID was incorrect");
205 if (! $submissionowner = get_record("user", "id", "$submission->userid")) {
206 echo "Could not find user $submission->userid\n";
209 if (! $assessmentowner = get_record("user", "id", "$assessment->userid")) {
210 echo "Could not find user $assessment->userid\n";
213 if (! workshop_is_student($workshop, $submissionowner->id
) and !workshop_is_teacher($workshop,
214 $submissionowner->id
)) {
215 continue; // Not an active participant
217 if (! workshop_is_student($workshop, $assessmentowner->id
) and !workshop_is_teacher($workshop,
218 $assessmentowner->id
)) {
219 continue; // Not an active participant
221 // don't sent self assessment
222 if ($submissionowner->id
== $assessmentowner->id
) {
225 $strworkshops = get_string("modulenameplural", "workshop");
226 $strworkshop = get_string("modulename", "workshop");
228 // it's an assessment, tell the submission owner
229 $USER->lang
= $submissionowner->lang
;
230 $sendto = $submissionowner;
231 // "Your assignment \"$submission->title\" has been assessed by"
232 if (workshop_is_student($workshop, $assessmentowner->id
)) {
233 $msg = get_string("mail1", "workshop", $submission->title
)." a $course->student.\n";
236 $msg = get_string("mail1", "workshop", $submission->title
).
237 " ".fullname($assessmentowner)."\n";
239 // "The comments and grade can be seen in the workshop assignment '$workshop->name'
240 // I have taken the following line out because the info is repeated below.
241 // $msg .= get_string("mail2", "workshop", $workshop->name)."\n\n";
243 $postsubject = "$course->shortname: $strworkshops: ".format_string($workshop->name
,true);
244 $posttext = "$course->shortname -> $strworkshops -> ".format_string($workshop->name
,true)."\n";
245 $posttext .= "---------------------------------------------------------------------\n";
247 // "The comments and grade can be seen in ..."
248 $posttext .= get_string("mail2", "workshop",
249 format_string($workshop->name
,true).", $CFG->wwwroot/mod/workshop/view.php?id=$cm->id")."\n";
250 $posttext .= "---------------------------------------------------------------------\n";
251 if ($sendto->mailformat
== 1) { // HTML
252 $posthtml = "<p><font face=\"sans-serif\">".
253 "<a href=\"$CFG->wwwroot/course/view.php?id=$course->id\">$course->shortname</a> ->".
254 "<a href=\"$CFG->wwwroot/mod/workshop/index.php?id=$course->id\">$strworkshops</a> ->".
255 "<a href=\"$CFG->wwwroot/mod/workshop/view.php?id=$cm->id\">".format_string($workshop->name
,true)."</a></font></p>";
256 $posthtml .= "<hr><font face=\"sans-serif\">";
257 $posthtml .= "<p>$msg</p>";
258 $posthtml .= "<p>".get_string("mail2", "workshop",
259 " <a href=\"$CFG->wwwroot/mod/workshop/view.php?id=$cm->id\">".format_string($workshop->name
,true)."</a>")."</p></font><hr>";
264 if (!$teacher = get_teacher($course->id
)) {
265 echo "Error: can not find teacher for course $course->id!\n";
268 if (! email_to_user($sendto, $teacher, $postsubject, $posttext, $posthtml)) {
269 echo "Error: workshop cron: Could not send out mail for id $submission->id to
270 user $sendto->id ($sendto->email)\n";
275 // look for new assessments of resubmissions
276 if ($assessments = workshop_get_unmailed_resubmissions($cutofftime)) {
279 foreach ($assessments as $assessment) {
281 echo "Processing workshop assessment $assessment->id\n";
283 // only process the entry once
284 if (! set_field("workshop_assessments", "mailed", "1", "id", "$assessment->id")) {
285 echo "Could not update the mailed field for id $assessment->id\n";
288 if (! $submission = get_record("workshop_submissions", "id", "$assessment->submissionid")) {
289 echo "Could not find submission $assessment->submissionid\n";
292 if (! $workshop = get_record("workshop", "id", $submission->workshopid
)) {
293 echo "Could not find workshop id $submission->workshopid\n";
296 if (! $course = get_record("course", "id", $workshop->course
)) {
297 error("Could not find course id $workshop->course");
300 if (! $cm = get_coursemodule_from_instance("workshop", $workshop->id
, $course->id
)) {
301 error("Course Module ID was incorrect");
304 if (! $submissionowner = get_record("user", "id", "$submission->userid")) {
305 echo "Could not find user $submission->userid\n";
308 if (! $assessmentowner = get_record("user", "id", "$assessment->userid")) {
309 echo "Could not find user $assessment->userid\n";
312 if (! workshop_is_student($workshop, $submissionowner->id
) and !workshop_is_teacher($workshop,
313 $submissionowner->id
)) {
314 continue; // Not an active participant
316 if (! workshop_is_student($workshop, $assessmentowner->id
) and !workshop_is_teacher($workshop,
317 $assessmentowner->id
)) {
318 continue; // Not an active participant
321 $strworkshops = get_string("modulenameplural", "workshop");
322 $strworkshop = get_string("modulename", "workshop");
324 // it's a resubission assessment, tell the assessment owner to (re)assess
325 $USER->lang
= $assessmentowner->lang
;
326 $sendto = $assessmentowner;
327 // "The assignment \"$submission->title\" is a revised piece of work. "
328 $msg = get_string("mail8", "workshop", $submission->title
)."\n";
329 // "Please assess it in the workshop assignment '$workshop->name'
330 // $msg .= get_string("mail9", "workshop", $workshop->name)."\n\n";
332 $postsubject = "$course->shortname: $strworkshops: ".format_string($workshop->name
,true);
333 $posttext = "$course->shortname -> $strworkshops -> ".format_string($workshop->name
,true)."\n";
334 $posttext .= "---------------------------------------------------------------------\n";
336 // "Please assess it in ..."
337 $posttext .= get_string("mail9", "workshop",
338 format_string($workshop->name
,true).", $CFG->wwwroot/mod/workshop/view.php?id=$cm->id")."\n";
339 $posttext .= "---------------------------------------------------------------------\n";
340 if ($sendto->mailformat
== 1) { // HTML
341 $posthtml = "<p><font face=\"sans-serif\">".
342 "<a href=\"$CFG->wwwroot/course/view.php?id=$course->id\">$course->shortname</a> ->".
343 "<a href=\"$CFG->wwwroot/mod/workshop/index.php?id=$course->id\">$strworkshops</a> ->".
344 "<a href=\"$CFG->wwwroot/mod/workshop/view.php?id=$cm->id\">".format_string($workshop->name
,true)."</a></font></p>";
345 $posthtml .= "<hr><font face=\"sans-serif\">";
346 $posthtml .= "<p>$msg</p>";
347 $posthtml .= "<p>".get_string("mail9", "workshop",
348 " <a href=\"$CFG->wwwroot/mod/workshop/view.php?id=$cm->id\">".format_string($workshop->name
,true)."</a>").'</p></font><hr>';
354 if (!$teacher = get_teacher($course->id
)) {
355 echo "Error: can not find teacher for course $course->id!\n";
358 if (! email_to_user($sendto, $teacher, $postsubject, $posttext, $posthtml)) {
359 echo "Error: workshop cron: Could not send out mail for id $submission->id to
360 user $sendto->id ($sendto->email)\n";
365 // look for new comments
366 if ($comments = workshop_get_unmailed_comments($cutofftime)) {
369 foreach ($comments as $comment) {
371 echo "Processing workshop comment $comment->id\n";
373 // only process the entry once
374 if (! set_field("workshop_comments", "mailed", "1", "id", "$comment->id")) {
375 echo "Could not update the mailed field for comment id $comment->id\n";
378 if (! $assessment = get_record("workshop_assessments", "id", "$comment->assessmentid")) {
379 echo "Could not find assessment $comment->assessmentid\n";
382 if (! $submission = get_record("workshop_submissions", "id", "$assessment->submissionid")) {
383 echo "Could not find submission $assessment->submissionid\n";
386 if (! $workshop = get_record("workshop", "id", $submission->workshopid
)) {
387 echo "Could not find workshop id $submission->workshopid\n";
390 if (! $course = get_record("course", "id", $workshop->course
)) {
391 error("Could not find course id $workshop->course");
394 if (! $cm = get_coursemodule_from_instance("workshop", $workshop->id
, $course->id
)) {
395 error("Course Module ID was incorrect");
398 if (! $submissionowner = get_record("user", "id", "$submission->userid")) {
399 echo "Could not find user $submission->userid\n";
402 if (! $assessmentowner = get_record("user", "id", "$assessment->userid")) {
403 echo "Could not find user $assessment->userid\n";
406 if (! workshop_is_student($workshop, $submissionowner->id
) and !workshop_is_teacher($workshop,
407 $submissionowner->id
)) {
408 continue; // Not an active participant
410 if (! workshop_is_student($workshop, $assessmentowner->id
) and !workshop_is_teacher($workshop,
411 $assessmentowner->id
)) {
412 continue; // Not an active participant
415 $strworkshops = get_string("modulenameplural", "workshop");
416 $strworkshop = get_string("modulename", "workshop");
418 // see if the submission owner needs to be told
419 if ($comment->userid
!= $submission->userid
) {
420 $USER->lang
= $submissionowner->lang
;
421 $sendto = $submissionowner;
422 // "A comment has been added to the assignment \"$submission->title\" by
423 if (workshop_is_student($workshop, $assessmentowner->id
)) {
424 $msg = get_string("mail4", "workshop", $submission->title
)." a $course->student.\n";
427 $msg = get_string("mail4", "workshop", $submission->title
)." ".fullname($assessmentowner)."\n";
429 // "The new comment can be seen in the workshop assignment '$workshop->name'
430 // $msg .= get_string("mail5", "workshop", $workshop->name)."\n\n";
432 $postsubject = "$course->shortname: $strworkshops: ".format_string($workshop->name
,true);
433 $posttext = "$course->shortname -> $strworkshops -> ".format_string($workshop->name
,true)."\n";
434 $posttext .= "---------------------------------------------------------------------\n";
436 // "The new comment can be seen in ..."
437 $posttext .= get_string("mail5", "workshop",
438 format_string($workshop->name
,true).", $CFG->wwwroot/mod/workshop/view.php?id=$cm->id")."\n";
439 $posttext .= "---------------------------------------------------------------------\n";
440 if ($sendto->mailformat
== 1) { // HTML
441 $posthtml = "<p><font face=\"sans-serif\">".
442 "<a href=\"$CFG->wwwroot/course/view.php?id=$course->id\">$course->shortname</a> ->".
443 "<a href=\"$CFG->wwwroot/mod/workshop/index.php?id=$course->id\">$strworkshops</a> ->".
444 "<a href=\"$CFG->wwwroot/mod/workshop/view.php?id=$cm->id\">".format_string($workshop->name
,true)."</a></font></p>";
445 $posthtml .= "<hr><font face=\"sans-serif\">";
446 $posthtml .= "<p>$msg</p>";
447 $posthtml .= "<p>".get_string("mail5", "workshop",
448 " <a href=\"$CFG->wwwroot/mod/workshop/view.php?id=$cm->id\">".format_string($workshop->name
,true)."</a>")
455 if (!$teacher = get_teacher($course->id
)) {
456 echo "Error: can not find teacher for course $course->id!\n";
459 if (! email_to_user($sendto, $teacher, $postsubject, $posttext, $posthtml)) {
460 echo "Error: workshop cron: Could not send out mail for id $submission->id to user
461 $sendto->id ($sendto->email)\n";
464 // see if the assessor needs to to told
465 if ($comment->userid
!= $assessment->userid
) {
466 $USER->lang
= $assessmentowner->lang
;
467 $sendto = $assessmentowner;
468 // "A comment has been added to the assignment \"$submission->title\" by
469 if (workshop_is_student($workshop, $submissionowner->id
)) {
470 $msg = get_string("mail4", "workshop", $submission->title
)." a $course->student.\n";
473 $msg = get_string("mail4", "workshop", $submission->title
).
474 " ".fullname($submissionowner)."\n";
476 // "The new comment can be seen in the workshop assignment '$workshop->name'
477 // $msg .= get_string("mail5", "workshop", $workshop->name)."\n\n";
479 $postsubject = "$course->shortname: $strworkshops: ".format_string($workshop->name
,true);
480 $posttext = "$course->shortname -> $strworkshops -> ".format_string($workshop->name
,true)."\n";
481 $posttext .= "---------------------------------------------------------------------\n";
483 // "The new comment can be seen in ..."
484 $posttext .= get_string("mail5", "workshop",
485 format_string($workshop->name
,true).", $CFG->wwwroot/mod/workshop/view.php?id=$cm->id")."\n";
486 $posttext .= "---------------------------------------------------------------------\n";
487 if ($sendto->mailformat
== 1) { // HTML
488 $posthtml = "<p><font face=\"sans-serif\">".
489 "<a href=\"$CFG->wwwroot/course/view.php?id=$course->id\">$course->shortname</a> ->".
490 "<a href=\"$CFG->wwwroot/mod/workshop/index.php?id=$course->id\">$strworkshops</a> ->".
491 "<a href=\"$CFG->wwwroot/mod/workshop/view.php?id=$cm->id\">".format_string($workshop->name
,true)."</a></font></p>";
492 $posthtml .= "<hr><font face=\"sans-serif\">";
493 $posthtml .= "<p>$msg</p>";
494 $posthtml .= "<p>".get_string("mail5", "workshop",
495 " <a href=\"$CFG->wwwroot/mod/workshop/view.php?id=$cm->id\">".format_string($workshop->name
,true)."</a>")
502 if (!$teacher = get_teacher($course->id
)) {
503 echo "Error: can not find teacher for course $course->id!\n";
506 if (! email_to_user($sendto, $teacher, $postsubject, $posttext, $posthtml)) {
507 echo "Error: workshop cron: Could not send out mail for id $submission->id to user
508 $sendto->id ($sendto->email)\n";
510 if (! set_field("workshop_comments", "mailed", "1", "id", "$comment->id")) {
511 echo "Could not update the mailed field for comment id $comment->id\n";
520 ///////////////////////////////////////////////////////////////////////////////
521 function workshop_delete_instance($id) {
522 // Given an ID of an instance of this module,
523 // this function will permanently delete the instance
524 // and any data that depends on it.
526 if (! $workshop = get_record("workshop", "id", "$id")) {
530 // delete all the associated records in the workshop tables, start positive...
533 if (! delete_records("workshop_comments", "workshopid", "$workshop->id")) {
537 if (! delete_records("workshop_stockcomments", "workshopid", "$workshop->id")) {
541 if (! delete_records("workshop_grades", "workshopid", "$workshop->id")) {
545 if (! delete_records("workshop_elements", "workshopid", "$workshop->id")) {
549 if (! delete_records("workshop_assessments", "workshopid", "$workshop->id")) {
553 if (! delete_records("workshop_submissions", "workshopid", "$workshop->id")) {
557 if (! delete_records("workshop", "id", "$workshop->id")) {
561 if (! delete_records('event', 'modulename', 'workshop', 'instance', $workshop->id
)) {
569 ///////////////////////////////////////////////////////////////////////////////
570 function workshop_grades($workshopid) {
571 /// Must return an array of grades, indexed by user, and a max grade.
572 /// only returns grades once assessment has started
573 /// returns nothing if workshop is not graded
577 if ($workshop = get_record("workshop", "id", $workshopid)) {
578 if (($workshop->assessmentstart
< time()) and $workshop->gradingstrategy
) {
579 if ($students = workshop_get_students($workshop)) {
580 foreach ($students as $student) {
581 if ($workshop->wtype
) {
582 $gradinggrade = workshop_gradinggrade($workshop, $student);
583 } else { // ignore grading grades for simple assignments
587 if ($submissions = workshop_get_user_submissions($workshop, $student)) {
588 foreach ($submissions as $submission) {
589 if (!$submission->late
) {
590 $grade = workshop_submission_grade($workshop, $submission);
594 if ($grade > $bestgrade) {
599 $return->grades
[$student->id
] = $gradinggrade +
$bestgrade;
603 // set maximum grade if graded
604 if ($workshop->gradingstrategy
) {
605 if ($workshop->wtype
) {
606 $return->maxgrade
= $workshop->grade +
$workshop->gradinggrade
;
607 } else { // ignore grading grades for simple assignemnts
608 $return->maxgrade
= $workshop->grade
;
615 //////////////////////////////////////////////////////////////////////////////////////
616 function workshop_is_recent_activity($course, $isteacher, $timestart) {//jlw1 added for adding mark to courses with activity in My Moodle
619 // have a look for agreed assessments for this user (agree)
620 $agreecontent = false;
621 if (!$isteacher) { // teachers only need to see submissions
622 if ($logs = workshop_get_agree_logs($course, $timestart)) {
623 // got some, see if any belong to a visible module
624 foreach ($logs as $log) {
625 // Create a temp valid module structure (only need courseid, moduleid)
626 $tempmod->course
= $course->id
;
627 $tempmod->id
= $log->workshopid
;
628 //Obtain the visible property from the instance
629 if (instance_is_visible("workshop",$tempmod)) {
630 $agreecontent = true;
640 ///////////////////////////////////////////////////////////////////////////////
642 // NOTE: $isteacher usage should be converted to use roles.
643 // TODO: Fix this function.
645 function workshop_print_recent_activity($course, $viewfullanmes, $timestart) {
648 $isteacher = has_capability('mod/workshop:manage', get_context_instance(CONTEXT_COURSE
, $course->id
));
650 $modinfo = get_fast_modinfo($course);
652 // have a look for agreed assessments for this user (agree)
653 $agreecontent = false;
654 if (!$isteacher) { // teachers only need to see submissions
655 if ($logs = workshop_get_agree_logs($course, $timestart)) {
656 $agreecontent = true;
657 print_headline(get_string("workshopagreedassessments", "workshop").":");
658 foreach ($logs as $log) {
659 if (!workshop_is_teacher($workshop, $log->userid
)) { // don't break anonymous rule
660 $log->firstname
= $course->student
;
663 print_recent_activity_note($log->time
, $log, $log->name
,
664 $CFG->wwwroot
.'/mod/workshop/'.$log->url
);
669 // have a look for new assessments for this user (assess)
670 $assesscontent = false;
671 if (!$isteacher) { // teachers only need to see submissions
672 if ($logs = workshop_get_assess_logs($course, $timestart)) {
673 // got some, see if any belong to a visible module
674 foreach ($logs as $id=>$log) {
675 $cm = $modinfo->instances
['workshop'][$log->workshopid
];
676 if (!$cm->uservisible
) {
681 // if we got some "live" ones then output them
683 $assesscontent = true;
684 print_headline(get_string("workshopassessments", "workshop").":");
685 foreach ($logs as $log) {
686 if (!workshop_is_teacher($tempmod->id
, $log->userid
)) { // don't break anonymous rule
687 $log->firstname
= $course->student
; // Keep anonymous
690 print_recent_activity_note($log->time
, $log, $log->name
,
691 $CFG->wwwroot
.'/mod/workshop/'.$log->url
);
696 // have a look for new comments for this user (comment)
697 $commentcontent = false;
698 if (!$isteacher) { // teachers only need to see submissions
699 if ($logs = workshop_get_comment_logs($course, $timestart)) {
700 // got some, see if any belong to a visible module
701 foreach ($logs as $id=>$log) {
702 $cm = $modinfo->instances
['workshop'][$log->workshopid
];
703 if (!$cm->uservisible
) {
708 // if we got some "live" ones then output them
710 $commentcontent = true;
711 print_headline(get_string("workshopcomments", "workshop").":");
712 foreach ($logs as $log) {
713 $log->firstname
= $course->student
; // Keep anonymous
715 print_recent_activity_note($log->time
, $log, $log->name
,
716 $CFG->wwwroot
.'/mod/workshop/'.$log->url
);
722 // have a look for new assessment gradings for this user (grade)
723 $gradecontent = false;
724 if ($logs = workshop_get_grade_logs($course, $timestart)) {
725 // got some, see if any belong to a visible module
726 foreach ($logs as $id=>$log) {
727 $cm = $modinfo->instances
['workshop'][$log->workshopid
];
728 if (!$cm->uservisible
) {
733 // if we got some "live" ones then output them
735 $gradecontent = true;
736 print_headline(get_string("workshopfeedback", "workshop").":");
737 foreach ($logs as $log) {
738 $log->firstname
= $course->teacher
; // Keep anonymous
740 print_recent_activity_note($log->time
, $log, $log->name
,
741 $CFG->wwwroot
.'/mod/workshop/'.$log->url
);
746 // have a look for new submissions (only show to teachers) (submit)
747 $submitcontent = false;
749 if ($logs = workshop_get_submit_logs($course, $timestart)) {
750 // got some, see if any belong to a visible module
751 foreach ($logs as $id=>$log) {
752 $cm = $modinfo->instances
['workshop'][$log->workshopid
];
753 if (!$cm->uservisible
) {
758 // if we got some "live" ones then output them
760 $submitcontent = true;
761 print_headline(get_string("workshopsubmissions", "workshop").":");
762 foreach ($logs as $log) {
763 print_recent_activity_note($log->time
, $log, $log->name
,
764 $CFG->wwwroot
.'/mod/workshop/'.$log->url
);
770 return $agreecontent or $assesscontent or $commentcontent or $gradecontent or $submitcontent;
774 ///////////////////////////////////////////////////////////////////////////////
775 function workshop_refresh_events($courseid = 0) {
776 // This standard function will check all instances of this module
777 // and make sure there are up-to-date events created for each of them.
778 // If courseid = 0, then every workshop event in the site is checked, else
779 // only workshop events belonging to the course specified are checked.
780 // This function is used, in its new format, by restore_refresh_events()
782 if ($courseid == 0) {
783 if (! $workshops = get_records("workshop")) {
787 if (! $workshops = get_records("workshop", "course", $courseid)) {
791 $moduleid = get_field('modules', 'id', 'name', 'workshop');
793 foreach ($workshops as $workshop) {
796 'submissionstart' => $workshop->submissionstart
,
797 'submissionend' => $workshop->submissionend
,
798 'assessmentstart' => $workshop->assessmentstart
,
799 'assessmentend' => $workshop->assessmentend
802 foreach ($dates as $type => $date) {
805 if ($event = get_record('event', 'modulename', 'workshop', 'instance', $workshop->id
, 'eventtype', $type)) {
806 $event->name
= addslashes(get_string($type.'event','workshop', $workshop->name
));
807 $event->description
= addslashes($workshop->description
);
808 $event->eventtype
= $type;
809 $event->timestart
= $date;
810 update_event($event);
812 $event->courseid
= $workshop->course
;
813 $event->modulename
= 'workshop';
814 $event->instance
= $workshop->id
;
815 $event->name
= addslashes(get_string($type.'event','workshop', $workshop->name
));
816 $event->description
= addslashes($workshop->description
);
817 $event->eventtype
= $type;
818 $event->timestart
= $date;
819 $event->timeduration
= 0;
820 $event->visible
= get_field('course_modules', 'visible', 'module', $moduleid, 'instance', $workshop->id
);
830 ///////////////////////////////////////////////////////////////////////////////
831 function workshop_update_instance($workshop) {
832 // Given an object containing all the necessary data,
833 // (defined by the form in mod.html) this function
834 // will update an existing instance with new data.
837 $workshop->timemodified
= time();
839 $workshop->submissionstart
= make_timestamp($workshop->submissionstartyear
,
840 $workshop->submissionstartmonth
, $workshop->submissionstartday
, $workshop->submissionstarthour
,
841 $workshop->submissionstartminute
);
843 $workshop->assessmentstart
= make_timestamp($workshop->assessmentstartyear
,
844 $workshop->assessmentstartmonth
, $workshop->assessmentstartday
, $workshop->assessmentstarthour
,
845 $workshop->assessmentstartminute
);
847 $workshop->submissionend
= make_timestamp($workshop->submissionendyear
,
848 $workshop->submissionendmonth
, $workshop->submissionendday
, $workshop->submissionendhour
,
849 $workshop->submissionendminute
);
851 $workshop->assessmentend
= make_timestamp($workshop->assessmentendyear
,
852 $workshop->assessmentendmonth
, $workshop->assessmentendday
, $workshop->assessmentendhour
,
853 $workshop->assessmentendminute
);
855 $workshop->releasegrades
= make_timestamp($workshop->releaseyear
,
856 $workshop->releasemonth
, $workshop->releaseday
, $workshop->releasehour
,
857 $workshop->releaseminute
);
859 if (!workshop_check_dates($workshop)) {
860 return get_string('invaliddates', 'workshop');
863 // set the workshop's type
864 $wtype = 0; // 3 phases, no grading grades
865 if ($workshop->includeself
or $workshop->ntassessments
) $wtype = 1; // 3 phases with grading grades
866 if ($workshop->nsassessments
) $wtype = 2; // 5 phases with grading grades
867 $workshop->wtype
= $wtype;
869 // encode password if necessary
870 if (!empty($workshop->password
)) {
871 $workshop->password
= md5($workshop->password
);
873 unset($workshop->password
);
876 $workshop->id
= $workshop->instance
;
878 if ($returnid = update_record("workshop", $workshop)) {
881 'submissionstart' => $workshop->submissionstart
,
882 'submissionend' => $workshop->submissionend
,
883 'assessmentstart' => $workshop->assessmentstart
,
884 'assessmentend' => $workshop->assessmentend
886 $moduleid = get_field('modules', 'id', 'name', 'workshop');
888 foreach ($dates as $type => $date) {
889 if ($event = get_record('event', 'modulename', 'workshop', 'instance', $workshop->id
, 'eventtype', $type)) {
890 $event->name
= get_string($type.'event','workshop', $workshop->name
);
891 $event->description
= $workshop->description
;
892 $event->eventtype
= $type;
893 $event->timestart
= $date;
894 update_event($event);
897 $event->name
= get_string($type.'event','workshop', $workshop->name
);
898 $event->description
= $workshop->description
;
899 $event->courseid
= $workshop->course
;
902 $event->modulename
= 'workshop';
903 $event->instance
= $workshop->instance
;
904 $event->eventtype
= $type;
905 $event->timestart
= $date;
906 $event->timeduration
= 0;
907 $event->visible
= get_field('course_modules', 'visible', 'module', $moduleid, 'instance', $workshop->id
);
913 if (time() > $workshop->assessmentstart
) {
914 // regrade all the submissions...
915 set_field("workshop_submissions", "nassessments", 0, "workshopid", $workshop->id
);
916 workshop_grade_assessments($workshop);
922 ///////////////////////////////////////////////////////////////////////////////
923 function workshop_user_complete($course, $user, $mod, $workshop) {
924 if ($submission = workshop_get_student_submission($workshop, $user)) {
925 if ($basedir = workshop_file_area($workshop, $user)) {
926 if ($files = get_directory_list($basedir)) {
927 $countfiles = count($files).' '.get_string('submissions', 'workshop');
928 foreach ($files as $file) {
929 $countfiles .= "; $file";
934 print_simple_box_start();
936 echo $submission->description
.'<br />';
938 if (!empty($countfiles)) {
939 echo $countfiles,'<br />';
942 workshop_print_feedback($course, $submission);
944 print_simple_box_end();
947 print_string('notsubmittedyet', 'workshop');
951 //////////////////////////////////////////////////////////////////////////////////////
952 function workshop_print_feedback($course, $submission) {
953 global $CFG, $RATING;
955 if (! $feedbacks = get_records('workshop_assessments', 'submissionid', $submission->id
)) {
959 $strgrade = get_string('grade');
960 $strnograde = get_string('nograde');
962 foreach ($feedbacks as $feedback) {
963 if (! $user = get_record('user', 'id', $feedback->userid
)) {
964 /// Weird error but we'll just ignore it and continue with other feedback
968 echo '<table cellspacing="0" class="workshop_feedbackbox">';
971 echo '<td class="picture left">';
972 print_user_picture($user->id
, $course->id
, $user->picture
);
974 echo '<td><span class="author">'.fullname($user).'</span>';
975 echo '<span class="time">'.userdate($feedback->timegraded
).'</span>';
978 echo '<tr><td class="left side"> </td>';
979 echo '<td class="content">';
981 if ($feedback->grade
) {
982 echo $strgrade.': '.$feedback->grade
;
987 echo '<span class="comment">'.format_text($feedback->generalcomment
).'</span>';
988 echo '<span class="teachercomment">'.format_text($feedback->teachercomment
).'</span>';
989 echo '</td></tr></table>';
997 ///////////////////////////////////////////////////////////////////////////////
998 function workshop_user_outline($course, $user, $mod, $workshop) {
999 if ($submissions = workshop_get_user_submissions($workshop, $user)) {
1000 $result->info
= count($submissions)." ".get_string("submissions", "workshop");
1001 // workshop_get_user_submissions returns the newest one first
1002 foreach ($submissions as $submission) {
1003 $result->time
= $submission->timecreated
;
1011 //////////////////////////////////////////////////////////////////////////////////////
1012 function workshop_get_participants($workshopid) {
1013 //Returns the users with data in one workshop
1014 //(users with records in workshop_submissions, workshop_assessments and workshop_comments, students)
1018 //Get students from workshop_submissions
1019 $st_submissions = get_records_sql("SELECT DISTINCT u.id, u.id
1020 FROM {$CFG->prefix}user u,
1021 {$CFG->prefix}workshop_submissions s
1022 WHERE s.workshopid = '$workshopid' and
1024 //Get students from workshop_assessments
1025 $st_assessments = get_records_sql("SELECT DISTINCT u.id, u.id
1026 FROM {$CFG->prefix}user u,
1027 {$CFG->prefix}workshop_assessments a
1028 WHERE a.workshopid = '$workshopid' and
1031 //Get students from workshop_comments
1032 $st_comments = get_records_sql("SELECT DISTINCT u.id, u.id
1033 FROM {$CFG->prefix}user u,
1034 {$CFG->prefix}workshop_comments c
1035 WHERE c.workshopid = '$workshopid' and
1038 //Add st_assessments to st_submissions
1039 if ($st_assessments) {
1040 foreach ($st_assessments as $st_assessment) {
1041 $st_submissions[$st_assessment->id
] = $st_assessment;
1044 //Add st_comments to st_submissions
1046 foreach ($st_comments as $st_comment) {
1047 $st_submissions[$st_comment->id
] = $st_comment;
1050 //Return st_submissions array (it contains an array of unique users)
1051 return ($st_submissions);
1054 //////////////////////////////////////////////////////////////////////////////////////
1055 function workshop_get_recent_mod_activity(&$activities, &$index, $sincetime, $courseid,
1056 $workshop="0", $user="", $groupid="") {
1057 // Returns all workshop posts since a given time. If workshop is specified then
1058 // this restricts the results
1063 $workshopselect = " AND cm.id = '$workshop'";
1065 $workshopselect = "";
1069 $userselect = " AND u.id = '$user'";
1074 $posts = get_records_sql("SELECT s.*, u.firstname, u.lastname,
1075 u.picture, cm.instance, w.name, cm.section, cm.groupmode,
1076 cm.course, cm.groupingid, cm.groupmembersonly
1077 FROM {$CFG->prefix}workshop_submissions s,
1078 {$CFG->prefix}user u,
1079 {$CFG->prefix}course_modules cm,
1080 {$CFG->prefix}workshop w
1081 WHERE s.timecreated > '$sincetime' $workshopselect
1082 AND s.userid = u.id $userselect
1083 AND w.course = '$courseid'
1084 AND cm.instance = w.id
1085 AND cm.course = w.course
1086 AND s.workshopid = w.id
1090 if (empty($posts)) {
1094 foreach ($posts as $post) {
1095 if ((empty($groupid) ||
groups_is_member($groupid, $post->userid
)) && groups_course_module_visible($post)) {
1097 $tmpactivity = new Object;
1099 $tmpactivity->type
= "workshop";
1100 $tmpactivity->defaultindex
= $index;
1101 $tmpactivity->instance
= $post->instance
;
1102 $tmpactivity->name
= $post->name
;
1103 $tmpactivity->section
= $post->section
;
1105 $tmpactivity->content
->id
= $post->id
;
1106 $tmpactivity->content
->title
= $post->title
;
1108 $tmpactivity->user
->userid
= $post->userid
;
1109 $tmpactivity->user
->fullname
= fullname($post);
1110 $tmpactivity->user
->picture
= $post->picture
;
1112 $tmpactivity->timestamp
= $post->timecreated
;
1113 $activities[] = $tmpactivity;
1122 //////////////////////////////////////////////////////////////////////////////////////
1123 function workshop_print_recent_mod_activity($activity, $course, $detail=false) {
1127 echo '<table border="0" cellpadding="3" cellspacing="0">';
1129 if (!empty($activity->content
->parent
)) {
1130 $openformat = "<font size=\"2\"><i>";
1131 $closeformat = "</i></font>";
1133 $openformat = "<b>";
1134 $closeformat = "</b>";
1137 echo "<tr><td class=\"workshoppostpicture\" width=\"35\" valign=\"top\">";
1138 print_user_picture($activity->user
->userid
, $course, $activity->user
->picture
);
1139 echo "</td><td>$openformat";
1142 echo "<img src=\"$CFG->modpixpath/$activity->type/icon.gif\" ".
1143 "class=\"icon\" alt=\"".strip_tags(format_string($activity->name
,true))."\" /> ";
1145 echo "<a href=\"$CFG->wwwroot/mod/workshop/view.php?"
1146 . "#" . $activity->content
->id
. "\">".$activity->content
->title
;
1148 echo "</a>$closeformat";
1150 echo "<br /><font size=\"2\">";
1151 echo "<a href=\"$CFG->wwwroot/user/view.php?id=" . $activity->user
->userid
. "&course=" . "$course\">"
1152 . $activity->user
->fullname
. "</a>";
1153 echo " - " . userdate($activity->timestamp
) . "</font></td></tr>";
1161 //////////////////////////////////////////////////////////////////////////////////////
1162 // Non-standard workshop functions
1163 ///////////////////////////////////////////////////////////////////////////////////////////////
1164 function workshop_compare_assessments($workshop, $assessment1, $assessment2) {
1165 global $WORKSHOP_ASSESSMENT_COMPS, $WORKSHOP_EWEIGHTS;
1166 // first get the assignment elements for maxscores...
1167 $elementsraw = get_records("workshop_elements", "workshopid", $workshop->id
, "elementno ASC");
1168 foreach ($elementsraw as $element) {
1169 $maxscore[] = $element->maxscore
; // to renumber index 0,1,2...
1170 $weight[] = $WORKSHOP_EWEIGHTS[$element->weight
]; // get real value and renumber index 0,1,2...
1174 for ($i = 0; $i < 2; $i++
) {
1176 $rawgrades = get_records("workshop_grades", "assessmentid", $assessment1->id
, "elementno ASC");
1178 $rawgrades = get_records("workshop_grades", "assessmentid", $assessment2->id
, "elementno ASC");
1181 foreach ($rawgrades as $grade) {
1182 $grades[$i][] = $grade->grade
;
1188 switch ($workshop->gradingstrategy
) {
1189 case 1 : // accumulative grading and...
1190 case 4 : // ...rubic grading
1191 for ($i=0; $i < $workshop->nelements
; $i++
) {
1192 $diff = ($grades[0][$i] - $grades[1][$i]) * $weight[$i] / $maxscore[$i];
1193 $sumdiffs +
= $diff * $diff; // use squared distances
1194 $sumweights +
= $weight[$i];
1197 case 2 : // error banded grading
1198 // ignore maxscores here, the grades are either 0 or 1,
1199 for ($i=0; $i < $workshop->nelements
; $i++
) {
1200 $diff = ($grades[0][$i] - $grades[1][$i]) * $weight[$i];
1201 $sumdiffs +
= $diff * $diff; // use squared distances
1202 $sumweights +
= $weight[$i];
1205 case 3 : // criterion grading
1206 // here we only need to look at the difference between the "zero" grade elements
1207 $diff = ($grades[0][0] - $grades[1][0]) / (count($elementsraw) - 1);
1208 $sumdiffs = $diff * $diff;
1212 // convert to a sensible grade (always out of 100)
1213 $COMP = (object)$WORKSHOP_ASSESSMENT_COMPS[$workshop->assessmentcomps
];
1214 $factor = $COMP->value
;
1215 $gradinggrade = (($factor - ($sumdiffs / $sumweights)) / $factor) * 100;
1216 if ($gradinggrade < 0) {
1219 return $gradinggrade;
1223 //////////////////////////////////////////////////////////////////////////////////////
1224 function workshop_count_assessments($submission) {
1225 // Return the (real) assessments for this submission,
1227 return count_records_select("workshop_assessments",
1228 "submissionid = $submission->id AND timecreated < $timenow");
1232 //////////////////////////////////////////////////////////////////////////////////////
1233 function workshop_count_ungraded_assessments($workshop) {
1234 // function returns the number of ungraded assessments by students
1239 // get all the cold assessments that have not been graded
1240 if ($assessments = get_records_select("workshop_assessments", "workshopid = $workshop->id AND
1241 (timecreated + $CFG->maxeditingtime) < $timenow AND timegraded = 0")) {
1242 foreach ($assessments as $assessment) {
1243 if (workshop_is_student($workshop, $assessment->userid
)) {
1252 //////////////////////////////////////////////////////////////////////////////////////
1253 function workshop_file_area($workshop, $submission) {
1254 return make_upload_directory( workshop_file_area_name($workshop, $submission) );
1258 //////////////////////////////////////////////////////////////////////////////////////
1259 function workshop_file_area_name($workshop, $submission) {
1260 // Creates a directory file name, suitable for make_upload_directory()
1263 return "$workshop->course/$CFG->moddata/workshop/$submission->id";
1267 ///////////////////////////////////////////////////////////////////////////////////////////////
1268 function workshop_get_agree_logs($course, $timestart) {
1269 // get the "agree" entries for this user (the assessment owner) and add the first and last names
1270 // the last two probably wont be used...
1272 if (empty($USER->id
)) {
1276 $timethen = time() - $CFG->maxeditingtime
;
1277 return get_records_sql("SELECT l.time, l.url, u.firstname, u.lastname, a.workshopid, a.userid, e.name
1278 FROM {$CFG->prefix}log l,
1279 {$CFG->prefix}workshop e,
1280 {$CFG->prefix}workshop_submissions s,
1281 {$CFG->prefix}workshop_assessments a,
1282 {$CFG->prefix}user u
1283 WHERE l.time > $timestart AND l.time < $timethen
1284 AND l.course = $course->id AND l.module = 'workshop' AND l.action = 'agree'
1285 AND a.id = l.info AND s.id = a.submissionid AND a.userid = $USER->id
1286 AND u.id = s.userid AND e.id = a.workshopid");
1290 ///////////////////////////////////////////////////////////////////////////////////////////////
1291 function workshop_get_assess_logs($course, $timestart) {
1292 // get the "assess" entries for this user and add the first and last names...
1294 if (empty($USER->id
)) {
1298 $timethen = time() - $CFG->maxeditingtime
;
1299 return get_records_sql("SELECT l.time, l.url, u.firstname, u.lastname, a.workshopid, a.userid, e.name
1300 FROM {$CFG->prefix}log l,
1301 {$CFG->prefix}workshop e,
1302 {$CFG->prefix}workshop_submissions s,
1303 {$CFG->prefix}workshop_assessments a,
1304 {$CFG->prefix}user u
1305 WHERE l.time > $timestart AND l.time < $timethen
1306 AND l.course = $course->id AND l.module = 'workshop' AND l.action = 'assess'
1307 AND a.id = l.info AND s.id = a.submissionid AND s.userid = $USER->id
1308 AND u.id = a.userid AND e.id = a.workshopid");
1312 //////////////////////////////////////////////////////////////////////////////////////
1313 function workshop_get_assessments($submission, $all = '', $order = '') {
1314 // Return assessments for this submission ordered oldest first, newest last
1315 // new assessments made within the editing time are NOT returned unless they
1316 // belong to the user or the second argument is set to ALL
1321 $order = "timecreated DESC";
1323 if ($all != 'ALL') {
1324 return get_records_select("workshop_assessments", "(submissionid = $submission->id) AND
1325 ((timecreated < $timenow - $CFG->maxeditingtime) or
1326 ((timecreated < $timenow) AND (userid = $USER->id)))", $order);
1328 return get_records_select("workshop_assessments", "submissionid = $submission->id AND
1329 (timecreated < $timenow)", $order);
1334 ///////////////////////////////////////////////////////////////////////////////////////////////
1335 function workshop_get_comment_logs($course, $timestart) {
1336 // get the "comment" entries for this user and add the first and last names (which may not be used)...
1338 if (empty($USER->id
)) {
1342 $timethen = time() - $CFG->maxeditingtime
;
1343 return get_records_sql("SELECT l.time, l.url, u.firstname, u.lastname, a.workshopid, e.name
1344 FROM {$CFG->prefix}log l,
1345 {$CFG->prefix}workshop e,
1346 {$CFG->prefix}workshop_submissions s,
1347 {$CFG->prefix}workshop_assessments a,
1348 {$CFG->prefix}workshop_comments c,
1349 {$CFG->prefix}user u
1350 WHERE l.time > $timestart AND l.time < $timethen
1351 AND l.course = $course->id AND l.module = 'workshop' AND l.action = 'comment'
1352 AND c.id = l.info AND c.userid != $USER->id AND a.id = c.assessmentid
1353 AND s.id = a.submissionid AND (s.userid = $USER->id OR a.userid = $USER->id)
1354 AND u.id = a.userid AND e.id = a.workshopid");
1358 ///////////////////////////////////////////////////////////////////////////////////////////////
1359 function workshop_get_grade_logs($course, $timestart) {
1360 // get the "grade" entries for this user and add the first and last names (of submission owner,
1361 // better to get name of teacher...
1362 // ...but not available in assessment record...)
1364 if (empty($USER->id
)) {
1368 $timethen = time() - $CFG->maxeditingtime
;
1369 return get_records_sql("SELECT l.time, l.url, u.firstname, u.lastname, a.workshopid, e.name
1370 FROM {$CFG->prefix}log l,
1371 {$CFG->prefix}workshop e,
1372 {$CFG->prefix}workshop_submissions s,
1373 {$CFG->prefix}workshop_assessments a,
1374 {$CFG->prefix}user u
1375 WHERE l.time > $timestart AND l.time < $timethen
1376 AND l.course = $course->id AND l.module = 'workshop' AND l.action = 'grade'
1377 AND a.id = l.info AND s.id = a.submissionid AND a.userid = $USER->id
1378 AND u.id = s.userid AND e.id = a.workshopid");
1382 //////////////////////////////////////////////////////////////////////////////////////
1383 function workshop_get_student_submission($workshop, $user) {
1384 // Return a submission for a particular user
1387 $submission = get_record("workshop_submissions", "workshopid", $workshop->id
, "userid", $user->id
);
1388 if (!empty($submission->timecreated
)) {
1395 //////////////////////////////////////////////////////////////////////////////////////
1396 function workshop_get_student_submissions($workshop, $order = "title") {
1397 // Return all ENROLLED student submissions
1400 if ($order == "title") {
1403 if ($order == "name") {
1404 $order = "a.lastname, a.firstname";
1406 if ($order == "time") {
1407 $order = "s.timecreated ASC";
1410 if (!$students = workshop_get_students($workshop)) {
1414 foreach ($students as $student) {
1415 $list .= "$student->id,";
1417 $list = rtrim($list, ',').")";
1419 return get_records_sql("SELECT s.* FROM {$CFG->prefix}workshop_submissions s, {$CFG->prefix}user a
1420 WHERE s.userid IN $list
1421 AND s.workshopid = $workshop->id
1422 AND s.timecreated > 0
1428 ///////////////////////////////////////////////////////////////////////////////////////////////
1429 function workshop_get_submit_logs($course, $timestart) {
1430 // get the "submit" entries and add the first and last names...
1433 $timethen = time() - $CFG->maxeditingtime
;
1434 return get_records_sql("SELECT l.time, l.url, u.firstname, u.lastname, l.info as workshopid, e.name
1435 FROM {$CFG->prefix}log l,
1436 {$CFG->prefix}workshop e,
1437 {$CFG->prefix}user u
1438 WHERE l.time > $timestart AND l.time < $timethen
1439 AND l.course = $course->id AND l.module = 'workshop'
1440 AND l.action = 'submit'
1442 AND u.id = l.userid");
1446 //////////////////////////////////////////////////////////////////////////////////////
1447 function workshop_get_unmailed_assessments($cutofftime) {
1448 /// Return list of assessments that have not been mailed out
1450 return get_records_sql("SELECT a.*, g.course, g.name
1451 FROM {$CFG->prefix}workshop_assessments a, {$CFG->prefix}workshop g
1453 AND a.timecreated < $cutofftime
1454 AND g.id = a.workshopid
1455 AND g.releasegrades < $cutofftime");
1459 //////////////////////////////////////////////////////////////////////////////////////
1460 function workshop_get_unmailed_comments($cutofftime) {
1461 /// Return list of comments that have not been mailed out
1463 return get_records_sql("SELECT c.*, g.course, g.name
1464 FROM {$CFG->prefix}workshop_comments c, {$CFG->prefix}workshop g
1466 AND c.timecreated < $cutofftime
1467 AND g.id = c.workshopid");
1471 //////////////////////////////////////////////////////////////////////////////////////
1472 function workshop_get_unmailed_graded_assessments($cutofftime) {
1473 /// Return list of graded assessments that have not been mailed out
1475 return get_records_sql("SELECT a.*, g.course, g.name
1476 FROM {$CFG->prefix}workshop_assessments a, {$CFG->prefix}workshop g
1478 AND a.timegraded < $cutofftime
1479 AND a.timegraded > 0
1480 AND g.id = a.workshopid");
1484 //////////////////////////////////////////////////////////////////////////////////////
1485 function workshop_get_unmailed_resubmissions($cutofftime) {
1486 /// Return list of assessments of resubmissions that have not been mailed out
1488 return get_records_sql("SELECT a.*, w.course, w.name
1489 FROM {$CFG->prefix}workshop_assessments a, {$CFG->prefix}workshop w
1491 AND a.resubmission = 1
1492 AND w.id = a.workshopid");
1496 //////////////////////////////////////////////////////////////////////////////////////
1497 function workshop_get_user_assessments($workshop, $user) {
1498 // Return all the user's assessments, newest first, oldest last (hot, warm and cold ones)
1499 return get_records_select("workshop_assessments", "workshopid = $workshop->id AND userid = $user->id",
1500 "timecreated DESC");
1504 //////////////////////////////////////////////////////////////////////////////////////
1505 function workshop_get_user_submissions($workshop, $user) {
1506 // return real submissions of user newest first, oldest last. Ignores the dummy submissions
1507 // which get created to hold the final grades for users that make no submissions
1508 return get_records_select("workshop_submissions", "workshopid = $workshop->id AND
1509 userid = $user->id AND timecreated > 0", "timecreated DESC" );
1513 //////////////////////////////////////////////////////////////////////////////////////
1514 function workshop_grade_assessments($workshop, $verbose=false) {
1515 global $WORKSHOP_EWEIGHTS;
1517 // timeout after 10 minutes
1518 @set_time_limit
(600);
1522 // set minumim value for the variance (of the elements)
1525 // check when the standard deviations were calculated
1526 $oldtotalassessments = get_field("workshop_elements", "totalassessments", "workshopid", $workshop->id
,
1528 $totalassessments = count_records("workshop_assessments", "workshopid", $workshop->id
);
1529 // calculate the std. devs every 10 assessments for low numbers of assessments, thereafter every 100 new assessments
1530 if ((($totalassessments < 100) and (($totalassessments - $oldtotalassessments) > 10)) or
1531 (($totalassessments - $oldtotalassessments) > 100)) {
1532 // calculate the means for each submission using just the "good" assessments
1533 if ($submissions = get_records("workshop_submissions", "workshopid", $workshop->id
)) {
1534 foreach ($submissions as $submission) {
1535 $nassessments[$submission->id
] = 0;
1536 if ($assessments = workshop_get_assessments($submission)) {
1537 foreach ($assessments as $assessment) {
1538 // test if assessment is "good", a teacher assessment always "good", but may be weighted out
1539 if (workshop_is_teacher($workshop, $assessment->userid
)) {
1540 if (!$workshop->teacherweight
) {
1541 // drop teacher's assessment as weight is zero
1544 } elseif ((!$assessment->gradinggrade
and $assessment->timegraded
) or
1545 ($workshop->agreeassessments
and !$assessment->timeagreed
)) {
1546 // it's a duff assessment, or it's not been agreed
1549 if (isset($num[$submission->id
])) {
1550 if (workshop_is_teacher($workshop, $assessment->userid
)) {
1551 $num[$submission->id
] +
= $workshop->teacherweight
; // weight teacher's assessment
1553 $num[$submission->id
]++
; // number of assessments
1555 $nassessments[$submission->id
]++
;
1557 if (workshop_is_teacher($workshop, $assessment->userid
)) {
1558 $num[$submission->id
] = $workshop->teacherweight
;
1560 $num[$submission->id
] = 1;
1562 $nassessments[$submission->id
] = 1;
1564 for ($i = 0; $i < $workshop->nelements
; $i++
) {
1565 $grade = get_field("workshop_grades", "grade",
1566 "assessmentid", $assessment->id
, "elementno", $i);
1567 if (isset($sum[$submission->id
][$i])) {
1568 if (workshop_is_teacher($workshop, $assessment->userid
)) {
1569 $sum[$submission->id
][$i] +
= $workshop->teacherweight
* $grade; // teacher's grade
1571 $sum[$submission->id
][$i] +
= $grade; // student's grade
1574 if (workshop_is_teacher($workshop, $assessment->userid
)) {
1575 $sum[$submission->id
][$i] = $workshop->teacherweight
* $grade; // teacher's grade
1577 $sum[$submission->id
][$i] = $grade; // students's grade
1586 // no assessments yet
1590 // calculate the means for each submission
1592 foreach ($num as $submissionid => $n) {
1593 if ($n) { // stop division by zero
1594 for ($i = 0; $i < $workshop->nelements
; $i++
) {
1595 $mean[$submissionid][$i] = $sum[$submissionid][$i] / $n;
1596 // echo "Submission: $submissionid; Element: $i; Mean: {$mean[$submissionid][$i]}<br />\n";
1598 $total +
= $n; // weighted total
1602 echo "<p style=\"text-align:center\">".get_string("numberofsubmissions", "workshop", count($num))."<br />\n";
1603 echo get_string("numberofassessmentsweighted", "workshop", $total)."</p>\n";
1606 // now get an estimate of the standard deviation of each element in the assessment
1607 // this is just a rough measure, all assessments are included and teacher's assesments are not weighted
1609 for ($i = 0; $i < $workshop->nelements
; $i++
) {
1612 foreach ($submissions as $submission) {
1613 if ($assessments = workshop_get_assessments($submission)) {
1614 foreach ($assessments as $assessment) {
1616 for ($i = 0; $i < $workshop->nelements
; $i++
) {
1617 $grade = get_field("workshop_grades", "grade",
1618 "assessmentid", $assessment->id
, "elementno", $i);
1619 $temp = $mean[$submission->id
][$i] - $grade;
1620 $var[$i] +
= $temp * $temp;
1625 for ($i = 0; $i < $workshop->nelements
; $i++
) {
1627 $sd[$i] = sqrt($var[$i] / ($n - 1));
1631 set_field("workshop_elements", "stddev", $sd[$i], "workshopid", $workshop->id
, "elementno", $i);
1632 set_field("workshop_elements", "totalassessments", $totalassessments, "workshopid", $workshop->id
,
1635 echo get_string("standarddeviationofelement", "workshop", $i+
1)." $sd[$i]<br />";
1636 if ($sd[$i] <= $minvar) {
1637 print_string("standarddeviationnote", "workshop")."<br />\n";
1644 // this section looks at each submission if the number of assessments made has increased it recalculates the
1645 // grading grades for those assessments
1646 // first get the assignment elements for the weights and the stddevs...
1647 if ($elementsraw = get_records("workshop_elements", "workshopid", $workshop->id
, "elementno ASC")) {
1648 foreach ($elementsraw as $element) {
1649 $weight[] = $element->weight
; // to renumber index 0,1,2...
1650 $sd[] = $element->stddev
; // to renumber index 0,1,2...
1654 unset($num); // may have been used in calculating stddevs
1655 unset($sum); // ditto
1656 if ($submissions = get_records("workshop_submissions", "workshopid", $workshop->id
)) {
1657 foreach ($submissions as $submission) {
1658 // see if the number of assessments has changed
1659 $nassessments = workshop_count_assessments($submission);
1660 if ($submission->nassessments
<> $nassessments) {
1661 // ...if there are three or more assessments calculate the variance of each assessment.
1662 // Use the variance to find the "best" assessment. (When there is only one or two assessments they
1663 // are not altered by this routine.)
1665 echo "Processing submission $submission->id ($nassessments asessments)...\n";
1667 if ($nassessments > 2) {
1668 $num = 0; // weighted number of assessments
1669 for ($i = 0; $i < $workshop->nelements
; $i++
) {
1670 $sum[$i] = 0; // weighted sum of grades
1672 if ($assessments = workshop_get_assessments($submission)) {
1673 // first calculate the mean grades for each element
1674 foreach ($assessments as $assessment) {
1675 // test if assessment is "good", a teacher assessment always "good", but may be weighted out
1676 if (workshop_is_teacher($workshop, $assessment->userid
)) {
1677 if (!$workshop->teacherweight
) {
1678 // drop teacher's assessment as weight is zero
1681 } else if ((!$assessment->gradinggrade
and $assessment->timegraded
) or
1682 ($workshop->agreeassessments
and !$assessment->timeagreed
)) {
1683 // it's a duff assessment, or it's not been agreed
1686 if (workshop_is_teacher($workshop, $assessment->userid
)) {
1687 $num +
= $workshop->teacherweight
; // weight teacher's assessment
1689 $num++
; // student assessment just add one
1691 for ($i = 0; $i < $workshop->nelements
; $i++
) {
1692 $grade = get_field("workshop_grades", "grade",
1693 "assessmentid", $assessment->id
, "elementno", $i);
1694 if (workshop_is_teacher($workshop, $assessment->userid
)) {
1695 $sum[$i] +
= $workshop->teacherweight
* $grade; // teacher's grade
1697 $sum[$i] +
= $grade; // student's grade
1701 if ($num) { // could all the assessments be duff?
1702 for ($i = 0; $i < $workshop->nelements
; $i++
) {
1703 $mean[$i] = $sum[$i] / $num;
1704 if ($verbose) echo "Submission: $submission->id; Element: $i; Mean: {$mean[$i]}\n";
1707 continue; // move to the next submission
1709 // run through the assessments again to see which is the "best" one (the one
1710 // closest to the mean)
1712 foreach ($assessments as $assessment) {
1713 if ($workshop->agreeassessments
and !$assessment->timeagreed
) {
1714 // ignore assessments that have not been agreed
1718 for ($i = 0; $i < $workshop->nelements
; $i++
) {
1719 $grade = get_field("workshop_grades", "grade",
1720 "assessmentid", $assessment->id
, "elementno", $i);
1721 if ($sd[$i] > $minvar) {
1722 $temp = ($mean[$i] - $grade) *
1723 $WORKSHOP_EWEIGHTS[$weight[$i]] / $sd[$i];
1727 $var +
= $temp * $temp;
1729 // find the "best" assessment of this submission
1730 if ($lowest > $var) {
1732 $bestassessmentid = $assessment->id
;
1736 if (!$best = get_record("workshop_assessments", "id", $bestassessmentid)) {
1737 notify("Workshop grade assessments: cannot find best assessment");
1741 echo "Best assessment is $bestassessmentid;\n";
1743 foreach ($assessments as $assessment) {
1744 // don't overwrite teacher's grade
1745 if ($assessment->teachergraded
) {
1748 if ($assessment->id
== $bestassessmentid) {
1749 // it's the best one, set the grading grade to the maximum
1750 set_field("workshop_assessments", "gradinggrade", 100, "id", $assessment->id
);
1751 set_field("workshop_assessments", "timegraded", $timenow, "id", $assessment->id
);
1753 // it's one of the pack, compare with the best...
1754 $gradinggrade = workshop_compare_assessments($workshop, $best, $assessment);
1755 // ...and save the grade for the assessment
1756 set_field("workshop_assessments", "gradinggrade", $gradinggrade, "id", $assessment->id
);
1757 set_field("workshop_assessments", "timegraded", $timenow, "id", $assessment->id
);
1762 // there are less than 3 assessments for this submission
1763 if ($assessments = workshop_get_assessments($submission)) {
1764 foreach ($assessments as $assessment) {
1765 if (!$assessment->timegraded
and !$assessment->teachergraded
) {
1766 // set the grading grade to the maximum and say it's been graded
1767 set_field("workshop_assessments", "gradinggrade", 100, "id", $assessment->id
);
1768 set_field("workshop_assessments", "timegraded", $timenow, "id", $assessment->id
);
1773 // set the number of assessments for this submission
1774 set_field("workshop_submissions", "nassessments", $nassessments, "id", $submission->id
);
1782 //////////////////////////////////////////////////////////////////////////////////////
1783 function workshop_gradinggrade($workshop, $student) {
1784 // returns the current (external) grading grade of the based on their (cold) assessments
1785 // (needed as it's called by grade)
1788 if ($assessments = workshop_get_user_assessments($workshop, $student)) {
1790 foreach ($assessments as $assessment) {
1791 $gradinggrade +
= $assessment->gradinggrade
;
1794 if ($n < ($workshop->ntassessments +
$workshop->nsassessments
)) { // the minimum students should do
1795 $n = $workshop->ntassessments +
$workshop->nsassessments
;
1797 $gradinggrade = $gradinggrade / $n;
1799 return number_format($gradinggrade * $workshop->gradinggrade
/ 100, 1);
1803 //////////////////////////////////////////////////////////////////////////////////////
1804 function workshop_submission_grade($workshop, $submission) {
1805 // returns the current (external) grade of the submission based on the "good" (cold) assessments
1806 // (needed as it's called by grade)
1809 if ($assessments = workshop_get_assessments($submission)) {
1811 foreach ($assessments as $assessment) {
1812 if ($workshop->agreeassessments
and !$assessment->timeagreed
) {
1813 // ignore assessments which have not been agreed
1816 if ($assessment->gradinggrade
or !$assessment->timegraded
) {
1817 // a good assessment (or one that has not been graded yet)
1818 if (workshop_is_teacher($workshop, $assessment->userid
)) {
1820 if ($timenow > $workshop->releasegrades
) {
1821 // teacher's grade is available
1822 $grade +
= $workshop->teacherweight
* $assessment->grade
;
1823 $n +
= $workshop->teacherweight
;
1826 $grade +
= $assessment->grade
;
1831 if ($n) { // stop division by zero
1832 $grade = $grade / $n;
1835 return number_format($grade * $workshop->grade
/ 100, 1);
1839 /////////////////////////////////////////////////////////////////////////////
1840 function workshop_fullname($userid, $courseid) {
1842 if (!$user = get_record('user', 'id', $userid)) {
1845 return '<a href="'.$CFG->wwwroot
.'/user/view.php?id='.$user->id
.'&course='.$courseid.'">'.
1846 fullname($user).'</a>';
1849 function workshop_get_view_actions() {
1850 return array('view','view all');
1853 function workshop_get_post_actions() {
1854 return array('agree','assess','comment','grade','newattachment','removeattachments','resubmit','submit');
1858 * Returns all other caps used in module
1860 function workshop_get_extra_capabilities() {
1861 return array('moodle/site:accessallgroups', 'moodle/site:viewfullnames');