Automatic installer.php lang files by installer_builder (20070726)
[moodle-linuxchix.git] / mod / workshop / lib.php
blob69d42f4be7d175bb6f88b3cbad199d7e3677786a
1 <?php // $Id$
3 // workshop constants and standard Moodle functions plus the workshop functions
4 // called by the standard functions
6 // see also locallib.php for other non-standard workshop functions
8 require_once($CFG->libdir.'/filelib.php');
10 /*** Constants **********************************/
13 $WORKSHOP_EWEIGHTS = array( 0 => -4.0, 1 => -2.0, 2 => -1.5, 3 => -1.0, 4 => -0.75, 5 => -0.5, 6 => -0.25,
14 7 => 0.0, 8 => 0.25, 9 => 0.5, 10 => 0.75, 11=> 1.0, 12 => 1.5, 13=> 2.0,
15 14 => 4.0);
17 $WORKSHOP_FWEIGHTS = array( 0 => 0, 1 => 0.1, 2 => 0.25, 3 => 0.5, 4 => 0.75, 5 => 1.0, 6 => 1.5,
18 7 => 2.0, 8 => 3.0, 9 => 5.0, 10 => 7.5, 11=> 10.0, 12=>50.0);
21 $WORKSHOP_ASSESSMENT_COMPS = array (
22 0 => array('name' => get_string('verylax', 'workshop'), 'value' => 1),
23 1 => array('name' => get_string('lax', 'workshop'), 'value' => 0.6),
24 2 => array('name' => get_string('fair', 'workshop'), 'value' => 0.4),
25 3 => array('name' => get_string('strict', 'workshop'), 'value' => 0.33),
26 4 => array('name' => get_string('verystrict', 'workshop'), 'value' => 0.2) );
29 /*** Moodle 1.7 compatibility functions *****
31 ********************************************/
32 function workshop_context($workshop) {
33 //TODO: add some $cm caching if needed
34 if (is_object($workshop)) {
35 $workshop = $workshop->id;
37 if (! $cm = get_coursemodule_from_instance('workshop', $workshop)) {
38 error('Course Module ID was incorrect');
41 return get_context_instance(CONTEXT_MODULE, $cm->id);
44 function workshop_is_teacher($workshop, $userid=NULL) {
45 return has_capability('mod/workshop:manage', workshop_context($workshop), $userid);
48 function workshop_is_teacheredit($workshop, $userid=NULL) {
49 return has_capability('mod/workshop:manage', workshop_context($workshop), $userid)
50 and has_capability('moodle/site:accessallgroups', workshop_context($workshop), $userid);
53 function workshop_is_student($workshop, $userid=NULL) {
54 return has_capability('mod/workshop:participate', workshop_context($workshop), $userid);
57 function workshop_get_students($workshop, $sort='u.lastaccess', $fields='u.*') {
58 return $users = get_users_by_capability(workshop_context($workshop), 'mod/workshop:participate', $fields, $sort);
61 function workshop_get_teachers($workshop, $sort='u.lastaccess', $fields='u.*') {
62 return $users = get_users_by_capability(workshop_context($workshop), 'mod/workshop:manage', $fields, $sort);
66 /*** Standard Moodle functions ******************
67 workshop_add_instance($workshop)
68 workshop_check_dates($workshop)
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);
108 if (!workshop_check_dates($workshop)) {
109 return get_string('invaliddates', 'workshop');
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);
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;
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);
173 $timenow = time();
175 $CFG->enablerecordcache = true; // We want all the caching we can get
177 // Find all workshop notifications that have yet to be mailed out, and mails them
178 $cutofftime = $timenow - $CFG->maxeditingtime;
180 // look for new assessments
181 if ($assessments = workshop_get_unmailed_assessments($cutofftime)) {
182 foreach ($assessments as $assessment) {
184 echo "Processing workshop assessment $assessment->id\n";
186 // only process the entry once
187 if (! set_field("workshop_assessments", "mailed", "1", "id", "$assessment->id")) {
188 echo "Could not update the mailed field for id $assessment->id\n";
191 if (! $submission = get_record("workshop_submissions", "id", "$assessment->submissionid")) {
192 echo "Could not find submission $assessment->submissionid\n";
193 continue;
195 if (! $workshop = get_record("workshop", "id", $submission->workshopid)) {
196 echo "Could not find workshop id $submission->workshopid\n";
197 continue;
199 if (! $course = get_record("course", "id", $workshop->course)) {
200 error("Could not find course id $workshop->course");
201 continue;
203 if (! $cm = get_coursemodule_from_instance("workshop", $workshop->id, $course->id)) {
204 error("Course Module ID was incorrect");
205 continue;
207 if (! $submissionowner = get_record("user", "id", "$submission->userid")) {
208 echo "Could not find user $submission->userid\n";
209 continue;
211 if (! $assessmentowner = get_record("user", "id", "$assessment->userid")) {
212 echo "Could not find user $assessment->userid\n";
213 continue;
215 if (! workshop_is_student($workshop, $submissionowner->id) and !workshop_is_teacher($workshop,
216 $submissionowner->id)) {
217 continue; // Not an active participant
219 if (! workshop_is_student($workshop, $assessmentowner->id) and !workshop_is_teacher($workshop,
220 $assessmentowner->id)) {
221 continue; // Not an active participant
223 // don't sent self assessment
224 if ($submissionowner->id == $assessmentowner->id) {
225 continue;
227 $strworkshops = get_string("modulenameplural", "workshop");
228 $strworkshop = get_string("modulename", "workshop");
230 // it's an assessment, tell the submission owner
231 $USER->lang = $submissionowner->lang;
232 $sendto = $submissionowner;
233 // "Your assignment \"$submission->title\" has been assessed by"
234 if (workshop_is_student($workshop, $assessmentowner->id)) {
235 $msg = get_string("mail1", "workshop", $submission->title)." a $course->student.\n";
237 else {
238 $msg = get_string("mail1", "workshop", $submission->title).
239 " ".fullname($assessmentowner)."\n";
241 // "The comments and grade can be seen in the workshop assignment '$workshop->name'
242 // I have taken the following line out because the info is repeated below.
243 // $msg .= get_string("mail2", "workshop", $workshop->name)."\n\n";
245 $postsubject = "$course->shortname: $strworkshops: ".format_string($workshop->name,true);
246 $posttext = "$course->shortname -> $strworkshops -> ".format_string($workshop->name,true)."\n";
247 $posttext .= "---------------------------------------------------------------------\n";
248 $posttext .= $msg;
249 // "The comments and grade can be seen in ..."
250 $posttext .= get_string("mail2", "workshop",
251 format_string($workshop->name,true).", $CFG->wwwroot/mod/workshop/view.php?id=$cm->id")."\n";
252 $posttext .= "---------------------------------------------------------------------\n";
253 if ($sendto->mailformat == 1) { // HTML
254 $posthtml = "<p><font face=\"sans-serif\">".
255 "<a href=\"$CFG->wwwroot/course/view.php?id=$course->id\">$course->shortname</a> ->".
256 "<a href=\"$CFG->wwwroot/mod/workshop/index.php?id=$course->id\">$strworkshops</a> ->".
257 "<a href=\"$CFG->wwwroot/mod/workshop/view.php?id=$cm->id\">".format_string($workshop->name,true)."</a></font></p>";
258 $posthtml .= "<hr><font face=\"sans-serif\">";
259 $posthtml .= "<p>$msg</p>";
260 $posthtml .= "<p>".get_string("mail2", "workshop",
261 " <a href=\"$CFG->wwwroot/mod/workshop/view.php?id=$cm->id\">".format_string($workshop->name,true)."</a>")."</p></font><hr>";
262 } else {
263 $posthtml = "";
266 if (!$teacher = get_teacher($course->id)) {
267 echo "Error: can not find teacher for course $course->id!\n";
270 if (! email_to_user($sendto, $teacher, $postsubject, $posttext, $posthtml)) {
271 echo "Error: workshop cron: Could not send out mail for id $submission->id to
272 user $sendto->id ($sendto->email)\n";
277 // look for new assessments of resubmissions
278 if ($assessments = workshop_get_unmailed_resubmissions($cutofftime)) {
279 $timenow = time();
281 foreach ($assessments as $assessment) {
283 echo "Processing workshop assessment $assessment->id\n";
285 // only process the entry once
286 if (! set_field("workshop_assessments", "mailed", "1", "id", "$assessment->id")) {
287 echo "Could not update the mailed field for id $assessment->id\n";
290 if (! $submission = get_record("workshop_submissions", "id", "$assessment->submissionid")) {
291 echo "Could not find submission $assessment->submissionid\n";
292 continue;
294 if (! $workshop = get_record("workshop", "id", $submission->workshopid)) {
295 echo "Could not find workshop id $submission->workshopid\n";
296 continue;
298 if (! $course = get_record("course", "id", $workshop->course)) {
299 error("Could not find course id $workshop->course");
300 continue;
302 if (! $cm = get_coursemodule_from_instance("workshop", $workshop->id, $course->id)) {
303 error("Course Module ID was incorrect");
304 continue;
306 if (! $submissionowner = get_record("user", "id", "$submission->userid")) {
307 echo "Could not find user $submission->userid\n";
308 continue;
310 if (! $assessmentowner = get_record("user", "id", "$assessment->userid")) {
311 echo "Could not find user $assessment->userid\n";
312 continue;
314 if (! workshop_is_student($workshop, $submissionowner->id) and !workshop_is_teacher($workshop,
315 $submissionowner->id)) {
316 continue; // Not an active participant
318 if (! workshop_is_student($workshop, $assessmentowner->id) and !workshop_is_teacher($workshop,
319 $assessmentowner->id)) {
320 continue; // Not an active participant
323 $strworkshops = get_string("modulenameplural", "workshop");
324 $strworkshop = get_string("modulename", "workshop");
326 // it's a resubission assessment, tell the assessment owner to (re)assess
327 $USER->lang = $assessmentowner->lang;
328 $sendto = $assessmentowner;
329 // "The assignment \"$submission->title\" is a revised piece of work. "
330 $msg = get_string("mail8", "workshop", $submission->title)."\n";
331 // "Please assess it in the workshop assignment '$workshop->name'
332 // $msg .= get_string("mail9", "workshop", $workshop->name)."\n\n";
334 $postsubject = "$course->shortname: $strworkshops: ".format_string($workshop->name,true);
335 $posttext = "$course->shortname -> $strworkshops -> ".format_string($workshop->name,true)."\n";
336 $posttext .= "---------------------------------------------------------------------\n";
337 $posttext .= $msg;
338 // "Please assess it in ..."
339 $posttext .= get_string("mail9", "workshop",
340 format_string($workshop->name,true).", $CFG->wwwroot/mod/workshop/view.php?id=$cm->id")."\n";
341 $posttext .= "---------------------------------------------------------------------\n";
342 if ($sendto->mailformat == 1) { // HTML
343 $posthtml = "<p><font face=\"sans-serif\">".
344 "<a href=\"$CFG->wwwroot/course/view.php?id=$course->id\">$course->shortname</a> ->".
345 "<a href=\"$CFG->wwwroot/mod/workshop/index.php?id=$course->id\">$strworkshops</a> ->".
346 "<a href=\"$CFG->wwwroot/mod/workshop/view.php?id=$cm->id\">".format_string($workshop->name,true)."</a></font></p>";
347 $posthtml .= "<hr><font face=\"sans-serif\">";
348 $posthtml .= "<p>$msg</p>";
349 $posthtml .= "<p>".get_string("mail9", "workshop",
350 " <a href=\"$CFG->wwwroot/mod/workshop/view.php?id=$cm->id\">".format_string($workshop->name,true)."</a>").'</p></font><hr>';
352 else {
353 $posthtml = "";
356 if (!$teacher = get_teacher($course->id)) {
357 echo "Error: can not find teacher for course $course->id!\n";
360 if (! email_to_user($sendto, $teacher, $postsubject, $posttext, $posthtml)) {
361 echo "Error: workshop cron: Could not send out mail for id $submission->id to
362 user $sendto->id ($sendto->email)\n";
367 // look for new comments
368 if ($comments = workshop_get_unmailed_comments($cutofftime)) {
369 $timenow = time();
371 foreach ($comments as $comment) {
373 echo "Processing workshop comment $comment->id\n";
375 // only process the entry once
376 if (! set_field("workshop_comments", "mailed", "1", "id", "$comment->id")) {
377 echo "Could not update the mailed field for comment id $comment->id\n";
380 if (! $assessment = get_record("workshop_assessments", "id", "$comment->assessmentid")) {
381 echo "Could not find assessment $comment->assessmentid\n";
382 continue;
384 if (! $submission = get_record("workshop_submissions", "id", "$assessment->submissionid")) {
385 echo "Could not find submission $assessment->submissionid\n";
386 continue;
388 if (! $workshop = get_record("workshop", "id", $submission->workshopid)) {
389 echo "Could not find workshop id $submission->workshopid\n";
390 continue;
392 if (! $course = get_record("course", "id", $workshop->course)) {
393 error("Could not find course id $workshop->course");
394 continue;
396 if (! $cm = get_coursemodule_from_instance("workshop", $workshop->id, $course->id)) {
397 error("Course Module ID was incorrect");
398 continue;
400 if (! $submissionowner = get_record("user", "id", "$submission->userid")) {
401 echo "Could not find user $submission->userid\n";
402 continue;
404 if (! $assessmentowner = get_record("user", "id", "$assessment->userid")) {
405 echo "Could not find user $assessment->userid\n";
406 continue;
408 if (! workshop_is_student($workshop, $submissionowner->id) and !workshop_is_teacher($workshop,
409 $submissionowner->id)) {
410 continue; // Not an active participant
412 if (! workshop_is_student($workshop, $assessmentowner->id) and !workshop_is_teacher($workshop,
413 $assessmentowner->id)) {
414 continue; // Not an active participant
417 $strworkshops = get_string("modulenameplural", "workshop");
418 $strworkshop = get_string("modulename", "workshop");
420 // see if the submission owner needs to be told
421 if ($comment->userid != $submission->userid) {
422 $USER->lang = $submissionowner->lang;
423 $sendto = $submissionowner;
424 // "A comment has been added to the assignment \"$submission->title\" by
425 if (workshop_is_student($workshop, $assessmentowner->id)) {
426 $msg = get_string("mail4", "workshop", $submission->title)." a $course->student.\n";
428 else {
429 $msg = get_string("mail4", "workshop", $submission->title)." ".fullname($assessmentowner)."\n";
431 // "The new comment can be seen in the workshop assignment '$workshop->name'
432 // $msg .= get_string("mail5", "workshop", $workshop->name)."\n\n";
434 $postsubject = "$course->shortname: $strworkshops: ".format_string($workshop->name,true);
435 $posttext = "$course->shortname -> $strworkshops -> ".format_string($workshop->name,true)."\n";
436 $posttext .= "---------------------------------------------------------------------\n";
437 $posttext .= $msg;
438 // "The new comment can be seen in ..."
439 $posttext .= get_string("mail5", "workshop",
440 format_string($workshop->name,true).", $CFG->wwwroot/mod/workshop/view.php?id=$cm->id")."\n";
441 $posttext .= "---------------------------------------------------------------------\n";
442 if ($sendto->mailformat == 1) { // HTML
443 $posthtml = "<p><font face=\"sans-serif\">".
444 "<a href=\"$CFG->wwwroot/course/view.php?id=$course->id\">$course->shortname</a> ->".
445 "<a href=\"$CFG->wwwroot/mod/workshop/index.php?id=$course->id\">$strworkshops</a> ->".
446 "<a href=\"$CFG->wwwroot/mod/workshop/view.php?id=$cm->id\">".format_string($workshop->name,true)."</a></font></p>";
447 $posthtml .= "<hr><font face=\"sans-serif\">";
448 $posthtml .= "<p>$msg</p>";
449 $posthtml .= "<p>".get_string("mail5", "workshop",
450 " <a href=\"$CFG->wwwroot/mod/workshop/view.php?id=$cm->id\">".format_string($workshop->name,true)."</a>")
451 ."</p></font><hr>";
453 else {
454 $posthtml = "";
457 if (!$teacher = get_teacher($course->id)) {
458 echo "Error: can not find teacher for course $course->id!\n";
461 if (! email_to_user($sendto, $teacher, $postsubject, $posttext, $posthtml)) {
462 echo "Error: workshop cron: Could not send out mail for id $submission->id to user
463 $sendto->id ($sendto->email)\n";
466 // see if the assessor needs to to told
467 if ($comment->userid != $assessment->userid) {
468 $USER->lang = $assessmentowner->lang;
469 $sendto = $assessmentowner;
470 // "A comment has been added to the assignment \"$submission->title\" by
471 if (workshop_is_student($workshop, $submissionowner->id)) {
472 $msg = get_string("mail4", "workshop", $submission->title)." a $course->student.\n";
474 else {
475 $msg = get_string("mail4", "workshop", $submission->title).
476 " ".fullname($submissionowner)."\n";
478 // "The new comment can be seen in the workshop assignment '$workshop->name'
479 // $msg .= get_string("mail5", "workshop", $workshop->name)."\n\n";
481 $postsubject = "$course->shortname: $strworkshops: ".format_string($workshop->name,true);
482 $posttext = "$course->shortname -> $strworkshops -> ".format_string($workshop->name,true)."\n";
483 $posttext .= "---------------------------------------------------------------------\n";
484 $posttext .= $msg;
485 // "The new comment can be seen in ..."
486 $posttext .= get_string("mail5", "workshop",
487 format_string($workshop->name,true).", $CFG->wwwroot/mod/workshop/view.php?id=$cm->id")."\n";
488 $posttext .= "---------------------------------------------------------------------\n";
489 if ($sendto->mailformat == 1) { // HTML
490 $posthtml = "<p><font face=\"sans-serif\">".
491 "<a href=\"$CFG->wwwroot/course/view.php?id=$course->id\">$course->shortname</a> ->".
492 "<a href=\"$CFG->wwwroot/mod/workshop/index.php?id=$course->id\">$strworkshops</a> ->".
493 "<a href=\"$CFG->wwwroot/mod/workshop/view.php?id=$cm->id\">".format_string($workshop->name,true)."</a></font></p>";
494 $posthtml .= "<hr><font face=\"sans-serif\">";
495 $posthtml .= "<p>$msg</p>";
496 $posthtml .= "<p>".get_string("mail5", "workshop",
497 " <a href=\"$CFG->wwwroot/mod/workshop/view.php?id=$cm->id\">".format_string($workshop->name,true)."</a>")
498 ."</p></font><hr>";
500 else {
501 $posthtml = "";
504 if (!$teacher = get_teacher($course->id)) {
505 echo "Error: can not find teacher for course $course->id!\n";
508 if (! email_to_user($sendto, $teacher, $postsubject, $posttext, $posthtml)) {
509 echo "Error: workshop cron: Could not send out mail for id $submission->id to user
510 $sendto->id ($sendto->email)\n";
512 if (! set_field("workshop_comments", "mailed", "1", "id", "$comment->id")) {
513 echo "Could not update the mailed field for comment id $comment->id\n";
518 return true;
522 ///////////////////////////////////////////////////////////////////////////////
523 function workshop_delete_instance($id) {
524 // Given an ID of an instance of this module,
525 // this function will permanently delete the instance
526 // and any data that depends on it.
528 if (! $workshop = get_record("workshop", "id", "$id")) {
529 return false;
532 // delete all the associated records in the workshop tables, start positive...
533 $result = true;
535 if (! delete_records("workshop_comments", "workshopid", "$workshop->id")) {
536 $result = false;
539 if (! delete_records("workshop_stockcomments", "workshopid", "$workshop->id")) {
540 $result = false;
543 if (! delete_records("workshop_grades", "workshopid", "$workshop->id")) {
544 $result = false;
547 if (! delete_records("workshop_elements", "workshopid", "$workshop->id")) {
548 $result = false;
551 if (! delete_records("workshop_assessments", "workshopid", "$workshop->id")) {
552 $result = false;
555 if (! delete_records("workshop_submissions", "workshopid", "$workshop->id")) {
556 $result = false;
559 if (! delete_records("workshop", "id", "$workshop->id")) {
560 $result = false;
563 if (! delete_records('event', 'modulename', 'workshop', 'instance', $workshop->id)) {
564 $result = false;
567 return $result;
571 ///////////////////////////////////////////////////////////////////////////////
572 function workshop_grades($workshopid) {
573 /// Must return an array of grades, indexed by user, and a max grade.
574 /// only returns grades once assessment has started
575 /// returns nothing if workshop is not graded
576 global $CFG;
578 $return = null;
579 if ($workshop = get_record("workshop", "id", $workshopid)) {
580 if (($workshop->assessmentstart < time()) and $workshop->gradingstrategy) {
581 if ($students = workshop_get_students($workshop)) {
582 foreach ($students as $student) {
583 if ($workshop->wtype) {
584 $gradinggrade = workshop_gradinggrade($workshop, $student);
585 } else { // ignore grading grades for simple assignments
586 $gradinggrade = 0;
588 $bestgrade = 0;
589 if ($submissions = workshop_get_user_submissions($workshop, $student)) {
590 foreach ($submissions as $submission) {
591 if (!$submission->late) {
592 $grade = workshop_submission_grade($workshop, $submission);
593 } else {
594 $grade = 0.01;
596 if ($grade > $bestgrade) {
597 $bestgrade = $grade;
601 $return->grades[$student->id] = $gradinggrade + $bestgrade;
605 // set maximum grade if graded
606 if ($workshop->gradingstrategy) {
607 if ($workshop->wtype) {
608 $return->maxgrade = $workshop->grade + $workshop->gradinggrade;
609 } else { // ignore grading grades for simple assignemnts
610 $return->maxgrade = $workshop->grade;
614 return $return;
617 //////////////////////////////////////////////////////////////////////////////////////
618 function workshop_is_recent_activity($course, $isteacher, $timestart) {//jlw1 added for adding mark to courses with activity in My Moodle
619 global $CFG;
621 // have a look for agreed assessments for this user (agree)
622 $agreecontent = false;
623 if (!$isteacher) { // teachers only need to see submissions
624 if ($logs = workshop_get_agree_logs($course, $timestart)) {
625 // got some, see if any belong to a visible module
626 foreach ($logs as $log) {
627 // Create a temp valid module structure (only need courseid, moduleid)
628 $tempmod->course = $course->id;
629 $tempmod->id = $log->workshopid;
630 //Obtain the visible property from the instance
631 if (instance_is_visible("workshop",$tempmod)) {
632 $agreecontent = true;
633 break;
638 return false;
642 ///////////////////////////////////////////////////////////////////////////////
644 // NOTE: $isteacher usage should be converted to use roles.
645 // TODO: Fix this function.
647 function workshop_print_recent_activity($course, $isteacher, $timestart) {
648 global $CFG;
650 // have a look for agreed assessments for this user (agree)
651 $agreecontent = false;
652 if (!$isteacher) { // teachers only need to see submissions
653 if ($logs = workshop_get_agree_logs($course, $timestart)) {
654 // got some, see if any belong to a visible module
655 foreach ($logs as $log) {
656 // Create a temp valid module structure (only need courseid, moduleid)
657 $tempmod->course = $course->id;
658 $tempmod->id = $log->workshopid;
659 //Obtain the visible property from the instance
660 if (instance_is_visible("workshop",$tempmod)) {
661 $agreecontent = true;
662 break;
665 // if we got some "live" ones then output them
666 if ($agreecontent) {
667 print_headline(get_string("workshopagreedassessments", "workshop").":");
668 foreach ($logs as $log) {
669 //Create a temp valid module structure (only need courseid, moduleid)
670 $tempmod->course = $course->id;
671 $tempmod->id = $log->workshopid;
672 //Obtain the visible property from the instance
673 if (instance_is_visible("workshop",$tempmod)) {
674 if (!workshop_is_teacher($workshop, $log->userid)) { // don't break anonymous rule
675 $log->firstname = $course->student;
676 $log->lastname = '';
678 print_recent_activity_note($log->time, $log, $log->name,
679 $CFG->wwwroot.'/mod/workshop/'.$log->url);
686 // have a look for new assessments for this user (assess)
687 $assesscontent = false;
688 if (!$isteacher) { // teachers only need to see submissions
689 if ($logs = workshop_get_assess_logs($course, $timestart)) {
690 // got some, see if any belong to a visible module
691 foreach ($logs as $log) {
692 // Create a temp valid module structure (only need courseid, moduleid)
693 $tempmod->course = $course->id;
694 $tempmod->id = $log->workshopid;
695 //Obtain the visible property from the instance
696 if (instance_is_visible("workshop",$tempmod)) {
697 $assesscontent = true;
698 break;
701 // if we got some "live" ones then output them
702 if ($assesscontent) {
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 if (!workshop_is_teacher($tempmod->id, $log->userid)) { // don't break anonymous rule
711 $log->firstname = $course->student;
712 $log->lastname = '';
714 print_recent_activity_note($log->time, $log, $log->name,
715 $CFG->wwwroot.'/mod/workshop/'.$log->url);
721 // have a look for new comments for this user (comment)
722 $commentcontent = false;
723 if (!$isteacher) { // teachers only need to see submissions
724 if ($logs = workshop_get_comment_logs($course, $timestart)) {
725 // got some, see if any belong to a visible module
726 foreach ($logs as $log) {
727 // Create a temp valid module structure (only need courseid, moduleid)
728 $tempmod->course = $course->id;
729 $tempmod->id = $log->workshopid;
730 //Obtain the visible property from the instance
731 if (instance_is_visible("workshop",$tempmod)) {
732 $commentcontent = true;
733 break;
736 // if we got some "live" ones then output them
737 if ($commentcontent) {
738 print_headline(get_string("workshopcomments", "workshop").":");
739 foreach ($logs as $log) {
740 //Create a temp valid module structure (only need courseid, moduleid)
741 $tempmod->course = $course->id;
742 $tempmod->id = $log->workshopid;
743 //Obtain the visible property from the instance
744 if (instance_is_visible("workshop",$tempmod)) {
745 $log->firstname = $course->student; // Keep anonymous
746 $log->lastname = '';
747 print_recent_activity_note($log->time, $log, $log->name,
748 $CFG->wwwroot.'/mod/workshop/'.$log->url);
755 // have a look for new assessment gradings for this user (grade)
756 $gradecontent = false;
757 if ($logs = workshop_get_grade_logs($course, $timestart)) {
758 // got some, see if any belong to a visible module
759 foreach ($logs as $log) {
760 // Create a temp valid module structure (only need courseid, moduleid)
761 $tempmod->course = $course->id;
762 $tempmod->id = $log->workshopid;
763 //Obtain the visible property from the instance
764 if (instance_is_visible("workshop",$tempmod)) {
765 $gradecontent = true;
766 break;
769 // if we got some "live" ones then output them
770 if ($gradecontent) {
771 print_headline(get_string("workshopfeedback", "workshop").":");
772 foreach ($logs as $log) {
773 //Create a temp valid module structure (only need courseid, moduleid)
774 $tempmod->course = $course->id;
775 $tempmod->id = $log->workshopid;
776 //Obtain the visible property from the instance
777 if (instance_is_visible("workshop",$tempmod)) {
778 $log->firstname = $course->teacher; // Keep anonymous
779 $log->lastname = '';
780 print_recent_activity_note($log->time, $log, $log->name,
781 $CFG->wwwroot.'/mod/workshop/'.$log->url);
787 // have a look for new submissions (only show to teachers) (submit)
788 $submitcontent = false;
789 if ($isteacher) {
790 if ($logs = workshop_get_submit_logs($course, $timestart)) {
791 // got some, see if any belong to a visible module
792 foreach ($logs as $log) {
793 // Create a temp valid module structure (only need courseid, moduleid)
794 $tempmod->course = $course->id;
795 $tempmod->id = $log->workshopid;
796 //Obtain the visible property from the instance
797 if (instance_is_visible("workshop",$tempmod)) {
798 $submitcontent = true;
799 break;
802 // if we got some "live" ones then output them
803 if ($submitcontent) {
804 print_headline(get_string("workshopsubmissions", "workshop").":");
805 foreach ($logs as $log) {
806 //Create a temp valid module structure (only need courseid, moduleid)
807 $tempmod->course = $course->id;
808 $tempmod->id = $log->workshopid;
809 //Obtain the visible property from the instance
810 if (instance_is_visible("workshop",$tempmod)) {
811 print_recent_activity_note($log->time, $log, $log->name,
812 $CFG->wwwroot.'/mod/workshop/'.$log->url);
819 return $agreecontent or $assesscontent or $commentcontent or $gradecontent or $submitcontent;
823 ///////////////////////////////////////////////////////////////////////////////
824 function workshop_refresh_events($courseid = 0) {
825 // This standard function will check all instances of this module
826 // and make sure there are up-to-date events created for each of them.
827 // If courseid = 0, then every workshop event in the site is checked, else
828 // only workshop events belonging to the course specified are checked.
829 // This function is used, in its new format, by restore_refresh_events()
831 if ($courseid == 0) {
832 if (! $workshops = get_records("workshop")) {
833 return true;
835 } else {
836 if (! $workshops = get_records("workshop", "course", $courseid)) {
837 return true;
840 $moduleid = get_field('modules', 'id', 'name', 'workshop');
842 foreach ($workshops as $workshop) {
844 $dates = array(
845 'submissionstart' => $workshop->submissionstart,
846 'submissionend' => $workshop->submissionend,
847 'assessmentstart' => $workshop->assessmentstart,
848 'assessmentend' => $workshop->assessmentend
851 foreach ($dates as $type => $date) {
853 if ($date) {
854 if ($event = get_record('event', 'modulename', 'workshop', 'instance', $workshop->id, 'eventtype', $type)) {
855 $event->name = addslashes(get_string($type.'event','workshop', $workshop->name));
856 $event->description = addslashes($workshop->description);
857 $event->eventtype = $type;
858 $event->timestart = $date;
859 update_event($event);
860 } else {
861 $event->courseid = $workshop->course;
862 $event->modulename = 'workshop';
863 $event->instance = $workshop->id;
864 $event->name = addslashes(get_string($type.'event','workshop', $workshop->name));
865 $event->description = addslashes($workshop->description);
866 $event->eventtype = $type;
867 $event->timestart = $date;
868 $event->timeduration = 0;
869 $event->visible = get_field('course_modules', 'visible', 'module', $moduleid, 'instance', $workshop->id);
870 add_event($event);
875 return true;
879 ///////////////////////////////////////////////////////////////////////////////
880 function workshop_update_instance($workshop) {
881 // Given an object containing all the necessary data,
882 // (defined by the form in mod.html) this function
883 // will update an existing instance with new data.
884 global $CFG;
886 $workshop->timemodified = time();
888 $workshop->submissionstart = make_timestamp($workshop->submissionstartyear,
889 $workshop->submissionstartmonth, $workshop->submissionstartday, $workshop->submissionstarthour,
890 $workshop->submissionstartminute);
892 $workshop->assessmentstart = make_timestamp($workshop->assessmentstartyear,
893 $workshop->assessmentstartmonth, $workshop->assessmentstartday, $workshop->assessmentstarthour,
894 $workshop->assessmentstartminute);
896 $workshop->submissionend = make_timestamp($workshop->submissionendyear,
897 $workshop->submissionendmonth, $workshop->submissionendday, $workshop->submissionendhour,
898 $workshop->submissionendminute);
900 $workshop->assessmentend = make_timestamp($workshop->assessmentendyear,
901 $workshop->assessmentendmonth, $workshop->assessmentendday, $workshop->assessmentendhour,
902 $workshop->assessmentendminute);
904 $workshop->releasegrades = make_timestamp($workshop->releaseyear,
905 $workshop->releasemonth, $workshop->releaseday, $workshop->releasehour,
906 $workshop->releaseminute);
908 if (!workshop_check_dates($workshop)) {
909 return get_string('invaliddates', 'workshop');
912 // set the workshop's type
913 $wtype = 0; // 3 phases, no grading grades
914 if ($workshop->includeself or $workshop->ntassessments) $wtype = 1; // 3 phases with grading grades
915 if ($workshop->nsassessments) $wtype = 2; // 5 phases with grading grades
916 $workshop->wtype = $wtype;
918 // encode password if necessary
919 if (!empty($workshop->password)) {
920 $workshop->password = md5($workshop->password);
921 } else {
922 unset($workshop->password);
925 $workshop->id = $workshop->instance;
927 if ($returnid = update_record("workshop", $workshop)) {
929 $dates = array(
930 'submissionstart' => $workshop->submissionstart,
931 'submissionend' => $workshop->submissionend,
932 'assessmentstart' => $workshop->assessmentstart,
933 'assessmentend' => $workshop->assessmentend
935 $moduleid = get_field('modules', 'id', 'name', 'workshop');
937 foreach ($dates as $type => $date) {
938 if ($event = get_record('event', 'modulename', 'workshop', 'instance', $workshop->id, 'eventtype', $type)) {
939 $event->name = get_string($type.'event','workshop', $workshop->name);
940 $event->description = $workshop->description;
941 $event->eventtype = $type;
942 $event->timestart = $date;
943 update_event($event);
944 } else if ($date) {
945 $event = NULL;
946 $event->name = get_string($type.'event','workshop', $workshop->name);
947 $event->description = $workshop->description;
948 $event->courseid = $workshop->course;
949 $event->groupid = 0;
950 $event->userid = 0;
951 $event->modulename = 'workshop';
952 $event->instance = $workshop->instance;
953 $event->eventtype = $type;
954 $event->timestart = $date;
955 $event->timeduration = 0;
956 $event->visible = get_field('course_modules', 'visible', 'module', $moduleid, 'instance', $workshop->id);
957 add_event($event);
962 if (time() > $workshop->assessmentstart) {
963 // regrade all the submissions...
964 set_field("workshop_submissions", "nassessments", 0, "workshopid", $workshop->id);
965 workshop_grade_assessments($workshop);
968 return $returnid;
971 ///////////////////////////////////////////////////////////////////////////////
972 function workshop_user_complete($course, $user, $mod, $workshop) {
973 if ($submission = workshop_get_student_submission($workshop, $user)) {
974 if ($basedir = workshop_file_area($workshop, $user)) {
975 if ($files = get_directory_list($basedir)) {
976 $countfiles = count($files).' '.get_string('submissions', 'workshop');
977 foreach ($files as $file) {
978 $countfiles .= "; $file";
983 print_simple_box_start();
985 echo $submission->description.'<br />';
987 if (!empty($countfiles)) {
988 echo $countfiles,'<br />';
991 workshop_print_feedback($course, $submission);
993 print_simple_box_end();
995 } else {
996 print_string('notsubmittedyet', 'workshop');
1000 //////////////////////////////////////////////////////////////////////////////////////
1001 function workshop_print_feedback($course, $submission) {
1002 global $CFG, $RATING;
1004 if (! $feedbacks = get_records('workshop_assessments', 'submissionid', $submission->id)) {
1005 return;
1008 $strgrade = get_string('grade');
1009 $strnograde = get_string('nograde');
1011 foreach ($feedbacks as $feedback) {
1012 if (! $user = get_record('user', 'id', $feedback->userid)) {
1013 /// Weird error but we'll just ignore it and continue with other feedback
1014 continue;
1017 echo '<table cellspacing="0" class="workshop_feedbackbox">';
1019 echo '<tr>';
1020 echo '<td class="picture left">';
1021 print_user_picture($user->id, $course->id, $user->picture);
1022 echo '</td>';
1023 echo '<td><span class="author">'.fullname($user).'</span>';
1024 echo '<span class="time">'.userdate($feedback->timegraded).'</span>';
1025 echo '</tr>';
1027 echo '<tr><td class="left side">&nbsp;</td>';
1028 echo '<td class="content">';
1030 if ($feedback->grade) {
1031 echo $strgrade.': '.$feedback->grade;
1032 } else {
1033 echo $strnograde;
1036 echo '<span class="comment">'.format_text($feedback->generalcomment).'</span>';
1037 echo '<span class="teachercomment">'.format_text($feedback->teachercomment).'</span>';
1038 echo '</td></tr></table>';
1046 ///////////////////////////////////////////////////////////////////////////////
1047 function workshop_user_outline($course, $user, $mod, $workshop) {
1048 if ($submissions = workshop_get_user_submissions($workshop, $user)) {
1049 $result->info = count($submissions)." ".get_string("submissions", "workshop");
1050 // workshop_get_user_submissions returns the newest one first
1051 foreach ($submissions as $submission) {
1052 $result->time = $submission->timecreated;
1053 break;
1055 return $result;
1057 return NULL;
1060 //////////////////////////////////////////////////////////////////////////////////////
1061 function workshop_get_participants($workshopid) {
1062 //Returns the users with data in one workshop
1063 //(users with records in workshop_submissions, workshop_assessments and workshop_comments, students)
1065 global $CFG;
1067 //Get students from workshop_submissions
1068 $st_submissions = get_records_sql("SELECT DISTINCT u.id, u.id
1069 FROM {$CFG->prefix}user u,
1070 {$CFG->prefix}workshop_submissions s
1071 WHERE s.workshopid = '$workshopid' and
1072 u.id = s.userid");
1073 //Get students from workshop_assessments
1074 $st_assessments = get_records_sql("SELECT DISTINCT u.id, u.id
1075 FROM {$CFG->prefix}user u,
1076 {$CFG->prefix}workshop_assessments a
1077 WHERE a.workshopid = '$workshopid' and
1078 u.id = a.userid");
1080 //Get students from workshop_comments
1081 $st_comments = get_records_sql("SELECT DISTINCT u.id, u.id
1082 FROM {$CFG->prefix}user u,
1083 {$CFG->prefix}workshop_comments c
1084 WHERE c.workshopid = '$workshopid' and
1085 u.id = c.userid");
1087 //Add st_assessments to st_submissions
1088 if ($st_assessments) {
1089 foreach ($st_assessments as $st_assessment) {
1090 $st_submissions[$st_assessment->id] = $st_assessment;
1093 //Add st_comments to st_submissions
1094 if ($st_comments) {
1095 foreach ($st_comments as $st_comment) {
1096 $st_submissions[$st_comment->id] = $st_comment;
1099 //Return st_submissions array (it contains an array of unique users)
1100 return ($st_submissions);
1103 //////////////////////////////////////////////////////////////////////////////////////
1104 function workshop_get_recent_mod_activity(&$activities, &$index, $sincetime, $courseid,
1105 $workshop="0", $user="", $groupid="") {
1106 // Returns all workshop posts since a given time. If workshop is specified then
1107 // this restricts the results
1109 global $CFG;
1111 if ($workshop) {
1112 $workshopselect = " AND cm.id = '$workshop'";
1113 } else {
1114 $workshopselect = "";
1117 if ($user) {
1118 $userselect = " AND u.id = '$user'";
1119 } else {
1120 $userselect = "";
1123 $posts = get_records_sql("SELECT s.*, u.firstname, u.lastname,
1124 u.picture, cm.instance, w.name, cm.section
1125 FROM {$CFG->prefix}workshop_submissions s,
1126 {$CFG->prefix}user u,
1127 {$CFG->prefix}course_modules cm,
1128 {$CFG->prefix}workshop w
1129 WHERE s.timecreated > '$sincetime' $workshopselect
1130 AND s.userid = u.id $userselect
1131 AND w.course = '$courseid'
1132 AND cm.instance = w.id
1133 AND cm.course = w.course
1134 AND s.workshopid = w.id
1135 ORDER BY s.id");
1138 if (empty($posts)) {
1139 return;
1142 foreach ($posts as $post) {
1144 if (empty($groupid) || ismember($groupid, $post->userid)) {
1146 $tmpactivity = new Object;
1148 $tmpactivity->type = "workshop";
1149 $tmpactivity->defaultindex = $index;
1150 $tmpactivity->instance = $post->instance;
1151 $tmpactivity->name = $post->name;
1152 $tmpactivity->section = $post->section;
1154 $tmpactivity->content->id = $post->id;
1155 $tmpactivity->content->title = $post->title;
1157 $tmpactivity->user->userid = $post->userid;
1158 $tmpactivity->user->fullname = fullname($post);
1159 $tmpactivity->user->picture = $post->picture;
1161 $tmpactivity->timestamp = $post->timecreated;
1162 $activities[] = $tmpactivity;
1164 $index++;
1168 return;
1171 //////////////////////////////////////////////////////////////////////////////////////
1172 function workshop_print_recent_mod_activity($activity, $course, $detail=false) {
1174 global $CFG;
1176 echo '<table border="0" cellpadding="3" cellspacing="0">';
1178 if (!empty($activity->content->parent)) {
1179 $openformat = "<font size=\"2\"><i>";
1180 $closeformat = "</i></font>";
1181 } else {
1182 $openformat = "<b>";
1183 $closeformat = "</b>";
1186 echo "<tr><td class=\"workshoppostpicture\" width=\"35\" valign=\"top\">";
1187 print_user_picture($activity->user->userid, $course, $activity->user->picture);
1188 echo "</td><td>$openformat";
1190 if ($detail) {
1191 echo "<img src=\"$CFG->modpixpath/$activity->type/icon.gif\" ".
1192 "class=\"icon\" alt=\"".strip_tags(format_string($activity->name,true))."\" /> ";
1194 echo "<a href=\"$CFG->wwwroot/mod/workshop/view.php?"
1195 . "#" . $activity->content->id . "\">".$activity->content->title;
1197 echo "</a>$closeformat";
1199 echo "<br /><font size=\"2\">";
1200 echo "<a href=\"$CFG->wwwroot/user/view.php?id=" . $activity->user->userid . "&amp;course=" . "$course\">"
1201 . $activity->user->fullname . "</a>";
1202 echo " - " . userdate($activity->timestamp) . "</font></td></tr>";
1203 echo "</table>";
1205 return;
1210 //////////////////////////////////////////////////////////////////////////////////////
1211 // Non-standard workshop functions
1212 ///////////////////////////////////////////////////////////////////////////////////////////////
1213 function workshop_compare_assessments($workshop, $assessment1, $assessment2) {
1214 global $WORKSHOP_ASSESSMENT_COMPS, $WORKSHOP_EWEIGHTS;
1215 // first get the assignment elements for maxscores...
1216 $elementsraw = get_records("workshop_elements", "workshopid", $workshop->id, "elementno ASC");
1217 foreach ($elementsraw as $element) {
1218 $maxscore[] = $element->maxscore; // to renumber index 0,1,2...
1219 $weight[] = $WORKSHOP_EWEIGHTS[$element->weight]; // get real value and renumber index 0,1,2...
1222 $grades = array();
1223 for ($i = 0; $i < 2; $i++) {
1224 if ($i) {
1225 $rawgrades = get_records("workshop_grades", "assessmentid", $assessment1->id, "elementno ASC");
1226 } else {
1227 $rawgrades = get_records("workshop_grades", "assessmentid", $assessment2->id, "elementno ASC");
1229 if ($rawgrades) {
1230 foreach ($rawgrades as $grade) {
1231 $grades[$i][] = $grade->grade;
1235 $sumdiffs = 0;
1236 $sumweights = 0;
1237 switch ($workshop->gradingstrategy) {
1238 case 1 : // accumulative grading and...
1239 case 4 : // ...rubic grading
1240 for ($i=0; $i < $workshop->nelements; $i++) {
1241 $diff = ($grades[0][$i] - $grades[1][$i]) * $weight[$i] / $maxscore[$i];
1242 $sumdiffs += $diff * $diff; // use squared distances
1243 $sumweights += $weight[$i];
1245 break;
1246 case 2 : // error banded grading
1247 // ignore maxscores here, the grades are either 0 or 1,
1248 for ($i=0; $i < $workshop->nelements; $i++) {
1249 $diff = ($grades[0][$i] - $grades[1][$i]) * $weight[$i];
1250 $sumdiffs += $diff * $diff; // use squared distances
1251 $sumweights += $weight[$i];
1253 break;
1254 case 3 : // criterion grading
1255 // here we only need to look at the difference between the "zero" grade elements
1256 $diff = ($grades[0][0] - $grades[1][0]) / (count($elementsraw) - 1);
1257 $sumdiffs = $diff * $diff;
1258 $sumweights = 1;
1259 break;
1261 // convert to a sensible grade (always out of 100)
1262 $COMP = (object)$WORKSHOP_ASSESSMENT_COMPS[$workshop->assessmentcomps];
1263 $factor = $COMP->value;
1264 $gradinggrade = (($factor - ($sumdiffs / $sumweights)) / $factor) * 100;
1265 if ($gradinggrade < 0) {
1266 $gradinggrade = 0;
1268 return $gradinggrade;
1272 //////////////////////////////////////////////////////////////////////////////////////
1273 function workshop_count_assessments($submission) {
1274 // Return the (real) assessments for this submission,
1275 $timenow = time();
1276 return count_records_select("workshop_assessments",
1277 "submissionid = $submission->id AND timecreated < $timenow");
1281 //////////////////////////////////////////////////////////////////////////////////////
1282 function workshop_count_ungraded_assessments($workshop) {
1283 // function returns the number of ungraded assessments by students
1284 global $CFG;
1286 $timenow = time();
1287 $n = 0;
1288 // get all the cold assessments that have not been graded
1289 if ($assessments = get_records_select("workshop_assessments", "workshopid = $workshop->id AND
1290 (timecreated + $CFG->maxeditingtime) < $timenow AND timegraded = 0")) {
1291 foreach ($assessments as $assessment) {
1292 if (workshop_is_student($workshop, $assessment->userid)) {
1293 $n++;
1297 return $n;
1301 //////////////////////////////////////////////////////////////////////////////////////
1302 function workshop_file_area($workshop, $submission) {
1303 return make_upload_directory( workshop_file_area_name($workshop, $submission) );
1307 //////////////////////////////////////////////////////////////////////////////////////
1308 function workshop_file_area_name($workshop, $submission) {
1309 // Creates a directory file name, suitable for make_upload_directory()
1310 global $CFG;
1312 return "$workshop->course/$CFG->moddata/workshop/$submission->id";
1316 ///////////////////////////////////////////////////////////////////////////////////////////////
1317 function workshop_get_agree_logs($course, $timestart) {
1318 // get the "agree" entries for this user (the assessment owner) and add the first and last names
1319 // the last two probably wont be used...
1320 global $CFG, $USER;
1321 if (empty($USER->id)) {
1322 return false;
1325 $timethen = time() - $CFG->maxeditingtime;
1326 return get_records_sql("SELECT l.time, l.url, u.firstname, u.lastname, a.workshopid, a.userid, e.name
1327 FROM {$CFG->prefix}log l,
1328 {$CFG->prefix}workshop e,
1329 {$CFG->prefix}workshop_submissions s,
1330 {$CFG->prefix}workshop_assessments a,
1331 {$CFG->prefix}user u
1332 WHERE l.time > $timestart AND l.time < $timethen
1333 AND l.course = $course->id AND l.module = 'workshop' AND l.action = 'agree'
1334 AND a.id = l.info AND s.id = a.submissionid AND a.userid = $USER->id
1335 AND u.id = s.userid AND e.id = a.workshopid");
1339 ///////////////////////////////////////////////////////////////////////////////////////////////
1340 function workshop_get_assess_logs($course, $timestart) {
1341 // get the "assess" entries for this user and add the first and last names...
1342 global $CFG, $USER;
1343 if (empty($USER->id)) {
1344 return false;
1347 $timethen = time() - $CFG->maxeditingtime;
1348 return get_records_sql("SELECT l.time, l.url, u.firstname, u.lastname, a.workshopid, a.userid, e.name
1349 FROM {$CFG->prefix}log l,
1350 {$CFG->prefix}workshop e,
1351 {$CFG->prefix}workshop_submissions s,
1352 {$CFG->prefix}workshop_assessments a,
1353 {$CFG->prefix}user u
1354 WHERE l.time > $timestart AND l.time < $timethen
1355 AND l.course = $course->id AND l.module = 'workshop' AND l.action = 'assess'
1356 AND a.id = l.info AND s.id = a.submissionid AND s.userid = $USER->id
1357 AND u.id = a.userid AND e.id = a.workshopid");
1361 //////////////////////////////////////////////////////////////////////////////////////
1362 function workshop_get_assessments($submission, $all = '', $order = '') {
1363 // Return assessments for this submission ordered oldest first, newest last
1364 // new assessments made within the editing time are NOT returned unless they
1365 // belong to the user or the second argument is set to ALL
1366 global $CFG, $USER;
1368 $timenow = time();
1369 if (!$order) {
1370 $order = "timecreated DESC";
1372 if ($all != 'ALL') {
1373 return get_records_select("workshop_assessments", "(submissionid = $submission->id) AND
1374 ((timecreated < $timenow - $CFG->maxeditingtime) or
1375 ((timecreated < $timenow) AND (userid = $USER->id)))", $order);
1376 } else {
1377 return get_records_select("workshop_assessments", "submissionid = $submission->id AND
1378 (timecreated < $timenow)", $order);
1383 ///////////////////////////////////////////////////////////////////////////////////////////////
1384 function workshop_get_comment_logs($course, $timestart) {
1385 // get the "comment" entries for this user and add the first and last names (which may not be used)...
1386 global $CFG, $USER;
1387 if (empty($USER->id)) {
1388 return false;
1391 $timethen = time() - $CFG->maxeditingtime;
1392 return get_records_sql("SELECT l.time, l.url, u.firstname, u.lastname, a.workshopid, e.name
1393 FROM {$CFG->prefix}log l,
1394 {$CFG->prefix}workshop e,
1395 {$CFG->prefix}workshop_submissions s,
1396 {$CFG->prefix}workshop_assessments a,
1397 {$CFG->prefix}workshop_comments c,
1398 {$CFG->prefix}user u
1399 WHERE l.time > $timestart AND l.time < $timethen
1400 AND l.course = $course->id AND l.module = 'workshop' AND l.action = 'comment'
1401 AND c.id = l.info AND c.userid != $USER->id AND a.id = c.assessmentid
1402 AND s.id = a.submissionid AND (s.userid = $USER->id OR a.userid = $USER->id)
1403 AND u.id = a.userid AND e.id = a.workshopid");
1407 ///////////////////////////////////////////////////////////////////////////////////////////////
1408 function workshop_get_grade_logs($course, $timestart) {
1409 // get the "grade" entries for this user and add the first and last names (of submission owner,
1410 // better to get name of teacher...
1411 // ...but not available in assessment record...)
1412 global $CFG, $USER;
1413 if (empty($USER->id)) {
1414 return false;
1417 $timethen = time() - $CFG->maxeditingtime;
1418 return get_records_sql("SELECT l.time, l.url, u.firstname, u.lastname, a.workshopid, e.name
1419 FROM {$CFG->prefix}log l,
1420 {$CFG->prefix}workshop e,
1421 {$CFG->prefix}workshop_submissions s,
1422 {$CFG->prefix}workshop_assessments a,
1423 {$CFG->prefix}user u
1424 WHERE l.time > $timestart AND l.time < $timethen
1425 AND l.course = $course->id AND l.module = 'workshop' AND l.action = 'grade'
1426 AND a.id = l.info AND s.id = a.submissionid AND a.userid = $USER->id
1427 AND u.id = s.userid AND e.id = a.workshopid");
1431 //////////////////////////////////////////////////////////////////////////////////////
1432 function workshop_get_student_submission($workshop, $user) {
1433 // Return a submission for a particular user
1434 global $CFG;
1436 $submission = get_record("workshop_submissions", "workshopid", $workshop->id, "userid", $user->id);
1437 if (!empty($submission->timecreated)) {
1438 return $submission;
1440 return NULL;
1444 //////////////////////////////////////////////////////////////////////////////////////
1445 function workshop_get_student_submissions($workshop, $order = "title") {
1446 // Return all ENROLLED student submissions
1447 global $CFG;
1449 if ($order == "title") {
1450 $order = "s.title";
1452 if ($order == "name") {
1453 $order = "a.lastname, a.firstname";
1455 if ($order == "time") {
1456 $order = "s.timecreated ASC";
1459 if (!$students = workshop_get_students($workshop)) {
1460 return false;
1462 $list = "(";
1463 foreach ($students as $student) {
1464 $list .= "$student->id,";
1466 $list = rtrim($list, ',').")";
1468 return get_records_sql("SELECT s.* FROM {$CFG->prefix}workshop_submissions s, {$CFG->prefix}user a
1469 WHERE s.userid IN $list
1470 AND s.workshopid = $workshop->id
1471 AND s.timecreated > 0
1472 AND s.userid = a.id
1473 ORDER BY $order");
1477 ///////////////////////////////////////////////////////////////////////////////////////////////
1478 function workshop_get_submit_logs($course, $timestart) {
1479 // get the "submit" entries and add the first and last names...
1480 global $CFG, $USER;
1482 $timethen = time() - $CFG->maxeditingtime;
1483 return get_records_sql("SELECT l.time, l.url, u.firstname, u.lastname, l.info as workshopid, e.name
1484 FROM {$CFG->prefix}log l,
1485 {$CFG->prefix}workshop e,
1486 {$CFG->prefix}user u
1487 WHERE l.time > $timestart AND l.time < $timethen
1488 AND l.course = $course->id AND l.module = 'workshop'
1489 AND l.action = 'submit'
1490 AND e.id = l.info
1491 AND u.id = l.userid");
1495 //////////////////////////////////////////////////////////////////////////////////////
1496 function workshop_get_unmailed_assessments($cutofftime) {
1497 /// Return list of assessments that have not been mailed out
1498 global $CFG;
1499 return get_records_sql("SELECT a.*, g.course, g.name
1500 FROM {$CFG->prefix}workshop_assessments a, {$CFG->prefix}workshop g
1501 WHERE a.mailed = 0
1502 AND a.timecreated < $cutofftime
1503 AND g.id = a.workshopid
1504 AND g.releasegrades < $cutofftime");
1508 //////////////////////////////////////////////////////////////////////////////////////
1509 function workshop_get_unmailed_comments($cutofftime) {
1510 /// Return list of comments that have not been mailed out
1511 global $CFG;
1512 return get_records_sql("SELECT c.*, g.course, g.name
1513 FROM {$CFG->prefix}workshop_comments c, {$CFG->prefix}workshop g
1514 WHERE c.mailed = 0
1515 AND c.timecreated < $cutofftime
1516 AND g.id = c.workshopid");
1520 //////////////////////////////////////////////////////////////////////////////////////
1521 function workshop_get_unmailed_graded_assessments($cutofftime) {
1522 /// Return list of graded assessments that have not been mailed out
1523 global $CFG;
1524 return get_records_sql("SELECT a.*, g.course, g.name
1525 FROM {$CFG->prefix}workshop_assessments a, {$CFG->prefix}workshop g
1526 WHERE a.mailed = 0
1527 AND a.timegraded < $cutofftime
1528 AND a.timegraded > 0
1529 AND g.id = a.workshopid");
1533 //////////////////////////////////////////////////////////////////////////////////////
1534 function workshop_get_unmailed_resubmissions($cutofftime) {
1535 /// Return list of assessments of resubmissions that have not been mailed out
1536 global $CFG;
1537 return get_records_sql("SELECT a.*, w.course, w.name
1538 FROM {$CFG->prefix}workshop_assessments a, {$CFG->prefix}workshop w
1539 WHERE a.mailed = 0
1540 AND a.resubmission = 1
1541 AND w.id = a.workshopid");
1545 //////////////////////////////////////////////////////////////////////////////////////
1546 function workshop_get_user_assessments($workshop, $user) {
1547 // Return all the user's assessments, newest first, oldest last (hot, warm and cold ones)
1548 return get_records_select("workshop_assessments", "workshopid = $workshop->id AND userid = $user->id",
1549 "timecreated DESC");
1553 //////////////////////////////////////////////////////////////////////////////////////
1554 function workshop_get_user_submissions($workshop, $user) {
1555 // return real submissions of user newest first, oldest last. Ignores the dummy submissions
1556 // which get created to hold the final grades for users that make no submissions
1557 return get_records_select("workshop_submissions", "workshopid = $workshop->id AND
1558 userid = $user->id AND timecreated > 0", "timecreated DESC" );
1562 //////////////////////////////////////////////////////////////////////////////////////
1563 function workshop_grade_assessments($workshop, $verbose=false) {
1564 global $WORKSHOP_EWEIGHTS;
1566 // timeout after 10 minutes
1567 @set_time_limit(600);
1569 $timenow = time();
1571 // set minumim value for the variance (of the elements)
1572 $minvar = 0.05;
1574 // check when the standard deviations were calculated
1575 $oldtotalassessments = get_field("workshop_elements", "totalassessments", "workshopid", $workshop->id,
1576 "elementno", 0);
1577 $totalassessments = count_records("workshop_assessments", "workshopid", $workshop->id);
1578 // calculate the std. devs every 10 assessments for low numbers of assessments, thereafter every 100 new assessments
1579 if ((($totalassessments < 100) and (($totalassessments - $oldtotalassessments) > 10)) or
1580 (($totalassessments - $oldtotalassessments) > 100)) {
1581 // calculate the means for each submission using just the "good" assessments
1582 if ($submissions = get_records("workshop_submissions", "workshopid", $workshop->id)) {
1583 foreach ($submissions as $submission) {
1584 $nassessments[$submission->id] = 0;
1585 if ($assessments = workshop_get_assessments($submission)) {
1586 foreach ($assessments as $assessment) {
1587 // test if assessment is "good", a teacher assessment always "good", but may be weighted out
1588 if (workshop_is_teacher($workshop, $assessment->userid)) {
1589 if (!$workshop->teacherweight) {
1590 // drop teacher's assessment as weight is zero
1591 continue;
1593 } elseif ((!$assessment->gradinggrade and $assessment->timegraded) or
1594 ($workshop->agreeassessments and !$assessment->timeagreed)) {
1595 // it's a duff assessment, or it's not been agreed
1596 continue;
1598 if (isset($num[$submission->id])) {
1599 if (workshop_is_teacher($workshop, $assessment->userid)) {
1600 $num[$submission->id] += $workshop->teacherweight; // weight teacher's assessment
1601 } else {
1602 $num[$submission->id]++; // number of assessments
1604 $nassessments[$submission->id]++;
1605 } else {
1606 if (workshop_is_teacher($workshop, $assessment->userid)) {
1607 $num[$submission->id] = $workshop->teacherweight;
1608 } else {
1609 $num[$submission->id] = 1;
1611 $nassessments[$submission->id] = 1;
1613 for ($i = 0; $i < $workshop->nelements; $i++) {
1614 $grade = get_field("workshop_grades", "grade",
1615 "assessmentid", $assessment->id, "elementno", $i);
1616 if (isset($sum[$submission->id][$i])) {
1617 if (workshop_is_teacher($workshop, $assessment->userid)) {
1618 $sum[$submission->id][$i] += $workshop->teacherweight * $grade; // teacher's grade
1619 } else {
1620 $sum[$submission->id][$i] += $grade; // student's grade
1622 } else {
1623 if (workshop_is_teacher($workshop, $assessment->userid)) {
1624 $sum[$submission->id][$i] = $workshop->teacherweight * $grade; // teacher's grade
1625 } else {
1626 $sum[$submission->id][$i] = $grade; // students's grade
1634 if (!isset($num)) {
1635 // no assessments yet
1636 return;
1638 reset($num);
1639 // calculate the means for each submission
1640 $total = 0;
1641 foreach ($num as $submissionid => $n) {
1642 if ($n) { // stop division by zero
1643 for ($i = 0; $i < $workshop->nelements; $i++) {
1644 $mean[$submissionid][$i] = $sum[$submissionid][$i] / $n;
1645 // echo "Submission: $submissionid; Element: $i; Mean: {$mean[$submissionid][$i]}<br />\n";
1647 $total += $n; // weighted total
1650 if ($verbose) {
1651 echo "<p style=\"text-align:center\">".get_string("numberofsubmissions", "workshop", count($num))."<br />\n";
1652 echo get_string("numberofassessmentsweighted", "workshop", $total)."</p>\n";
1655 // now get an estimate of the standard deviation of each element in the assessment
1656 // this is just a rough measure, all assessments are included and teacher's assesments are not weighted
1657 $n = 0;
1658 for ($i = 0; $i < $workshop->nelements; $i++) {
1659 $var[$i] = 0;
1661 foreach ($submissions as $submission) {
1662 if ($assessments = workshop_get_assessments($submission)) {
1663 foreach ($assessments as $assessment) {
1664 $n++;
1665 for ($i = 0; $i < $workshop->nelements; $i++) {
1666 $grade = get_field("workshop_grades", "grade",
1667 "assessmentid", $assessment->id, "elementno", $i);
1668 $temp = $mean[$submission->id][$i] - $grade;
1669 $var[$i] += $temp * $temp;
1674 for ($i = 0; $i < $workshop->nelements; $i++) {
1675 if ($n > 1) {
1676 $sd[$i] = sqrt($var[$i] / ($n - 1));
1677 } else {
1678 $sd[$i] = 0;
1680 set_field("workshop_elements", "stddev", $sd[$i], "workshopid", $workshop->id, "elementno", $i);
1681 set_field("workshop_elements", "totalassessments", $totalassessments, "workshopid", $workshop->id,
1682 "elementno", $i);
1683 if ($verbose) {
1684 echo get_string("standarddeviationofelement", "workshop", $i+1)." $sd[$i]<br />";
1685 if ($sd[$i] <= $minvar) {
1686 print_string("standarddeviationnote", "workshop")."<br />\n";
1693 // this section looks at each submission if the number of assessments made has increased it recalculates the
1694 // grading grades for those assessments
1695 // first get the assignment elements for the weights and the stddevs...
1696 if ($elementsraw = get_records("workshop_elements", "workshopid", $workshop->id, "elementno ASC")) {
1697 foreach ($elementsraw as $element) {
1698 $weight[] = $element->weight; // to renumber index 0,1,2...
1699 $sd[] = $element->stddev; // to renumber index 0,1,2...
1703 unset($num); // may have been used in calculating stddevs
1704 unset($sum); // ditto
1705 if ($submissions = get_records("workshop_submissions", "workshopid", $workshop->id)) {
1706 foreach ($submissions as $submission) {
1707 // see if the number of assessments has changed
1708 $nassessments = workshop_count_assessments($submission);
1709 if ($submission->nassessments <> $nassessments) {
1710 // ...if there are three or more assessments calculate the variance of each assessment.
1711 // Use the variance to find the "best" assessment. (When there is only one or two assessments they
1712 // are not altered by this routine.)
1713 if ($verbose) {
1714 echo "Processing submission $submission->id ($nassessments asessments)...\n";
1716 if ($nassessments > 2) {
1717 $num = 0; // weighted number of assessments
1718 for ($i = 0; $i < $workshop->nelements; $i++) {
1719 $sum[$i] = 0; // weighted sum of grades
1721 if ($assessments = workshop_get_assessments($submission)) {
1722 // first calculate the mean grades for each element
1723 foreach ($assessments as $assessment) {
1724 // test if assessment is "good", a teacher assessment always "good", but may be weighted out
1725 if (workshop_is_teacher($workshop, $assessment->userid)) {
1726 if (!$workshop->teacherweight) {
1727 // drop teacher's assessment as weight is zero
1728 continue;
1730 } else if ((!$assessment->gradinggrade and $assessment->timegraded) or
1731 ($workshop->agreeassessments and !$assessment->timeagreed)) {
1732 // it's a duff assessment, or it's not been agreed
1733 continue;
1735 if (workshop_is_teacher($workshop, $assessment->userid)) {
1736 $num += $workshop->teacherweight; // weight teacher's assessment
1737 } else {
1738 $num++; // student assessment just add one
1740 for ($i = 0; $i < $workshop->nelements; $i++) {
1741 $grade = get_field("workshop_grades", "grade",
1742 "assessmentid", $assessment->id, "elementno", $i);
1743 if (workshop_is_teacher($workshop, $assessment->userid)) {
1744 $sum[$i] += $workshop->teacherweight * $grade; // teacher's grade
1745 } else {
1746 $sum[$i] += $grade; // student's grade
1750 if ($num) { // could all the assessments be duff?
1751 for ($i = 0; $i < $workshop->nelements; $i++) {
1752 $mean[$i] = $sum[$i] / $num;
1753 if ($verbose) echo "Submission: $submission->id; Element: $i; Mean: {$mean[$i]}\n";
1755 } else {
1756 continue; // move to the next submission
1758 // run through the assessments again to see which is the "best" one (the one
1759 // closest to the mean)
1760 $lowest = 10e9;
1761 foreach ($assessments as $assessment) {
1762 if ($workshop->agreeassessments and !$assessment->timeagreed) {
1763 // ignore assessments that have not been agreed
1764 continue;
1766 $var = 0;
1767 for ($i = 0; $i < $workshop->nelements; $i++) {
1768 $grade = get_field("workshop_grades", "grade",
1769 "assessmentid", $assessment->id, "elementno", $i);
1770 if ($sd[$i] > $minvar) {
1771 $temp = ($mean[$i] - $grade) *
1772 $WORKSHOP_EWEIGHTS[$weight[$i]] / $sd[$i];
1773 } else {
1774 $temp = 0;
1776 $var += $temp * $temp;
1778 // find the "best" assessment of this submission
1779 if ($lowest > $var) {
1780 $lowest = $var;
1781 $bestassessmentid = $assessment->id;
1785 if (!$best = get_record("workshop_assessments", "id", $bestassessmentid)) {
1786 notify("Workshop grade assessments: cannot find best assessment");
1787 continue;
1789 if ($verbose) {
1790 echo "Best assessment is $bestassessmentid;\n";
1792 foreach ($assessments as $assessment) {
1793 // don't overwrite teacher's grade
1794 if ($assessment->teachergraded) {
1795 continue;
1797 if ($assessment->id == $bestassessmentid) {
1798 // it's the best one, set the grading grade to the maximum
1799 set_field("workshop_assessments", "gradinggrade", 100, "id", $assessment->id);
1800 set_field("workshop_assessments", "timegraded", $timenow, "id", $assessment->id);
1801 } else {
1802 // it's one of the pack, compare with the best...
1803 $gradinggrade = workshop_compare_assessments($workshop, $best, $assessment);
1804 // ...and save the grade for the assessment
1805 set_field("workshop_assessments", "gradinggrade", $gradinggrade, "id", $assessment->id);
1806 set_field("workshop_assessments", "timegraded", $timenow, "id", $assessment->id);
1810 } else {
1811 // there are less than 3 assessments for this submission
1812 if ($assessments = workshop_get_assessments($submission)) {
1813 foreach ($assessments as $assessment) {
1814 if (!$assessment->timegraded and !$assessment->teachergraded) {
1815 // set the grading grade to the maximum and say it's been graded
1816 set_field("workshop_assessments", "gradinggrade", 100, "id", $assessment->id);
1817 set_field("workshop_assessments", "timegraded", $timenow, "id", $assessment->id);
1822 // set the number of assessments for this submission
1823 set_field("workshop_submissions", "nassessments", $nassessments, "id", $submission->id);
1827 return;
1831 //////////////////////////////////////////////////////////////////////////////////////
1832 function workshop_gradinggrade($workshop, $student) {
1833 // returns the current (external) grading grade of the based on their (cold) assessments
1834 // (needed as it's called by grade)
1836 $gradinggrade = 0;
1837 if ($assessments = workshop_get_user_assessments($workshop, $student)) {
1838 $n = 0;
1839 foreach ($assessments as $assessment) {
1840 $gradinggrade += $assessment->gradinggrade;
1841 $n++;
1843 if ($n < ($workshop->ntassessments + $workshop->nsassessments)) { // the minimum students should do
1844 $n = $workshop->ntassessments + $workshop->nsassessments;
1846 $gradinggrade = $gradinggrade / $n;
1848 return number_format($gradinggrade * $workshop->gradinggrade / 100, 1);
1852 //////////////////////////////////////////////////////////////////////////////////////
1853 function workshop_submission_grade($workshop, $submission) {
1854 // returns the current (external) grade of the submission based on the "good" (cold) assessments
1855 // (needed as it's called by grade)
1857 $grade = 0;
1858 if ($assessments = workshop_get_assessments($submission)) {
1859 $n = 0;
1860 foreach ($assessments as $assessment) {
1861 if ($workshop->agreeassessments and !$assessment->timeagreed) {
1862 // ignore assessments which have not been agreed
1863 continue;
1865 if ($assessment->gradinggrade or !$assessment->timegraded) {
1866 // a good assessment (or one that has not been graded yet)
1867 if (workshop_is_teacher($workshop, $assessment->userid)) {
1868 $timenow = time();
1869 if ($timenow > $workshop->releasegrades) {
1870 // teacher's grade is available
1871 $grade += $workshop->teacherweight * $assessment->grade;
1872 $n += $workshop->teacherweight;
1874 } else {
1875 $grade += $assessment->grade;
1876 $n++;
1880 if ($n) { // stop division by zero
1881 $grade = $grade / $n;
1884 return number_format($grade * $workshop->grade / 100, 1);
1888 /////////////////////////////////////////////////////////////////////////////
1889 function workshop_fullname($userid, $courseid) {
1890 global $CFG;
1891 if (!$user = get_record('user', 'id', $userid)) {
1892 return '';
1894 return '<a href="'.$CFG->wwwroot.'/user/view.php?id='.$user->id.'&amp;course='.$courseid.'">'.
1895 fullname($user).'</a>';
1898 function workshop_get_view_actions() {
1899 return array('view','view all');
1902 function workshop_get_post_actions() {
1903 return array('agree','assess','comment','grade','newattachment','removeattachments','resubmit','submit');