More changes to the user interface. See http://moodle.org/mod/forum/view.php?id=740.
[moodle.git] / mod / workshop / lib.php
1 <?php  // $Id: lib.php,v 1.1 23 Aug 2003
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 include_once("$CFG->dirroot/files/mimetypes.php");
10 /*** Constants **********************************/
12 $WORKSHOP_TYPE = array (0 => get_string("notgraded", "workshop"),
13                           1 => get_string("accumulative", "workshop"),
14                           2 => get_string("errorbanded", "workshop"),
15                           3 => get_string("criterion", "workshop"),
16                           4 => get_string("rubric", "workshop") );
18 $WORKSHOP_SHOWGRADES = array (0 => get_string("dontshowgrades", "workshop"),
19                           1 => get_string("showgrades", "workshop") );
21 $WORKSHOP_SCALES = array( 
22                     0 => array( 'name' => get_string("scaleyes", "workshop"), 'type' => 'radio', 
23                         'size' => 2, 'start' => get_string("yes"), 'end' => get_string("no")),
24                     1 => array( 'name' => get_string("scalepresent", "workshop"), 'type' => 'radio', 
25                         'size' => 2, 'start' => get_string("present", "workshop"), 
26                         'end' => get_string("absent", "workshop")),
27                     2 => array( 'name' => get_string("scalecorrect", "workshop"), 'type' => 'radio', 
28                         'size' => 2, 'start' => get_string("correct", "workshop"), 
29                         'end' => get_string("incorrect", "workshop")), 
30                     3 => array( 'name' => get_string("scalegood3", "workshop"), 'type' => 'radio', 
31                         'size' => 3, 'start' => get_string("good", "workshop"), 
32                         'end' => get_string("poor", "workshop")), 
33                     4 => array( 'name' => get_string("scaleexcellent4", "workshop"), 'type' => 'radio', 
34                         'size' => 4, 'start' => get_string("excellent", "workshop"), 
35                         'end' => get_string("verypoor", "workshop")),
36                     5 => array( 'name' => get_string("scaleexcellent5", "workshop"), 'type' => 'radio', 
37                         'size' => 5, 'start' => get_string("excellent", "workshop"), 
38                         'end' => get_string("verypoor", "workshop")),
39                     6 => array( 'name' => get_string("scaleexcellent7", "workshop"), 'type' => 'radio', 
40                         'size' => 7, 'start' => get_string("excellent", "workshop"), 
41                         'end' => get_string("verypoor", "workshop")),
42                     7 => array( 'name' => get_string("scale10", "workshop"), 'type' => 'selection', 
43                         'size' => 10),
44                     8 => array( 'name' => get_string("scale20", "workshop"), 'type' => 'selection', 
45                             'size' => 20),
46                     9 => array( 'name' => get_string("scale100", "workshop"), 'type' => 'selection', 
47                             'size' => 100)); 
49 $WORKSHOP_EWEIGHTS = array(  0 => -4.0, 1 => -2.0, 2 => -1.5, 3 => -1.0, 4 => -0.75, 5 => -0.5,  6 => -0.25, 
50                              7 => 0.0, 8 => 0.25, 9 => 0.5, 10 => 0.75, 11=> 1.0, 12 => 1.5, 13=> 2.0, 
51                              14 => 4.0); 
53 $WORKSHOP_FWEIGHTS = array(  0 => 0, 1 => 0.1, 2 => 0.25, 3 => 0.5, 4 => 0.75, 5 => 1.0,  6 => 1.5, 
54                              7 => 2.0, 8 => 3.0, 9 => 5.0, 10 => 7.5, 11=> 10.0, 12=>50.0); 
57 $WORKSHOP_ASSESSMENT_COMPS = array (
58                           0 => array('name' => get_string("verylax", "workshop"), 'value' => 1),
59                           1 => array('name' => get_string("lax", "workshop"), 'value' => 0.6),
60                           2 => array('name' => get_string("fair", "workshop"), 'value' => 0.4),
61                           3 => array('name' => get_string("strict", "workshop"), 'value' => 0.33),
62                           4 => array('name' => get_string("verystrict", "workshop"), 'value' => 0.2) );
66 /*** Standard Moodle functions ******************
67 workshop_add_instance($workshop) 
68 workshop_check_dates($workshop)
69 workshop_cron () 
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);
107     
108     if (!workshop_check_dates($workshop)) {
109         return get_string('invaliddates', 'workshop');
110     }
112     if ($returnid = insert_record("workshop", $workshop)) {
114         $event = NULL;
115         $event->name        = get_string('submissionstartevent','workshop', $workshop->name);
116         $event->description = $workshop->description;
117         $event->courseid    = $workshop->course;
118         $event->groupid     = 0;
119         $event->userid      = 0;
120         $event->modulename  = 'workshop';
121         $event->instance    = $returnid;
122         $event->eventtype   = 'submissionstart';
123         $event->timestart   = $workshop->submissionstart;
124         $event->timeduration = 0;
125         add_event($event);
127         $event->name        = get_string('submissionendevent','workshop', $workshop->name);
128         $event->eventtype   = 'submissionend';
129         $event->timestart   = $workshop->submissionend;
130         add_event($event);
132         $event->name        = get_string('assessmentstartevent','workshop', $workshop->name);
133         $event->eventtype   = 'assessmentstart';
134         $event->timestart   = $workshop->assessmentstart;
135         add_event($event);
137         $event->name        = get_string('assessmentendevent','workshop', $workshop->name);
138         $event->eventtype   = 'assessmentend';
139         $event->timestart   = $workshop->assessmentend;
140         add_event($event);
141     }
143     return $returnid;
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
162     global $CFG, $USER;
163     
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);
170             }
171         }
172     }
173     $timenow = time();
174     
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";
183             
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";
187             }
188             
189             if (! $submission = get_record("workshop_submissions", "id", "$assessment->submissionid")) {
190                 echo "Could not find submission $assessment->submissionid\n";
191                 continue;
192             }
193             if (! $workshop = get_record("workshop", "id", $submission->workshopid)) {
194                 echo "Could not find workshop id $submission->workshopid\n";
195                 continue;
196             }
197             if (! $course = get_record("course", "id", $workshop->course)) {
198                 error("Could not find course id $workshop->course");
199                 continue;
200             }
201             if (! $cm = get_coursemodule_from_instance("workshop", $workshop->id, $course->id)) {
202                 error("Course Module ID was incorrect");
203                 continue;
204             }
205             if (! $submissionowner = get_record("user", "id", "$submission->userid")) {
206                 echo "Could not find user $submission->userid\n";
207                 continue;
208             }
209             if (! $assessmentowner = get_record("user", "id", "$assessment->userid")) {
210                 echo "Could not find user $assessment->userid\n";
211                 continue;
212             }
213             if (! isstudent($course->id, $submissionowner->id) and !isteacher($course->id, 
214                         $submissionowner->id)) {
215                 continue;  // Not an active participant
216             }
217             if (! isstudent($course->id, $assessmentowner->id) and !isteacher($course->id, 
218                         $assessmentowner->id)) {
219                 continue;  // Not an active participant
220             }
221             // don't sent self assessment
222             if ($submissionowner->id == $assessmentowner->id) {
223                 continue;
224             }
225             $strworkshops = get_string("modulenameplural", "workshop");
226             $strworkshop  = get_string("modulename", "workshop");
227     
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 (isstudent($course->id, $assessmentowner->id)) {
233                 $msg = get_string("mail1", "workshop", $submission->title)." a $course->student.\n";
234             }
235             else {
236                 $msg = get_string("mail1", "workshop", $submission->title).
237                     " ".fullname($assessmentowner)."\n";
238             }
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";
242     
243             $postsubject = "$course->shortname: $strworkshops: $workshop->name";
244             $posttext  = "$course->shortname -> $strworkshops -> $workshop->name\n";
245             $posttext .= "---------------------------------------------------------------------\n";
246             $posttext .= $msg;
247             // "The comments and grade can be seen in ..."
248             $posttext .= get_string("mail2", "workshop", 
249                 "$workshop->name,   $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\">$workshop->name</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\">$workshop->name</a>")."</p></font><hr>";
260             } else {
261                 $posthtml = "";
262             }
263     
264             if (!$teacher = get_teacher($course->id)) {
265                 echo "Error: can not find teacher for course $course->id!\n";
266             }
267                 
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";
271             }
272         }
273     }
274         
275     // look for new assessments of resubmissions
276     if ($assessments = workshop_get_unmailed_resubmissions($cutofftime)) {
277         $timenow = time();
279         foreach ($assessments as $assessment) {
281             echo "Processing workshop assessment $assessment->id\n";
282             
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";
286             }
287             
288             if (! $submission = get_record("workshop_submissions", "id", "$assessment->submissionid")) {
289                 echo "Could not find submission $assessment->submissionid\n";
290                 continue;
291             }
292             if (! $workshop = get_record("workshop", "id", $submission->workshopid)) {
293                 echo "Could not find workshop id $submission->workshopid\n";
294                 continue;
295             }
296             if (! $course = get_record("course", "id", $workshop->course)) {
297                 error("Could not find course id $workshop->course");
298                 continue;
299             }
300             if (! $cm = get_coursemodule_from_instance("workshop", $workshop->id, $course->id)) {
301                 error("Course Module ID was incorrect");
302                 continue;
303             }
304             if (! $submissionowner = get_record("user", "id", "$submission->userid")) {
305                 echo "Could not find user $submission->userid\n";
306                 continue;
307             }
308             if (! $assessmentowner = get_record("user", "id", "$assessment->userid")) {
309                 echo "Could not find user $assessment->userid\n";
310                 continue;
311             }
312             if (! isstudent($course->id, $submissionowner->id) and !isteacher($course->id, 
313                         $submissionowner->id)) {
314                 continue;  // Not an active participant
315             }
316             if (! isstudent($course->id, $assessmentowner->id) and !isteacher($course->id, 
317                         $assessmentowner->id)) {
318                 continue;  // Not an active participant
319             }
320     
321             $strworkshops = get_string("modulenameplural", "workshop");
322             $strworkshop  = get_string("modulename", "workshop");
323     
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";
331     
332             $postsubject = "$course->shortname: $strworkshops: $workshop->name";
333             $posttext  = "$course->shortname -> $strworkshops -> $workshop->name\n";
334             $posttext .= "---------------------------------------------------------------------\n";
335             $posttext .= $msg;
336             // "Please assess it in ..."
337             $posttext .= get_string("mail9", "workshop", 
338                            "$workshop->name, $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\">$workshop->name</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\">$workshop->name</a>").'</p></font><hr>';
349             } 
350             else {
351               $posthtml = "";
352             }
353     
354             if (!$teacher = get_teacher($course->id)) {
355                 echo "Error: can not find teacher for course $course->id!\n";
356             }
357                 
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";
361             }
362         }
363     }
364     
365     // look for new comments
366     if ($comments = workshop_get_unmailed_comments($cutofftime)) {
367         $timenow = time();
369         foreach ($comments as $comment) {
371             echo "Processing workshop comment $comment->id\n";
372             
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";
376             }
377             
378             if (! $assessment = get_record("workshop_assessments", "id", "$comment->assessmentid")) {
379                 echo "Could not find assessment $comment->assessmentid\n";
380                 continue;
381             }
382             if (! $submission = get_record("workshop_submissions", "id", "$assessment->submissionid")) {
383                 echo "Could not find submission $assessment->submissionid\n";
384                 continue;
385             }
386             if (! $workshop = get_record("workshop", "id", $submission->workshopid)) {
387                 echo "Could not find workshop id $submission->workshopid\n";
388                 continue;
389             }
390             if (! $course = get_record("course", "id", $workshop->course)) {
391                 error("Could not find course id $workshop->course");
392                 continue;
393             }
394             if (! $cm = get_coursemodule_from_instance("workshop", $workshop->id, $course->id)) {
395                 error("Course Module ID was incorrect");
396                 continue;
397             }
398             if (! $submissionowner = get_record("user", "id", "$submission->userid")) {
399                 echo "Could not find user $submission->userid\n";
400                 continue;
401             }
402             if (! $assessmentowner = get_record("user", "id", "$assessment->userid")) {
403                 echo "Could not find user $assessment->userid\n";
404                 continue;
405             }
406             if (! isstudent($course->id, $submissionowner->id) and !isteacher($course->id, 
407                         $submissionowner->id)) {
408                 continue;  // Not an active participant
409             }
410             if (! isstudent($course->id, $assessmentowner->id) and !isteacher($course->id, 
411                         $assessmentowner->id)) {
412                 continue;  // Not an active participant
413             }
414     
415             $strworkshops = get_string("modulenameplural", "workshop");
416             $strworkshop  = get_string("modulename", "workshop");
417     
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 (isstudent($course->id, $assessmentowner->id)) {
424                     $msg = get_string("mail4", "workshop", $submission->title)." a $course->student.\n";
425                 }
426                 else {
427                     $msg = get_string("mail4", "workshop", $submission->title)." ".fullname($assessmentowner)."\n";
428                 }
429                 // "The new comment can be seen in the workshop assignment '$workshop->name'
430                 // $msg .= get_string("mail5", "workshop", $workshop->name)."\n\n";
431     
432                 $postsubject = "$course->shortname: $strworkshops: $workshop->name";
433                 $posttext  = "$course->shortname -> $strworkshops -> $workshop->name\n";
434                 $posttext .= "---------------------------------------------------------------------\n";
435                 $posttext .= $msg;
436                 // "The new comment can be seen in ..."
437                 $posttext .= get_string("mail5", "workshop",
438                     "$workshop->name,   $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\">$workshop->name</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\">$workshop->name</a>")
449                         ."</p></font><hr>";
450                 } 
451                 else {
452                     $posthtml = "";
453                 }
454     
455                 if (!$teacher = get_teacher($course->id)) {
456                     echo "Error: can not find teacher for course $course->id!\n";
457                 }
458                     
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";
462                 }
463             }
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 (isstudent($course->id, $submissionowner->id)) {
470                     $msg = get_string("mail4", "workshop", $submission->title)." a $course->student.\n";
471                 }
472                 else {
473                     $msg = get_string("mail4", "workshop", $submission->title).
474                         " ".fullname($submissionowner)."\n";
475                 }
476                 // "The new comment can be seen in the workshop assignment '$workshop->name'
477                 // $msg .= get_string("mail5", "workshop", $workshop->name)."\n\n";
478     
479                 $postsubject = "$course->shortname: $strworkshops: $workshop->name";
480                 $posttext  = "$course->shortname -> $strworkshops -> $workshop->name\n";
481                 $posttext .= "---------------------------------------------------------------------\n";
482                 $posttext .= $msg;
483                 // "The new comment can be seen in ..."
484                 $posttext .= get_string("mail5", "workshop",
485                     "$workshop->name,  $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\">$workshop->name</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\">$workshop->name</a>")
496                         ."</p></font><hr>";
497                 } 
498                 else {
499                     $posthtml = "";
500                 }
501     
502                 if (!$teacher = get_teacher($course->id)) {
503                     echo "Error: can not find teacher for course $course->id!\n";
504                 }
505                     
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";
509                 }
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";
512                 }
513             }
514         }
515     }
516     return true;
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")) {
527         return false;
528     }
529     
530     // delete all the associated records in the workshop tables, start positive...
531     $result = true;
533     if (! delete_records("workshop_comments", "workshopid", "$workshop->id")) {
534         $result = false;
535     }
537     if (! delete_records("workshop_stockcomments", "workshopid", "$workshop->id")) {
538         $result = false;
539     }
541     if (! delete_records("workshop_grades", "workshopid", "$workshop->id")) {
542         $result = false;
543     }
545     if (! delete_records("workshop_elements", "workshopid", "$workshop->id")) {
546         $result = false;
547     }
549     if (! delete_records("workshop_assessments", "workshopid", "$workshop->id")) {
550         $result = false;
551     }
553     if (! delete_records("workshop_submissions", "workshopid", "$workshop->id")) {
554         $result = false;
555     }
557     if (! delete_records("workshop", "id", "$workshop->id")) {
558         $result = false;
559     }
561     if (! delete_records('event', 'modulename', 'workshop', 'instance', $workshop->id)) {
562         $result = false;    
563     }   
565     return $result;
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
574     global $CFG;
576     $return = null;
577     if ($workshop = get_record("workshop", "id", $workshopid)) {
578         if (($workshop->assessmentstart < time()) and $workshop->gradingstrategy) {
579             if ($students = get_course_students($workshop->course)) {
580                 foreach ($students as $student) {
581                     if ($workshop->wtype) {
582                         $gradinggrade = workshop_gradinggrade($workshop, $student);
583                     } else { // ignore grading grades for simple assignments
584                         $gradinggrade = 0;
585                     }
586                     $bestgrade = 0;
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);
591                             } else {
592                                 $grade = 0.01;
593                             }
594                             if ($grade > $bestgrade) {
595                                 $bestgrade = $grade;
596                             }
597                         }
598                     }
599                     $return->grades[$student->id] = $gradinggrade + $bestgrade;
600                 }
601             }
602         }
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;
609             }
610         }
611     }
612     return $return;
615 //////////////////////////////////////////////////////////////////////////////////////
616 function workshop_is_recent_activity($course, $isteacher, $timestart) {//jlw1 added for adding mark to courses with activity in My Moodle
617     global $CFG;
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;
631                     break;
632                 }
633             }
634         }
635     }
636     return false;
640 ///////////////////////////////////////////////////////////////////////////////
641 function workshop_print_recent_activity($course, $isteacher, $timestart) {
642     global $CFG;
644     // have a look for agreed assessments for this user (agree) 
645     $agreecontent = false;
646     if (!$isteacher) { // teachers only need to see submissions
647         if ($logs = workshop_get_agree_logs($course, $timestart)) {
648             // got some, see if any belong to a visible module
649             foreach ($logs as $log) {
650                 // Create a temp valid module structure (only need courseid, moduleid)
651                 $tempmod->course = $course->id;
652                 $tempmod->id = $log->workshopid;
653                 //Obtain the visible property from the instance
654                 if (instance_is_visible("workshop",$tempmod)) {
655                     $agreecontent = true;
656                     break;
657                     }
658                 }
659             // if we got some "live" ones then output them
660             if ($agreecontent) {
661                 $strftimerecent = get_string("strftimerecent");
662                 print_headline(get_string("workshopagreedassessments", "workshop").":");
663                 foreach ($logs as $log) {
664                     //Create a temp valid module structure (only need courseid, moduleid)
665                     $tempmod->course = $course->id;
666                     $tempmod->id = $log->workshopid;
667                     //Obtain the visible property from the instance
668                     if (instance_is_visible("workshop",$tempmod)) {
669                         $date = userdate($log->time, $strftimerecent);
670                         if (isteacher($course->id, $log->userid)) {
671                             echo "<p><font size=\"1\">$date - ".fullname($log)."<br />";
672                             }
673                         else { // don't break anonymous rule
674                             echo "<p><font size=\"1\">$date - A $course->student<br />";
675                             }
676                         echo "\"<a href=\"$CFG->wwwroot/mod/workshop/".str_replace('&', '&amp;', $log->url)."\">";
677                         echo "$log->name";
678                         echo "</a>\"</font></p>";
679                         }
680                     }
681                 }
682             }
683         }
685     // have a look for new assessments for this user (assess) 
686     $assesscontent = false;
687     if (!$isteacher) { // teachers only need to see submissions
688         if ($logs = workshop_get_assess_logs($course, $timestart)) {
689             // got some, see if any belong to a visible module
690             foreach ($logs as $log) {
691                 // Create a temp valid module structure (only need courseid, moduleid)
692                 $tempmod->course = $course->id;
693                 $tempmod->id = $log->workshopid;
694                 //Obtain the visible property from the instance
695                 if (instance_is_visible("workshop",$tempmod)) {
696                     $assesscontent = true;
697                     break;
698                     }
699                 }
700             // if we got some "live" ones then output them
701             if ($assesscontent) {
702                 $strftimerecent = get_string("strftimerecent");
703                 print_headline(get_string("workshopassessments", "workshop").":");
704                 foreach ($logs as $log) {
705                     //Create a temp valid module structure (only need courseid, moduleid)
706                     $tempmod->course = $course->id;
707                     $tempmod->id = $log->workshopid;
708                     //Obtain the visible property from the instance
709                     if (instance_is_visible("workshop",$tempmod)) {
710                         $date = userdate($log->time, $strftimerecent);
711                         if (isteacher($course->id, $log->userid)) {
712                             echo "<p><font size=\"1\">$date - ".fullname($log)."<br />";
713                             }
714                         else { // don't break anonymous rule
715                             echo "<p><font size=\"1\">$date - A $course->student<br />";
716                             }
717                         echo "\"<a href=\"$CFG->wwwroot/mod/workshop/".str_replace('&', '&amp;', $log->url)."\">";
718                         echo "$log->name";
719                         echo "</a>\"</font></p>";
720                         }
721                     }
722                 }
723             }
724         }
726     // have a look for new comments for this user (comment) 
727     $commentcontent = false;
728     if (!$isteacher) { // teachers only need to see submissions
729         if ($logs = workshop_get_comment_logs($course, $timestart)) {
730             // got some, see if any belong to a visible module
731             foreach ($logs as $log) {
732                 // Create a temp valid module structure (only need courseid, moduleid)
733                 $tempmod->course = $course->id;
734                 $tempmod->id = $log->workshopid;
735                 //Obtain the visible property from the instance
736                 if (instance_is_visible("workshop",$tempmod)) {
737                     $commentcontent = true;
738                     break;
739                     }
740                 }
741             // if we got some "live" ones then output them
742             if ($commentcontent) {
743                 $strftimerecent = get_string("strftimerecent");
744                 print_headline(get_string("workshopcomments", "workshop").":");
745                 foreach ($logs as $log) {
746                     //Create a temp valid module structure (only need courseid, moduleid)
747                     $tempmod->course = $course->id;
748                     $tempmod->id = $log->workshopid;
749                     //Obtain the visible property from the instance
750                     if (instance_is_visible("workshop",$tempmod)) {
751                         $date = userdate($log->time, $strftimerecent);
752                         echo "<p><font size=\"1\">$date - A $course->student<br />";
753                         echo "\"<a href=\"$CFG->wwwroot/mod/workshop/".str_replace('&', '&amp;', $log->url)."\">";
754                         echo "$log->name";
755                         echo "</a>\"</font></p>";
756                         }
757                     }
758                 }
759             }
760         }
762     // have a look for new assessment gradings for this user (grade)
763     $gradecontent = false;
764     if ($logs = workshop_get_grade_logs($course, $timestart)) {
765         // got some, see if any belong to a visible module
766         foreach ($logs as $log) {
767             // Create a temp valid module structure (only need courseid, moduleid)
768             $tempmod->course = $course->id;
769             $tempmod->id = $log->workshopid;
770             //Obtain the visible property from the instance
771             if (instance_is_visible("workshop",$tempmod)) {
772                 $gradecontent = true;
773                 break;
774                 }
775             }
776         // if we got some "live" ones then output them
777         if ($gradecontent) {
778             $strftimerecent = get_string("strftimerecent");
779             print_headline(get_string("workshopfeedback", "workshop").":");
780             foreach ($logs as $log) {
781                 //Create a temp valid module structure (only need courseid, moduleid)
782                 $tempmod->course = $course->id;
783                 $tempmod->id = $log->workshopid;
784                 //Obtain the visible property from the instance
785                 if (instance_is_visible("workshop",$tempmod)) {
786                     $date = userdate($log->time, $strftimerecent);
787                     echo "<p><font size=\"1\">$date - $course->teacher<br />";
788                     echo "\"<a href=\"$CFG->wwwroot/mod/workshop/".str_replace('&', '&amp;', $log->url)."\">";
789                     echo "$log->name";
790                     echo "</a>\"</font></p>";
791                     }
792                 }
793             }
794         }
796     // have a look for new submissions (only show to teachers) (submit)
797     $submitcontent = false;
798     if ($isteacher) {
799         if ($logs = workshop_get_submit_logs($course, $timestart)) {
800             // got some, see if any belong to a visible module
801             foreach ($logs as $log) {
802                 // Create a temp valid module structure (only need courseid, moduleid)
803                 $tempmod->course = $course->id;
804                 $tempmod->id = $log->workshopid;
805                 //Obtain the visible property from the instance
806                 if (instance_is_visible("workshop",$tempmod)) {
807                     $submitcontent = true;
808                     break;
809                     }
810                 }
811             // if we got some "live" ones then output them
812             if ($submitcontent) {
813                 $strftimerecent = get_string("strftimerecent");
814                 print_headline(get_string("workshopsubmissions", "workshop").":");
815                 foreach ($logs as $log) {
816                     //Create a temp valid module structure (only need courseid, moduleid)
817                     $tempmod->course = $course->id;
818                     $tempmod->id = $log->workshopid;
819                     //Obtain the visible property from the instance
820                     if (instance_is_visible("workshop",$tempmod)) {
821                         $date = userdate($log->time, $strftimerecent);
822                         echo "<p><font size=\"1\">$date - ".fullname($log)."<br />";
823                         echo "\"<a href=\"$CFG->wwwroot/mod/workshop/".str_replace('&', '&amp;', $log->url)."\">";
824                         echo "$log->name";
825                         echo "</a>\"</font></p>";
826                         }
827                     }
828                 }
829             }
830         }
832     return $agreecontent or $assesscontent or $commentcontent or $gradecontent or $submitcontent;
836 ///////////////////////////////////////////////////////////////////////////////
837 function workshop_refresh_events($courseid = 0) {
838 // This standard function will check all instances of this module
839 // and make sure there are up-to-date events created for each of them.
840 // If courseid = 0, then every workshop event in the site is checked, else
841 // only workshop events belonging to the course specified are checked.
842 // This function is used, in its new format, by restore_refresh_events()
844     if ($courseid == 0) {
845         if (! $workshops = get_records("workshop")) {
846             return true;        
847         }   
848     } else {
849         if (! $workshops = get_records("workshop", "course", $courseid)) {
850             return true;
851         }
852     }
853     $moduleid = get_field('modules', 'id', 'name', 'workshop');
854     
855     foreach ($workshops as $workshop) {
856     
857         $dates = array(
858             'submissionstart' => $workshop->submissionstart,
859             'submissionend' => $workshop->submissionend,
860             'assessmentstart' => $workshop->assessmentstart,
861             'assessmentend' => $workshop->assessmentend
862         );
863         
864         foreach ($dates as $type => $date) {
865         
866             if ($date) {
867                 if ($event = get_record('event', 'modulename', 'workshop', 'instance', $workshop->id, 'eventtype', $type)) {
868                     $event->name        = addslashes(get_string($type.'event','workshop', $workshop->name));
869                     $event->description = addslashes($workshop->description);
870                     $event->eventtype   = $type;
871                     $event->timestart   = $date;
872                     update_event($event);
873                 } else {
874                     $event->courseid    = $workshop->course;
875                     $event->modulename  = 'workshop';
876                     $event->instance    = $workshop->id; 
877                     $event->name        = addslashes(get_string($type.'event','workshop', $workshop->name));
878                     $event->description = addslashes($workshop->description);
879                     $event->eventtype   = $type;
880                     $event->timestart   = $date;
881                     $event->timeduration = 0;
882                     $event->visible     = get_field('course_modules', 'visible', 'module', $moduleid, 'instance', $workshop->id); 
883                     add_event($event);
884                 }
885             }
886         }
887     }
888     return true;
889 }   
892 ///////////////////////////////////////////////////////////////////////////////
893 function workshop_update_instance($workshop) {
894 // Given an object containing all the necessary data, 
895 // (defined by the form in mod.html) this function 
896 // will update an existing instance with new data.
897     global $CFG;
899     $workshop->timemodified = time();
901     $workshop->submissionstart = make_timestamp($workshop->submissionstartyear, 
902             $workshop->submissionstartmonth, $workshop->submissionstartday, $workshop->submissionstarthour, 
903             $workshop->submissionstartminute);
905     $workshop->assessmentstart = make_timestamp($workshop->assessmentstartyear, 
906             $workshop->assessmentstartmonth, $workshop->assessmentstartday, $workshop->assessmentstarthour, 
907             $workshop->assessmentstartminute);
909     $workshop->submissionend = make_timestamp($workshop->submissionendyear, 
910             $workshop->submissionendmonth, $workshop->submissionendday, $workshop->submissionendhour, 
911             $workshop->submissionendminute);
913     $workshop->assessmentend = make_timestamp($workshop->assessmentendyear, 
914             $workshop->assessmentendmonth, $workshop->assessmentendday, $workshop->assessmentendhour, 
915             $workshop->assessmentendminute);
917     $workshop->releasegrades = make_timestamp($workshop->releaseyear, 
918             $workshop->releasemonth, $workshop->releaseday, $workshop->releasehour, 
919             $workshop->releaseminute);
920             
921     if (!workshop_check_dates($workshop)) {
922         return get_string('invaliddates', 'workshop');
923     }
925     // set the workshop's type
926     $wtype = 0; // 3 phases, no grading grades
927     if ($workshop->includeself or $workshop->ntassessments) $wtype = 1; // 3 phases with grading grades
928     if ($workshop->nsassessments) $wtype = 2; // 5 phases with grading grades 
929     $workshop->wtype = $wtype;
930     
931     // encode password if necessary
932     if (!empty($workshop->password)) {
933         $workshop->password = md5($workshop->password);
934     } else {
935         unset($workshop->password);
936     }
938     $workshop->id = $workshop->instance;
940     if ($returnid = update_record("workshop", $workshop)) {
942         $dates = array(
943             'submissionstart' => $workshop->submissionstart,
944             'submissionend' => $workshop->submissionend,
945             'assessmentstart' => $workshop->assessmentstart,
946             'assessmentend' => $workshop->assessmentend
947         );
948         $moduleid = get_field('modules', 'id', 'name', 'workshop');
949         
950         foreach ($dates as $type => $date) {
951             if ($event = get_record('event', 'modulename', 'workshop', 'instance', $workshop->id, 'eventtype', $type)) {
952                 $event->name        = get_string($type.'event','workshop', $workshop->name);
953                 $event->description = $workshop->description;
954                 $event->eventtype   = $type;
955                 $event->timestart   = $date;
956                 update_event($event);
957             } else if ($date) {
958                 $event = NULL;
959                 $event->name        = get_string($type.'event','workshop', $workshop->name);
960                 $event->description = $workshop->description;
961                 $event->courseid    = $workshop->course;
962                 $event->groupid     = 0;
963                 $event->userid      = 0;
964                 $event->modulename  = 'workshop';
965                 $event->instance    = $workshop->instance;
966                 $event->eventtype   = $type;
967                 $event->timestart   = $date;
968                 $event->timeduration = 0;
969                 $event->visible     = get_field('course_modules', 'visible', 'module', $moduleid, 'instance', $workshop->id); 
970                 add_event($event);
971             }
972         }
973     }
975     if (time() > $workshop->assessmentstart) {
976         // regrade all the submissions...
977         set_field("workshop_submissions", "nassessments", 0, "workshopid", $workshop->id);
978         workshop_grade_assessments($workshop);
979     }
981     return $returnid;
984 ///////////////////////////////////////////////////////////////////////////////
985 function workshop_user_complete($course, $user, $mod, $workshop) {
986     if ($submission = workshop_get_student_submission($workshop, $user)) {
987         if ($basedir = workshop_file_area($workshop, $user)) {
988             if ($files = get_directory_list($basedir)) {
989                 $countfiles = count($files)." ".get_string("submissions", "workshop");
990                 foreach ($files as $file) {
991                     $countfiles .= "; $file";
992                 }
993             }
994         }
996         print_simple_box_start();
998         //workshop_print_user_files($workshop, $user);
1000         echo "Submission was made but no way to show you yet.";   //xxx
1002         //workshop_print_feedback($course, $submission);
1004         print_simple_box_end();
1006     } else {
1007         print_string("notsubmittedyet", "workshop");
1008     }
1013 ///////////////////////////////////////////////////////////////////////////////
1014 function workshop_user_outline($course, $user, $mod, $workshop) {
1015     if ($submissions = workshop_get_user_submissions($workshop, $user)) {
1016         $result->info = count($submissions)." ".get_string("submissions", "workshop");
1017         // workshop_get_user_submissions returns the newest one first
1018         foreach ($submissions as $submission) {
1019             $result->time = $submission->timecreated;
1020             break;
1021             }
1022         return $result;
1023     }
1024     return NULL;
1027 //////////////////////////////////////////////////////////////////////////////////////
1028 function workshop_get_participants($workshopid) {      
1029 //Returns the users with data in one workshop
1030 //(users with records in workshop_submissions, workshop_assessments and workshop_comments, students)
1032     global $CFG;
1034     //Get students from workshop_submissions
1035     $st_submissions = get_records_sql("SELECT DISTINCT u.*
1036                                        FROM {$CFG->prefix}user u,
1037                                             {$CFG->prefix}workshop_submissions s
1038                                        WHERE s.workshopid = '$workshopid' and
1039                                              u.id = s.userid");
1040     //Get students from workshop_assessments
1041     $st_assessments = get_records_sql("SELECT DISTINCT u.*
1042                                  FROM {$CFG->prefix}user u,
1043                                       {$CFG->prefix}workshop_assessments a
1044                                  WHERE a.workshopid = '$workshopid' and
1045                                        u.id = a.userid");
1047     //Get students from workshop_comments
1048     $st_comments = get_records_sql("SELECT DISTINCT u.*
1049                                    FROM {$CFG->prefix}user u,
1050                                         {$CFG->prefix}workshop_comments c
1051                                    WHERE c.workshopid = '$workshopid' and
1052                                          u.id = c.userid");
1054     //Add st_assessments to st_submissions
1055     if ($st_assessments) {
1056         foreach ($st_assessments as $st_assessment) {
1057             $st_submissions[$st_assessment->id] = $st_assessment;
1058         }
1059     }
1060     //Add st_comments to st_submissions
1061     if ($st_comments) {
1062         foreach ($st_comments as $st_comment) {
1063             $st_submissions[$st_comment->id] = $st_comment;
1064         }
1065     }
1066     //Return st_submissions array (it contains an array of unique users)
1067     return ($st_submissions);
1070 //////////////////////////////////////////////////////////////////////////////////////
1071 function workshop_get_recent_mod_activity(&$activities, &$index, $sincetime, $courseid, 
1072                                            $workshop="0", $user="", $groupid="") {
1073     // Returns all workshop posts since a given time.  If workshop is specified then
1074     // this restricts the results
1076     global $CFG;
1078     if ($workshop) {
1079         $workshopselect = " AND cm.id = '$workshop'";
1080     } else {
1081         $workshopselect = "";
1082     }
1084     if ($user) {
1085         $userselect = " AND u.id = '$user'";
1086     } else {
1087         $userselect = "";
1088     }
1090     $posts = get_records_sql("SELECT s.*, u.firstname, u.lastname,
1091             u.picture, cm.instance, w.name, cm.section
1092             FROM {$CFG->prefix}workshop_submissions s,
1093             {$CFG->prefix}user u,
1094             {$CFG->prefix}course_modules cm,
1095             {$CFG->prefix}workshop w
1096             WHERE s.timecreated  > '$sincetime' $workshopselect
1097             AND s.userid = u.id $userselect
1098             AND w.course = '$courseid' $groupselect
1099             AND cm.instance = w.id
1100             AND cm.course = w.course
1101             AND s.workshopid = w.id
1102             ORDER BY s.id");
1105     if (empty($posts)) {
1106         return;
1107     }
1109     foreach ($posts as $post) {
1111         if (empty($groupid) || ismember($groupid, $post->userid)) {
1112             $tmpactivity->type = "workshop";
1113             $tmpactivity->defaultindex = $index;
1114             $tmpactivity->instance = $post->instance;
1115             $tmpactivity->name = $post->name;
1116             $tmpactivity->section = $post->section;
1118             $tmpactivity->content->id = $post->id;
1119             $tmpactivity->content->title = $post->title;
1121             $tmpactivity->user->userid = $post->userid;
1122             $tmpactivity->user->fullname = fullname($post);
1123             $tmpactivity->user->picture = $post->picture;
1125             $tmpactivity->timestamp = $post->timecreated;
1126             $activities[] = $tmpactivity;
1128             $index++;
1129         }
1130     }
1132     return;
1135 //////////////////////////////////////////////////////////////////////////////////////
1136 function workshop_print_recent_mod_activity($activity, $course, $detail=false) {
1138     global $CFG;
1140     echo '<table border="0" cellpadding="3" cellspacing="0">';
1142     if ($activity->content->parent) {
1143         $openformat = "<font size=\"2\"><i>";
1144         $closeformat = "</i></font>";
1145     } else {
1146         $openformat = "<b>";
1147         $closeformat = "</b>";
1148     }
1150     echo "<tr><td bgcolor=\"$THEME->cellcontent2\" class=\"workshoppostpicture\" width=\"35\" valign=\"top\">";
1151     print_user_picture($activity->user->userid, $course, $activity->user->picture);
1152     echo "</td><td>$openformat";
1154     if ($detail) {
1155         echo "<img src=\"$CFG->modpixpath/$activity->type/icon.gif\" ".
1156             "height=\"16\" width=\"16\" alt=\"$activity->name\" />  ";
1157     }
1158     echo "<a href=\"$CFG->wwwroot/mod/workshop/view.php?" 
1159         . "#" . $activity->content->id . "\">".$activity->content->title;
1161     echo "</a>$closeformat";
1163     echo "<br /><font size=\"2\">";
1164     echo "<a href=\"$CFG->wwwroot/user/view.php?id=" . $activity->user->userid . "&amp;course=" . "$course\">"
1165         . $activity->user->fullname . "</a>";
1166     echo " - " . userdate($activity->timestamp) . "</font></td></tr>";
1167     echo "</table>";
1169     return;
1174 //////////////////////////////////////////////////////////////////////////////////////
1175 // Non-standard workshop functions
1176 ///////////////////////////////////////////////////////////////////////////////////////////////
1177 function workshop_compare_assessments($workshop, $assessment1, $assessment2) {
1178     global $WORKSHOP_ASSESSMENT_COMPS, $WORKSHOP_EWEIGHTS;
1179     // first get the assignment elements for maxscores...
1180     $elementsraw = get_records("workshop_elements", "workshopid", $workshop->id, "elementno ASC");
1181     foreach ($elementsraw as $element) {
1182         $maxscore[] = $element->maxscore;   // to renumber index 0,1,2...
1183         $weight[] = $WORKSHOP_EWEIGHTS[$element->weight];   // get real value and renumber index 0,1,2...
1184     }
1185     for ($i = 0; $i < 2; $i++) {
1186         if ($i) {
1187             $rawgrades = get_records("workshop_grades", "assessmentid", $assessment1->id, "elementno ASC");
1188         } else {
1189             $rawgrades = get_records("workshop_grades", "assessmentid", $assessment2->id, "elementno ASC");
1190         }
1191         foreach ($rawgrades as $grade) {
1192             $grades[$i][] = $grade->grade;
1193         }
1194     }
1195     $sumdiffs = 0;
1196     $sumweights = 0;
1197     switch ($workshop->gradingstrategy) {
1198         case 1 : // accumulative grading and...
1199         case 4 : // ...rubic grading
1200             for ($i=0; $i < $workshop->nelements; $i++) {
1201                 $diff = ($grades[0][$i] - $grades[1][$i]) * $weight[$i] / $maxscore[$i];
1202                 $sumdiffs += $diff * $diff; // use squared distances
1203                 $sumweights += $weight[$i];
1204                 }
1205             break;
1206         case 2 :  // error banded grading
1207             // ignore maxscores here, the grades are either 0 or 1,
1208             for ($i=0; $i < $workshop->nelements; $i++) {
1209                 $diff = ($grades[0][$i] - $grades[1][$i]) * $weight[$i];
1210                 $sumdiffs += $diff * $diff; // use squared distances
1211                 $sumweights += $weight[$i];
1212                 }
1213             break;
1214         case 3 : // criterion grading
1215             // here we only need to look at the difference between the "zero" grade elements
1216             $diff = ($grades[0][0] - $grades[1][0]) / (count($elementsraw) - 1);
1217             $sumdiffs = $diff * $diff;
1218             $sumweights = 1;
1219             break;
1220     }            
1221     // convert to a sensible grade (always out of 100)
1222     $COMP = (object)$WORKSHOP_ASSESSMENT_COMPS[$workshop->assessmentcomps];
1223     $factor = $COMP->value;
1224     $gradinggrade = (($factor - ($sumdiffs / $sumweights)) / $factor) * 100;
1225     if ($gradinggrade < 0) {
1226         $gradinggrade = 0;
1227     }
1228     return $gradinggrade;
1232 //////////////////////////////////////////////////////////////////////////////////////
1233 function workshop_count_assessments($submission) {
1234     // Return the (real) assessments for this submission, 
1235     $timenow = time();
1236    return count_records_select("workshop_assessments", 
1237            "submissionid = $submission->id AND timecreated < $timenow");
1241 //////////////////////////////////////////////////////////////////////////////////////
1242 function workshop_count_ungraded_assessments($workshop) {
1243     // function returns the number of ungraded assessments by students
1244     global $CFG;
1245     
1246     $timenow = time();
1247     $n = 0;
1248     // get all the cold assessments that have not been graded
1249     if ($assessments = get_records_select("workshop_assessments", "workshopid = $workshop->id AND 
1250             (timecreated + $CFG->maxeditingtime) < $timenow AND timegraded = 0")) {
1251         foreach ($assessments as $assessment) {
1252             if (isstudent($workshop->course, $assessment->userid)) {
1253                 $n++;
1254             }
1255         }
1256     }
1257     return $n;
1261 //////////////////////////////////////////////////////////////////////////////////////
1262 function workshop_file_area($workshop, $submission) {
1263     return make_upload_directory( workshop_file_area_name($workshop, $submission) );
1267 //////////////////////////////////////////////////////////////////////////////////////
1268 function workshop_file_area_name($workshop, $submission) {
1269 //  Creates a directory file name, suitable for make_upload_directory()
1270     global $CFG;
1272     return "$workshop->course/$CFG->moddata/workshop/$submission->id";
1276 ///////////////////////////////////////////////////////////////////////////////////////////////
1277 function workshop_get_agree_logs($course, $timestart) {
1278     // get the "agree" entries for this user (the assessment owner) and add the first and last names 
1279     // the last two probably wont be used...
1280     global $CFG, $USER;
1281     if (empty($USER->id)) {
1282         return false;
1283     }
1284     
1285     $timethen = time() - $CFG->maxeditingtime;
1286     return get_records_sql("SELECT l.time, l.url, u.firstname, u.lastname, a.workshopid, a.userid, e.name
1287                              FROM {$CFG->prefix}log l,
1288                                 {$CFG->prefix}workshop e, 
1289                                 {$CFG->prefix}workshop_submissions s, 
1290                                 {$CFG->prefix}workshop_assessments a, 
1291                                 {$CFG->prefix}user u
1292                             WHERE l.time > $timestart AND l.time < $timethen 
1293                                 AND l.course = $course->id AND l.module = 'workshop' AND l.action = 'agree'
1294                                 AND a.id = l.info AND s.id = a.submissionid AND a.userid = $USER->id
1295                                 AND u.id = s.userid AND e.id = a.workshopid");
1299 ///////////////////////////////////////////////////////////////////////////////////////////////
1300 function workshop_get_assess_logs($course, $timestart) {
1301     // get the "assess" entries for this user and add the first and last names...
1302     global $CFG, $USER;
1303     if (empty($USER->id)) {
1304         return false;
1305     }
1306     
1307     $timethen = time() - $CFG->maxeditingtime;
1308     return get_records_sql("SELECT l.time, l.url, u.firstname, u.lastname, a.workshopid, a.userid, e.name
1309                              FROM {$CFG->prefix}log l,
1310                                 {$CFG->prefix}workshop e, 
1311                                 {$CFG->prefix}workshop_submissions s, 
1312                                 {$CFG->prefix}workshop_assessments a, 
1313                                 {$CFG->prefix}user u
1314                             WHERE l.time > $timestart AND l.time < $timethen 
1315                                 AND l.course = $course->id AND l.module = 'workshop' AND l.action = 'assess'
1316                                 AND a.id = l.info AND s.id = a.submissionid AND s.userid = $USER->id
1317                                 AND u.id = a.userid AND e.id = a.workshopid");
1321 //////////////////////////////////////////////////////////////////////////////////////
1322 function workshop_get_assessments($submission, $all = '', $order = '') {
1323     // Return assessments for this submission ordered oldest first, newest last
1324     // new assessments made within the editing time are NOT returned unless they
1325     // belong to the user or the second argument is set to ALL
1326     global $CFG, $USER;
1328     $timenow = time();
1329     if (!$order) {
1330         $order = "timecreated DESC";
1331     }
1332     if ($all != 'ALL') {
1333         return get_records_select("workshop_assessments", "(submissionid = $submission->id) AND 
1334             ((timecreated < $timenow - $CFG->maxeditingtime) or 
1335                 ((timecreated < $timenow) AND (userid = $USER->id)))", $order);
1336     } else {
1337         return get_records_select("workshop_assessments", "submissionid = $submission->id AND 
1338             (timecreated < $timenow)", $order);
1339     }
1343 ///////////////////////////////////////////////////////////////////////////////////////////////
1344 function workshop_get_comment_logs($course, $timestart) {
1345     // get the "comment" entries for this user and add the first and last names (which may not be used)...
1346     global $CFG, $USER;
1347     if (empty($USER->id)) {
1348         return false;
1349     }
1350     
1351     $timethen = time() - $CFG->maxeditingtime;
1352     return get_records_sql("SELECT l.time, l.url, u.firstname, u.lastname, a.workshopid, e.name
1353                              FROM {$CFG->prefix}log l,
1354                                 {$CFG->prefix}workshop e, 
1355                                 {$CFG->prefix}workshop_submissions s, 
1356                                 {$CFG->prefix}workshop_assessments a, 
1357                                 {$CFG->prefix}workshop_comments c, 
1358                                 {$CFG->prefix}user u
1359                             WHERE l.time > $timestart AND l.time < $timethen 
1360                                 AND l.course = $course->id AND l.module = 'workshop' AND l.action = 'comment'
1361                                 AND c.id = l.info AND c.userid != $USER->id AND a.id = c.assessmentid
1362                                 AND s.id = a.submissionid AND (s.userid = $USER->id OR a.userid = $USER->id)
1363                                 AND u.id = a.userid AND e.id = a.workshopid");
1367 ///////////////////////////////////////////////////////////////////////////////////////////////
1368 function workshop_get_grade_logs($course, $timestart) {
1369     // get the "grade" entries for this user and add the first and last names (of submission owner, 
1370     // better to get name of teacher...
1371     // ...but not available in assessment record...)
1372     global $CFG, $USER;
1373     if (empty($USER->id)) {
1374         return false;
1375     }
1376     
1377     $timethen = time() - $CFG->maxeditingtime;
1378     return get_records_sql("SELECT l.time, l.url, u.firstname, u.lastname, a.workshopid, e.name
1379                              FROM {$CFG->prefix}log l,
1380                                 {$CFG->prefix}workshop e, 
1381                                 {$CFG->prefix}workshop_submissions s, 
1382                                 {$CFG->prefix}workshop_assessments a, 
1383                                 {$CFG->prefix}user u
1384                             WHERE l.time > $timestart AND l.time < $timethen 
1385                                 AND l.course = $course->id AND l.module = 'workshop'    AND l.action = 'grade'
1386                                 AND a.id = l.info AND s.id = a.submissionid AND a.userid = $USER->id
1387                                 AND u.id = s.userid AND e.id = a.workshopid");
1391 //////////////////////////////////////////////////////////////////////////////////////
1392 function workshop_get_student_submission($workshop, $user) {
1393 // Return a submission for a particular user
1394     global $CFG;
1396     $submission = get_record("workshop_submissions", "workshopid", $workshop->id, "userid", $user->id);
1397     if (!empty($submission->timecreated)) {
1398         return $submission;
1399     }
1400     return NULL;
1404 //////////////////////////////////////////////////////////////////////////////////////
1405 function workshop_get_student_submissions($workshop, $order = "title") {
1406 // Return all  ENROLLED student submissions
1407     global $CFG;
1408     
1409     if ($order == "title") {
1410         $order = "s.title";
1411         }
1412     if ($order == "name") {
1413         $order = "a.lastname, a.firstname";
1414         }
1415     if ($order == "time") {
1416         $order = "s.timecreated ASC";
1417     }
1418     // make sure it works on the site course
1419     $select = "u.course = '$workshop->course' AND";
1420     $site = get_site();
1421     if ($workshop->course == $site->id) {
1422         $select = '';
1423     }
1425     return get_records_sql("SELECT s.* FROM {$CFG->prefix}workshop_submissions s, 
1426                             {$CFG->prefix}user_students u, {$CFG->prefix}user a 
1427                             WHERE $select s.userid = u.userid
1428                               AND a.id = u.userid
1429                               AND s.workshopid = $workshop->id
1430                               AND s.timecreated > 0
1431                               ORDER BY $order");
1435 ///////////////////////////////////////////////////////////////////////////////////////////////
1436 function workshop_get_submit_logs($course, $timestart) {
1437     // get the "submit" entries and add the first and last names...
1438     global $CFG, $USER;
1439     
1440     $timethen = time() - $CFG->maxeditingtime;
1441     return get_records_sql("SELECT l.time, l.url, u.firstname, u.lastname, l.info as workshopid, e.name
1442                              FROM {$CFG->prefix}log l,
1443                                 {$CFG->prefix}workshop e, 
1444                                 {$CFG->prefix}user u
1445                             WHERE l.time > $timestart AND l.time < $timethen 
1446                                 AND l.course = $course->id AND l.module = 'workshop'
1447                                 AND l.action = 'submit'
1448                                 AND e.id = l.info 
1449                                 AND u.id = l.userid");
1453 //////////////////////////////////////////////////////////////////////////////////////
1454 function workshop_get_unmailed_assessments($cutofftime) {
1455     /// Return list of assessments that have not been mailed out
1456     global $CFG;
1457     return get_records_sql("SELECT a.*, g.course, g.name
1458                               FROM {$CFG->prefix}workshop_assessments a, {$CFG->prefix}workshop g
1459                              WHERE a.mailed = 0 
1460                                AND a.timecreated < $cutofftime 
1461                                AND g.id = a.workshopid
1462                                AND g.releasegrades < $cutofftime");
1466 //////////////////////////////////////////////////////////////////////////////////////
1467 function workshop_get_unmailed_comments($cutofftime) {
1468     /// Return list of comments that have not been mailed out
1469     global $CFG;
1470     return get_records_sql("SELECT c.*, g.course, g.name
1471                               FROM {$CFG->prefix}workshop_comments c, {$CFG->prefix}workshop g
1472                              WHERE c.mailed = 0 
1473                                AND c.timecreated < $cutofftime 
1474                                AND g.id = c.workshopid");
1478 //////////////////////////////////////////////////////////////////////////////////////
1479 function workshop_get_unmailed_graded_assessments($cutofftime) {
1480     /// Return list of graded assessments that have not been mailed out
1481     global $CFG;
1482     return get_records_sql("SELECT a.*, g.course, g.name
1483                               FROM {$CFG->prefix}workshop_assessments a, {$CFG->prefix}workshop g
1484                              WHERE a.mailed = 0 
1485                                AND a.timegraded < $cutofftime 
1486                                AND a.timegraded > 0
1487                                AND g.id = a.workshopid");
1491 //////////////////////////////////////////////////////////////////////////////////////
1492 function workshop_get_unmailed_resubmissions($cutofftime) {
1493     /// Return list of assessments of resubmissions that have not been mailed out
1494     global $CFG;
1495     return get_records_sql("SELECT a.*, w.course, w.name
1496                               FROM {$CFG->prefix}workshop_assessments a, {$CFG->prefix}workshop w
1497                              WHERE a.mailed = 0 
1498                                AND a.resubmission = 1
1499                                AND w.id = a.workshopid");
1503 //////////////////////////////////////////////////////////////////////////////////////
1504 function workshop_get_user_assessments($workshop, $user) {
1505 // Return all the  user's assessments, newest first, oldest last (hot, warm and cold ones)
1506     return get_records_select("workshop_assessments", "workshopid = $workshop->id AND userid = $user->id", 
1507                 "timecreated DESC");
1511 //////////////////////////////////////////////////////////////////////////////////////
1512 function workshop_get_user_submissions($workshop, $user) {
1513     // return real submissions of user newest first, oldest last. Ignores the dummy submissions
1514     // which get created to hold the final grades for users that make no submissions
1515     return get_records_select("workshop_submissions", "workshopid = $workshop->id AND 
1516         userid = $user->id AND timecreated > 0", "timecreated DESC" );
1520 //////////////////////////////////////////////////////////////////////////////////////
1521 function workshop_grade_assessments($workshop, $verbose=false) {
1522     global $WORKSHOP_EWEIGHTS;
1523     
1524     // timeout after 10 minutes
1525     @set_time_limit(600);
1527     $timenow = time();
1528     
1529     // set minumim value for the variance (of the elements)
1530     $minvar = 0.05;
1532     // check when the standard deviations were calculated
1533     $oldtotalassessments = get_field("workshop_elements", "totalassessments", "workshopid", $workshop->id, 
1534                 "elementno", 0);
1535     $totalassessments = count_records("workshop_assessments", "workshopid", $workshop->id);
1536     // calculate the std. devs every 10 assessments for low numbers of assessments, thereafter every 100 new assessments
1537     if ((($totalassessments < 100) and (($totalassessments - $oldtotalassessments) > 10)) or 
1538             (($totalassessments - $oldtotalassessments) > 100)) {
1539         // calculate the means for each submission using just the "good" assessments 
1540         if ($submissions = get_records("workshop_submissions", "workshopid", $workshop->id)) {
1541             foreach ($submissions as $submission) {
1542                 $nassessments[$submission->id] = 0;
1543                 if ($assessments = workshop_get_assessments($submission)) {
1544                     foreach ($assessments as $assessment) {
1545                         // test if assessment is "good", a teacher assessment always "good", but may be weighted out 
1546                         if (isteacher($workshop->course, $assessment->userid)) {
1547                             if (!$workshop->teacherweight) {
1548                                 // drop teacher's assessment as weight is zero
1549                                 continue;
1550                             }
1551                         } elseif ((!$assessment->gradinggrade and $assessment->timegraded) or 
1552                                 ($workshop->agreeassessments and !$assessment->timeagreed)) {
1553                             // it's a duff assessment, or it's not been agreed
1554                             continue;
1555                         }
1556                         if (isset($num[$submission->id])) {
1557                             if (isteacher($workshop->course, $assessment->userid)) {
1558                                 $num[$submission->id] += $workshop->teacherweight; // weight teacher's assessment
1559                             } else {
1560                                 $num[$submission->id]++; // number of assessments
1561                             }
1562                             $nassessments[$submission->id]++;
1563                         } else {
1564                             if (isteacher($workshop->course, $assessment->userid)) {
1565                                 $num[$submission->id] = $workshop->teacherweight;
1566                             } else {
1567                                 $num[$submission->id] = 1;
1568                             }
1569                             $nassessments[$submission->id] = 1;
1570                         }
1571                         for ($i = 0; $i < $workshop->nelements; $i++) {
1572                             $grade =  get_field("workshop_grades", "grade",
1573                                     "assessmentid", $assessment->id, "elementno", $i);
1574                             if (isset($sum[$submission->id][$i])) {
1575                                 if (isteacher($workshop->course, $assessment->userid)) {
1576                                     $sum[$submission->id][$i] += $workshop->teacherweight * $grade; // teacher's grade
1577                                 } else {
1578                                     $sum[$submission->id][$i] += $grade; // student's grade
1579                                 }
1580                             } else { 
1581                                 if (isteacher($workshop->course, $assessment->userid)) {
1582                                     $sum[$submission->id][$i] = $workshop->teacherweight * $grade; // teacher's grade
1583                                 } else {
1584                                     $sum[$submission->id][$i] = $grade; // students's grade
1585                                 }
1586                             }
1587                         }
1588                     }
1589                 }
1590             }
1592             if (!isset($num)) { 
1593                 // no assessments yet
1594                 return;
1595             }
1596             reset($num);
1597             // calculate the means for each submission
1598             $total = 0;
1599             foreach ($num as $submissionid => $n) {
1600                 if ($n) { // stop division by zero
1601                     for ($i = 0; $i < $workshop->nelements; $i++) {
1602                         $mean[$submissionid][$i] = $sum[$submissionid][$i] / $n;
1603                         // echo "Submission: $submissionid; Element: $i; Mean: {$mean[$submissionid][$i]}<br />\n";
1604                     }
1605                     $total += $n; // weighted total
1606                 }
1607             }
1608             if ($verbose) {
1609                 echo "<p align=\"center\">".get_string("numberofsubmissions", "workshop", count($num))."<br />\n";
1610                 echo get_string("numberofassessmentsweighted", "workshop", $total)."</p>\n";
1611             }
1613             // now get an estimate of the standard deviation of each element in the assessment
1614             // this is just a rough measure, all assessments are included and teacher's assesments are not weighted
1615             $n = 0;
1616             for ($i = 0; $i < $workshop->nelements; $i++) {
1617                 $var[$i] = 0;
1618             }
1619             foreach ($submissions as $submission) {
1620                 if ($assessments = workshop_get_assessments($submission)) {
1621                     foreach ($assessments as $assessment) {
1622                         $n++;
1623                         for ($i = 0; $i < $workshop->nelements; $i++) {
1624                             $grade =  get_field("workshop_grades", "grade",
1625                                     "assessmentid", $assessment->id, "elementno", $i);
1626                             $temp = $mean[$submission->id][$i] - $grade;
1627                             $var[$i] += $temp * $temp;
1628                         }
1629                     }
1630                 }
1631             }
1632             for ($i = 0; $i < $workshop->nelements; $i++) {
1633                 if ($n > 1) {
1634                     $sd[$i] = sqrt($var[$i] / ($n - 1));
1635                 } else {
1636                     $sd[$i] = 0;
1637                 }
1638                 set_field("workshop_elements", "stddev", $sd[$i], "workshopid", $workshop->id, "elementno", $i);
1639                 set_field("workshop_elements", "totalassessments", $totalassessments, "workshopid", $workshop->id,
1640                         "elementno", $i);
1641                 if ($verbose) {
1642                     echo get_string("standarddeviationofelement", "workshop", $i+1)." $sd[$i]<br />";
1643                     if ($sd[$i] <= $minvar) {
1644                         print_string("standarddeviationnote", "workshop")."<br />\n";
1645                     }
1646                 }
1647             }
1648         } 
1649     }
1651     // this section looks at each submission if the number of assessments made has increased it recalculates the
1652     // grading grades for those assessments
1653     // first get the assignment elements for the weights and the stddevs...
1654     $elementsraw = get_records("workshop_elements", "workshopid", $workshop->id, "elementno ASC");
1655     foreach ($elementsraw as $element) {
1656         $weight[] = $element->weight;   // to renumber index 0,1,2...
1657         $sd[] = $element->stddev;   // to renumber index 0,1,2...
1658     }
1660     unset($num); // may have been used in calculating stddevs
1661     unset($sum); // ditto
1662     if ($submissions = get_records("workshop_submissions", "workshopid", $workshop->id)) {
1663         foreach ($submissions as $submission) {
1664             // see if the number of assessments has changed
1665             $nassessments = workshop_count_assessments($submission);
1666             if ($submission->nassessments <> $nassessments) {
1667                 // ...if there are three or more assessments calculate the variance of each assessment.
1668                 // Use the variance to find the "best" assessment. (When there is only one or two assessments they 
1669                 // are not altered by this routine.)
1670                 if ($verbose) echo "Processing submission $submission->id ($nassessments asessments)...\n"; 
1671                 if ($nassessments > 2) {
1672                     $num = 0; // weighted number of assessments
1673                     for ($i = 0; $i < $workshop->nelements; $i++) {
1674                         $sum[$i] = 0; // weighted sum of grades
1675                     }
1676                     if ($assessments = workshop_get_assessments($submission)) {
1677                         // first calculate the mean grades for each element
1678                         foreach ($assessments as $assessment) {
1679                             // test if assessment is "good", a teacher assessment always "good", but may be weighted out 
1680                             if (isteacher($workshop->course, $assessment->userid)) {
1681                                 if (!$workshop->teacherweight) {
1682                                     // drop teacher's assessment as weight is zero
1683                                     continue;
1684                                 }
1685                             } elseif ((!$assessment->gradinggrade and $assessment->timegraded) or 
1686                                     ($workshop->agreeassessments and !$assessment->timeagreed)) {
1687                                 // it's a duff assessment, or it's not been agreed
1688                                 continue;
1689                             }
1690                             if (isteacher($workshop->course, $assessment->userid)) {
1691                                 $num += $workshop->teacherweight; // weight teacher's assessment
1692                             } else {
1693                                 $num++; // student assessment just add one
1694                             }
1695                             for ($i = 0; $i < $workshop->nelements; $i++) {
1696                                 $grade =  get_field("workshop_grades", "grade",
1697                                         "assessmentid", $assessment->id, "elementno", $i);
1698                                 if (isteacher($workshop->course, $assessment->userid)) {
1699                                     $sum[$i] += $workshop->teacherweight * $grade; // teacher's grade
1700                                 } else {
1701                                     $sum[$i] += $grade; // student's grade
1702                                 }
1703                             }
1704                         }
1705                         if ($num) { // could all the assessments be duff? 
1706                             for ($i = 0; $i < $workshop->nelements; $i++) {
1707                                 $mean[$i] = $sum[$i] / $num;
1708                                 if ($verbose) echo "Submission: $submission->id; Element: $i; Mean: {$mean[$i]}\n";
1709                             }
1710                         } else {
1711                             continue; // move to the next submission
1712                         }
1713                         // run through the assessments again to see which is the "best" one (the one
1714                         // closest to the mean)
1715                         $lowest = 10e9;
1716                         foreach ($assessments as $assessment) {
1717                             if ($workshop->agreeassessments and !$assessment->timeagreed) {
1718                                 // ignore assessments that have not been agreed
1719                                 continue;
1720                             }
1721                             $var = 0;
1722                             for ($i = 0; $i < $workshop->nelements; $i++) {
1723                                 $grade =  get_field("workshop_grades", "grade",
1724                                         "assessmentid", $assessment->id, "elementno", $i);
1725                                 if ($sd[$i] > $minvar) {
1726                                     $temp = ($mean[$i] - $grade) * 
1727                                         $WORKSHOP_EWEIGHTS[$weight[$i]] / $sd[$i];
1728                                 } else {
1729                                     $temp = 0;
1730                                 }
1731                                 $var += $temp * $temp;
1732                             }
1733                             // find the "best" assessment of this submission
1734                             if ($lowest > $var) {
1735                                 $lowest = $var;
1736                                 $bestassessmentid = $assessment->id;
1737                             }
1738                         }
1740                         if (!$best = get_record("workshop_assessments", "id", $bestassessmentid)) {
1741                             error("Workshop grade assessments: cannot find best assessment");
1742                         }
1743                         if ($verbose) echo "Best assessment is $bestassessmentid;\n";
1744                         foreach ($assessments as $assessment) {
1745                             // don't overwrite teacher's grade
1746                             if ($assessment->teachergraded) {
1747                                 continue;
1748                             }
1749                             if ($assessment->id == $bestassessmentid) { 
1750                                 // it's the best one, set the grading grade to the maximum 
1751                                 set_field("workshop_assessments", "gradinggrade", 100, "id", $assessment->id);
1752                                 set_field("workshop_assessments", "timegraded", $timenow, "id", $assessment->id);
1753                             } else {
1754                                 // it's one of the pack, compare with the best...
1755                                 $gradinggrade = workshop_compare_assessments($workshop, $best, $assessment);
1756                                 // ...and save the grade for the assessment 
1757                                 set_field("workshop_assessments", "gradinggrade", $gradinggrade, "id", $assessment->id);
1758                                 set_field("workshop_assessments", "timegraded", $timenow, "id", $assessment->id);
1759                             }
1760                         }
1761                     }
1762                 } else {
1763                     // there are less than 3 assessments for this submission
1764                     if ($assessments = workshop_get_assessments($submission)) {
1765                         foreach ($assessments as $assessment) {
1766                             if (!$assessment->timegraded and !$assessment->teachergraded) {
1767                                 // set the grading grade to the maximum and say it's been graded 
1768                                 set_field("workshop_assessments", "gradinggrade", 100, "id", $assessment->id);
1769                                 set_field("workshop_assessments", "timegraded", $timenow, "id", $assessment->id);
1770                             }
1771                         }
1772                     }
1773                 }       
1774                 // set the number of assessments for this submission
1775                 set_field("workshop_submissions", "nassessments", $nassessments, "id", $submission->id);    
1776             }
1777         }
1778     }
1779     return;
1783 //////////////////////////////////////////////////////////////////////////////////////
1784 function workshop_gradinggrade($workshop, $student) {
1785     // returns the current (external) grading grade of the based on their (cold) assessments
1786     // (needed as it's called by grade)
1787     
1788     $gradinggrade = 0;
1789     if ($assessments = workshop_get_user_assessments($workshop, $student)) {
1790         $n = 0;
1791         foreach ($assessments as $assessment) {
1792             $gradinggrade += $assessment->gradinggrade;
1793             $n++;
1794         }
1795         if ($n < ($workshop->ntassessments + $workshop->nsassessments)) { // the minimum students should do
1796             $n = $workshop->ntassessments + $workshop->nsassessments;
1797         }
1798         $gradinggrade = $gradinggrade / $n;
1799     }
1800     return number_format($gradinggrade * $workshop->gradinggrade / 100, 1);
1804 //////////////////////////////////////////////////////////////////////////////////////
1805 function workshop_submission_grade($workshop, $submission) {
1806     // returns the current (external) grade of the submission based on the "good" (cold) assessments
1807     // (needed as it's called by grade)
1808     
1809     $grade = 0;
1810     if ($assessments = workshop_get_assessments($submission)) {
1811         $n = 0;
1812         foreach ($assessments as $assessment) {
1813             if ($workshop->agreeassessments and !$assessment->timeagreed) {
1814                 // ignore assessments which have not been agreed
1815                 continue;
1816             }
1817             if ($assessment->gradinggrade or !$assessment->timegraded) { 
1818                 // a good assessment (or one that has not been graded yet)
1819                 if (isteacher($workshop->course, $assessment->userid)) {
1820                     $timenow = time();
1821                     if ($timenow > $workshop->releasegrades) {
1822                         // teacher's grade is available
1823                         $grade += $workshop->teacherweight * $assessment->grade;
1824                         $n += $workshop->teacherweight;
1825                     }
1826                 } else {
1827                     $grade += $assessment->grade;
1828                     $n++;
1829                 }
1830             }
1831         }
1832         if ($n) { // stop division by zero
1833             $grade = $grade / $n;
1834         }
1835     }
1836     return number_format($grade * $workshop->grade / 100, 1);
1840 /////////////////////////////////////////////////////////////////////////////
1841 function workshop_fullname($userid, $courseid) {
1842     global $CFG;
1843     if (!$user = get_record('user', 'id', $userid)) {
1844         return '';
1845     }
1846     return '<a href="'.$CFG->wwwroot.'/user/view.php?id='.$user->id.'&amp;course='.$courseid.'">'.
1847         fullname($user).'</a>';
1850 ?>