diff --git a/mod/assignment/backuplib.php b/mod/assignment/backuplib.php index 19b6bfa9a03..fd6dcdd60bd 100644 --- a/mod/assignment/backuplib.php +++ b/mod/assignment/backuplib.php @@ -42,6 +42,11 @@ fwrite ($bf,full_tag("FORMAT",4,false,$assignment->format)); fwrite ($bf,full_tag("RESUBMIT",4,false,$assignment->resubmit)); fwrite ($bf,full_tag("EMAILTEACHERS",4,false,$assignment->emailteachers)); + fwrite ($bf,full_tag("VAR1",4,false,$assignment->var1)); + fwrite ($bf,full_tag("VAR2",4,false,$assignment->var2)); + fwrite ($bf,full_tag("VAR3",4,false,$assignment->var3)); + fwrite ($bf,full_tag("VAR4",4,false,$assignment->var4)); + fwrite ($bf,full_tag("VAR5",4,false,$assignment->var5)); fwrite ($bf,full_tag("ASSIGNMENTTYPE",4,false,$assignment->assignmenttype)); fwrite ($bf,full_tag("MAXBYTES",4,false,$assignment->maxbytes)); fwrite ($bf,full_tag("TIMEDUE",4,false,$assignment->timedue)); diff --git a/mod/assignment/db/mysql.php b/mod/assignment/db/mysql.php index ddd1dabb828..facf386c1de 100644 --- a/mod/assignment/db/mysql.php +++ b/mod/assignment/db/mysql.php @@ -137,6 +137,15 @@ function assignment_upgrade($oldversion) { table_column('assignment_submissions', '', 'data1', 'MEDIUMTEXT', '', '', '', 'not null', 'numfiles'); } + if ($oldversion < 2005041600) { // Add five new fields for general assignment parameters + // so most assignment types won't need new fields and backups stay simple + table_column('assignment', '', 'var5', 'integer', '10', '', 0, 'null', 'emailteachers'); + table_column('assignment', '', 'var4', 'integer', '10', '', 0, 'null', 'emailteachers'); + table_column('assignment', '', 'var3', 'integer', '10', '', 0, 'null', 'emailteachers'); + table_column('assignment', '', 'var2', 'integer', '10', '', 0, 'null', 'emailteachers'); + table_column('assignment', '', 'var1', 'integer', '10', '', 0, 'null', 'emailteachers'); + } + /// These lines ALWAYS need to be here at the end of this file. Don't mess with them. :-) include_once("$CFG->dirroot/mod/assignment/lib.php"); diff --git a/mod/assignment/db/mysql.sql b/mod/assignment/db/mysql.sql index f8d57a74bbf..9a5aaa46bef 100644 --- a/mod/assignment/db/mysql.sql +++ b/mod/assignment/db/mysql.sql @@ -11,6 +11,11 @@ CREATE TABLE `prefix_assignment` ( `assignmenttype` varchar(50) NOT NULL default '', `resubmit` tinyint(2) unsigned NOT NULL default '0', `emailteachers` tinyint(2) unsigned NOT NULL default '0', + `var1` int(10) default '0', + `var2` int(10) default '0', + `var3` int(10) default '0', + `var4` int(10) default '0', + `var5` int(10) default '0', `maxbytes` int(10) unsigned NOT NULL default '100000', `timedue` int(10) unsigned NOT NULL default '0', `timeavailable` int(10) unsigned NOT NULL default '0', diff --git a/mod/assignment/db/postgres7.php b/mod/assignment/db/postgres7.php index 0f2744db8e8..3223ab4a7e0 100644 --- a/mod/assignment/db/postgres7.php +++ b/mod/assignment/db/postgres7.php @@ -135,6 +135,15 @@ function assignment_upgrade($oldversion) { table_column('assignment_submissions', '', 'data1', 'TEXT', '', '', '', 'not null', 'numfiles'); } + if ($oldversion < 2005041600) { // Add five new fields for general assignment parameters + // so most assignment types won't need new fields and backups stay simple + table_column('assignment', '', 'var5', 'integer', '10', '', 0, 'null', 'emailteachers'); + table_column('assignment', '', 'var4', 'integer', '10', '', 0, 'null', 'emailteachers'); + table_column('assignment', '', 'var3', 'integer', '10', '', 0, 'null', 'emailteachers'); + table_column('assignment', '', 'var2', 'integer', '10', '', 0, 'null', 'emailteachers'); + table_column('assignment', '', 'var1', 'integer', '10', '', 0, 'null', 'emailteachers'); + } + /// These lines ALWAYS need to be here at the end of this file. Don't mess with them. :-) diff --git a/mod/assignment/db/postgres7.sql b/mod/assignment/db/postgres7.sql index 9097beef45a..495b4d96c5e 100644 --- a/mod/assignment/db/postgres7.sql +++ b/mod/assignment/db/postgres7.sql @@ -11,6 +11,11 @@ CREATE TABLE prefix_assignment ( assignmenttype varchar(50) NOT NULL default '', resubmit integer NOT NULL default '0', emailteachers integer NOT NULL default '0', + var1 integer default '0', + var2 integer default '0', + var3 integer default '0', + var4 integer default '0', + var5 integer default '0', maxbytes integer NOT NULL default '100000', timedue integer NOT NULL default '0', timeavailable integer NOT NULL default '0', diff --git a/mod/assignment/details.php b/mod/assignment/details.php index d83408004c3..146f1c295d4 100644 --- a/mod/assignment/details.php +++ b/mod/assignment/details.php @@ -19,14 +19,6 @@ redirect($CFG->wwwroot.'/course/view.php?id='.$course->id); } -/// Set up things for a HTML editor if it's needed - - if ($usehtmleditor = can_use_html_editor()) { - $defaultformat = FORMAT_HTML; - $editorfields = ''; - } else { - $defaultformat = FORMAT_MOODLE; - } require_once("$CFG->dirroot/mod/assignment/type/$form->assignmenttype/assignment.class.php"); diff --git a/mod/assignment/lib.php b/mod/assignment/lib.php index af6b16e55a9..922c2fb4802 100644 --- a/mod/assignment/lib.php +++ b/mod/assignment/lib.php @@ -29,22 +29,29 @@ class assignment_base { * If cmid is set create the cm, course, assignment objects. * * @param cmid integer, the current course module id - not set for new assignments + * @param assignment object, usually null, but if we have it we pass it to save db access */ - function assignment_base($cmid=0) { + function assignment_base($cmid=0, $assignment=NULL, $cm=NULL, $course=NULL) { global $CFG; if ($cmid) { - if (! $this->cm = get_record("course_modules", "id", $cmid)) { - error("Course Module ID was incorrect"); + if ($cm) { + $this->cm = $cm; + } else if (! $this->cm = get_record('course_modules', 'id', $cmid)) { + error('Course Module ID was incorrect'); } - if (! $this->course = get_record("course", "id", $this->cm->course)) { - error("Course is misconfigured"); + if ($course) { + $this->course = $course; + } else if (! $this->course = get_record('course', 'id', $this->cm->course)) { + error('Course is misconfigured'); } - if (! $this->assignment = get_record("assignment", "id", $this->cm->instance)) { - error("assignment ID was incorrect"); + if ($assignment) { + $this->assignment = $assignment; + } else if (! $this->assignment = get_record('assignment', 'id', $this->cm->instance)) { + error('assignment ID was incorrect'); } $this->strassignment = get_string('modulename', 'assignment'); @@ -69,8 +76,15 @@ class assignment_base { } $this->currentgroup = get_current_group($this->course->id); - } + + /// Set up things for a HTML editor if it's needed + if ($this->usehtmleditor = can_use_html_editor()) { + $this->defaultformat = FORMAT_HTML; + } else { + $this->defaultformat = FORMAT_MOODLE; + } + } /* @@ -78,16 +92,11 @@ class assignment_base { */ function view() { - global $CFG; add_to_log($this->course->id, "assignment", "view", "view.php?id={$this->cm->id}", $this->assignment->id, $this->cm->id); - print_header($this->pagetitle, $this->course->fullname, $this->navigation.' '.$this->assignment->name, '', '', - true, update_module_button($this->cm->id, $this->course->id, $this->strassignment), - navmenu($this->course, $this->cm)); - - echo ''; + $this->view_header(); print_simple_box_start('center'); echo format_text($this->assignment->description, $this->assignment->format); @@ -100,7 +109,6 @@ class assignment_base { echo ''.get_string('duedate','assignment').':'; echo ' '.userdate($this->assignment->timedue).''; echo ''; - print_simple_box_end(); $this->view_feedback(); @@ -108,15 +116,44 @@ class assignment_base { print_footer($this->course); } + /* + * Display the top of the view.php page, this doesn't change much for submodules + */ + function view_header($subpage='') { - function view_feedback() { + global $CFG; + + if ($subpage) { + $extranav = ''. + $this->assignment->name.' -> '.$subpage; + } else { + $extranav = ' '.$this->assignment->name; + } + + print_header($this->pagetitle, $this->course->fullname, $this->navigation.$extranav, '', '', + true, update_module_button($this->cm->id, $this->course->id, $this->strassignment), + navmenu($this->course, $this->cm)); + + echo ''; + } + + + /* + * Display the bottom of the view.php page, this doesn't change much for submodules + */ + function view_footer() { + print_footer($this->course); + } + + + function view_feedback($submission=NULL) { global $USER; - /// Get submission for this assignment - /// If no submission then just return quietly - $submission = $this->get_submission($USER->id); - if (empty($submission->timemarked)) { - return; + if (!$submission) { /// Get submission for this assignment + $submission = $this->get_submission($USER->id); + if (empty($submission->timemarked)) { /// Nothing to show, so print nothing + return; + } } /// We need the teacher info @@ -135,7 +172,7 @@ class assignment_base { print_user_picture($teacher->id, $this->course->id, $teacher->picture); echo ''; echo ''; - echo '
'.fullname($teacher).'
'; + echo '
'.fullname($teacher).'
'; echo '
'.userdate($submission->timemarked).'
'; echo ''; echo ''; @@ -190,7 +227,7 @@ class assignment_base { $strname = get_string('name'); $strassignments = get_string('modulenameplural', 'assignment'); - $strheading = empty($form->name) ? get_string("type$form->assignmenttype",'assignment') : $form->name; + $strheading = empty($form->name) ? get_string("type$form->assignmenttype",'assignment') : s($form->name); print_header($this->course->shortname.': '.$strheading, "$strheading", "wwwroot/course/view.php?id={$this->course->id}\">{$this->course->shortname} -> ". @@ -205,13 +242,13 @@ class assignment_base { * Print the end of the setup form for the current assignment type */ function setup_end() { - global $CFG, $usehtmleditor; + global $CFG; include($CFG->dirroot.'/mod/assignment/type/common_end.html'); print_simple_box_end(); - if ($usehtmleditor) { + if ($this->usehtmleditor) { use_html_editor(); } @@ -299,11 +336,13 @@ class assignment_base { echo 'opener.document.getElementById("com'.$submission->userid. '").innerHTML="'.shorten_text($submission->comment, 15)."\";\n"; } - if (empty($SESSION->flextable['mod-assignment-submissions']->collapse['timemodified'])) { + if (empty($SESSION->flextable['mod-assignment-submissions']->collapse['timemodified']) && + $submission->timemodified) { echo 'opener.document.getElementById("ts'.$submission->userid. '").innerHTML="'.userdate($submission->timemodified)."\";\n"; } - if (empty($SESSION->flextable['mod-assignment-submissions']->collapse['timemarked'])) { + if (empty($SESSION->flextable['mod-assignment-submissions']->collapse['timemarked']) && + $submission->timemarked) { echo 'opener.document.getElementById("tt'.$submission->userid. '").innerHTML="'.userdate($submission->timemarked)."\";\n"; } @@ -365,10 +404,6 @@ class assignment_base { print_header($this->assignment->name.' '.fullname($user, true)); - echo '
'; - echo ''; - echo ''; - echo ''; echo ''; @@ -376,7 +411,10 @@ class assignment_base { echo ''; - echo ''; + echo ''; echo ''; echo ''; @@ -391,6 +429,10 @@ class assignment_base { echo ''; echo ''; echo '
'; print_user_picture($user->id, $this->course->id, $user->picture); echo ''.fullname($user, true).''; + echo '
'.fullname($user, true).'
'; + $this->print_user_files($user); + echo '
'; + echo ''; + echo ''; + echo ''; + echo ''; if (!$submission->grade and !$submission->timemarked) { $submission->grade = -1; /// Hack to stop zero being selected on the menu below (so it shows 'no grade') } @@ -402,13 +444,23 @@ class assignment_base { echo '  '.userdate($submission->timemarked); } echo '
'; - print_textarea(false, 6, 60, 500, 400, 'comment', $submission->comment, $this->course->id); + print_textarea($this->usehtmleditor, 10, 60, 0, 0, 'comment', $submission->comment, $this->course->id); + + echo '
'; + echo ''; + echo ''; + echo '
'; + + echo ''; + echo '
'; - echo ''; - echo ''; - echo ''; + + if ($this->usehtmleditor) { + use_html_editor(); + } + print_footer('none'); } @@ -711,6 +763,170 @@ class assignment_base { } } + function email_teachers($submission) { + /// Alerts teachers by email of new or changed assignments that need grading + + global $CFG; + + if (empty($assignment->emailteachers)) { // No need to do anything + return; + } + + $user = get_record('user', 'id', $submission->userid); + + $course = $this->course; // Shortcuts + $assignment = $this->assignment; + $cm = $this->cm; + + if (groupmode($course, $cm) == SEPARATEGROUPS) { // Separate groups are being used + if (!$group = user_group($course->id, $user->id)) { // Try to find a group + $group->id = 0; // Not in a group, never mind + } + $teachers = get_group_teachers($course->id, $group->id); // Works even if not in group + } else { + $teachers = get_course_teachers($course->id); + } + + if ($teachers) { + + $strassignments = get_string('modulenameplural', 'assignment'); + $strassignment = get_string('modulename', 'assignment'); + $strsubmitted = get_string('submitted', 'assignment'); + + foreach ($teachers as $teacher) { + unset($info); + $info->username = fullname($user); + $info->assignment = format_string($assignment->name,true); + $info->url = "$CFG->wwwroot/mod/assignment/submissions.php?id=$assignment->id"; + + $postsubject = "$strsubmitted: $info->username -> $assignment->name"; + $posttext = "$course->shortname -> $strassignments -> ".format_string($assignment->name,true)."\n"; + $posttext .= "---------------------------------------------------------------------\n"; + $posttext .= get_string("emailteachermail", "assignment", $info); + $posttext .= "\n---------------------------------------------------------------------\n"; + + if ($user->mailformat == 1) { // HTML + $posthtml = "

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

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

".get_string("emailteachermailhtml", "assignment", $info)."

"; + $posthtml .= "

"; + } else { + $posthtml = ""; + } + + @email_to_user($teacher, $user, $postsubject, $posttext, $posthtml); // If it fails, oh well, too bad. + } + } + } + + function print_user_files($user, $return=false) { + + global $CFG; + + $filearea = $this->file_area_name($user); + + $output = ''; + + if ($basedir = $this->file_area($user)) { + if ($files = get_directory_list($basedir)) { + foreach ($files as $key => $file) { + require_once($CFG->libdir.'/filelib.php'); + $icon = mimeinfo('icon', $file); + if ($CFG->slasharguments) { + $ffurl = "file.php/$filearea/$file"; + } else { + $ffurl = "file.php?file=/$filearea/$file"; + } + + $output = ''.$icon.''. + link_to_popup_window ('/'.$ffurl, 'file'.$key, $file, 450, 580, $file, 'none', true). + '
'; + } + } + } + + $output = '
'.$output.'
'; + + if ($return) { + return $output; + } + echo $output; + } + + + function file_area_name($user) { + // Creates a directory file name, suitable for make_upload_directory() + global $CFG; + + return $this->course->id.'/'.$CFG->moddata.'/assignment/'.$this->assignment->id.'/'.$user->id; + } + + function file_area($user) { + return make_upload_directory( $this->file_area_name($user) ); + } + + function user_outline($user) { + if ($submission = $this->get_submission($user->id)) { + + if ($submission->grade) { + $result->info = get_string("grade").": $submission->grade"; + } + $result->time = $submission->timemodified; + return $result; + } + return NULL; + } + + function user_complete($user) { + if ($submission = $this->get_submission($user->id)) { + if ($basedir = $this->file_area($user)) { + if ($files = get_directory_list($basedir)) { + $countfiles = count($files)." ".get_string("uploadedfiles", "assignment"); + foreach ($files as $file) { + $countfiles .= "; $file"; + } + } + } + + print_simple_box_start(); + echo get_string("lastmodified").": "; + echo userdate($submission->timemodified); + echo $this->display_lateness($this->assignment->timedue - $this->submission->timemodified); + + $this->print_user_files($user); + + echo '
'; + + if (empty($submission->timemarked)) { + print_string("notgradedyet", "assignment"); + } else { + $this->view_feedback($submission); + } + + print_simple_box_end(); + + } else { + print_string("notsubmittedyet", "assignment"); + } + } + + function display_lateness($time) { + if ($time < 0) { + $timetext = get_string('late', 'assignment', format_time($time)); + return ' ('.$timetext.')'; + } else { + $timetext = get_string('early', 'assignment', format_time($time)); + return ' ('.$timetext.')'; + } + } + + + + + } ////// End of the assignment_base class @@ -751,6 +967,471 @@ function assignment_add_instance($assignment) { return $ass->add_instance($assignment); } + +function assignment_user_outline($course, $user, $mod, $assignment) { + global $CFG; + + require_once("$CFG->dirroot/mod/assignment/type/$assignment->assignmenttype/assignment.class.php"); + $assignmentclass = "assignment_$assignment->assignmenttype"; + $ass = new $assignmentclass($mod->id, $assignment, $mod, $course); + return $ass->user_outline($user); +} + +function assignment_user_complete($course, $user, $mod, $assignment) { + global $CFG; + + require_once("$CFG->dirroot/mod/assignment/type/$assignment->assignmenttype/assignment.class.php"); + $assignmentclass = "assignment_$assignment->assignmenttype"; + $ass = new $assignmentclass($mod->id, $assignment, $mod, $course); + return $ass->user_complete($user); +} + + +function assignment_cron () { +// Function to be run periodically according to the moodle cron +// Finds all assignment notifications that have yet to be mailed out, and mails them + + global $CFG, $USER; + + /// Notices older than 1 day will not be mailed. This is to avoid the problem where + /// cron has not been running for a long time, and then suddenly people are flooded + /// with mail from the past few weeks or months + + $timenow = time(); + $endtime = $timenow - $CFG->maxeditingtime; + $starttime = $endtime - 24 * 3600; /// One day earlier + + if ($submissions = assignment_get_unmailed_submissions($starttime, $endtime)) { + + foreach ($submissions as $key => $submission) { + if (! set_field("assignment_submissions", "mailed", "1", "id", "$submission->id")) { + echo "Could not update the mailed field for id $submission->id. Not mailed.\n"; + unset($submissions[$key]); + } + } + + $timenow = time(); + + foreach ($submissions as $submission) { + + echo "Processing assignment submission $submission->id\n"; + + if (! $user = get_record("user", "id", "$submission->userid")) { + echo "Could not find user $post->userid\n"; + continue; + } + + $USER->lang = $user->lang; + + if (! $course = get_record("course", "id", "$submission->course")) { + echo "Could not find course $submission->course\n"; + continue; + } + + if (! isstudent($course->id, $user->id) and !isteacher($course->id, $user->id)) { + echo fullname($user)." not an active participant in $course->shortname\n"; + continue; + } + + if (! $teacher = get_record("user", "id", "$submission->teacher")) { + echo "Could not find teacher $submission->teacher\n"; + continue; + } + + if (! $mod = get_coursemodule_from_instance("assignment", $submission->assignment, $course->id)) { + echo "Could not find course module for assignment id $submission->assignment\n"; + continue; + } + + if (! $mod->visible) { /// Hold mail notification for hidden assignments until later + continue; + } + + $strassignments = get_string("modulenameplural", "assignment"); + $strassignment = get_string("modulename", "assignment"); + + unset($assignmentinfo); + $assignmentinfo->teacher = fullname($teacher); + $assignmentinfo->assignment = format_string($submission->name,true); + $assignmentinfo->url = "$CFG->wwwroot/mod/assignment/view.php?id=$mod->id"; + + $postsubject = "$course->shortname: $strassignments: ".format_string($submission->name,true); + $posttext = "$course->shortname -> $strassignments -> ".format_string($submission->name,true)."\n"; + $posttext .= "---------------------------------------------------------------------\n"; + $posttext .= get_string("assignmentmail", "assignment", $assignmentinfo); + $posttext .= "---------------------------------------------------------------------\n"; + + if ($user->mailformat == 1) { // HTML + $posthtml = "

". + "wwwroot/course/view.php?id=$course->id\">$course->shortname ->". + "wwwroot/mod/assignment/index.php?id=$course->id\">$strassignments ->". + "wwwroot/mod/assignment/view.php?id=$mod->id\">".format_string($submission->name,true)."

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

".get_string("assignmentmailhtml", "assignment", $assignmentinfo)."

"; + $posthtml .= "

"; + } else { + $posthtml = ""; + } + + if (! email_to_user($user, $teacher, $postsubject, $posttext, $posthtml)) { + echo "Error: assignment cron: Could not send out mail for id $submission->id to user $user->id ($user->email)\n"; + } + } + } + + return true; +} + +function assignment_grades($assignmentid) { +/// Must return an array of grades, indexed by user, and a max grade. + + + if (!$assignment = get_record("assignment", "id", $assignmentid)) { + return NULL; + } + + $grades = get_records_menu("assignment_submissions", "assignment", + $assignment->id, "", "userid,grade"); + + if ($assignment->grade >= 0) { + $return->grades = $grades; + $return->maxgrade = $assignment->grade; + + } else { // Scale + if ($grades) { + $scaleid = - ($assignment->grade); + if ($scale = get_record('scale', 'id', $scaleid)) { + $scalegrades = make_menu_from_list($scale->scale); + foreach ($grades as $key => $grade) { + $grades[$key] = $scalegrades[$grade]; + } + } + } + $return->grades = $grades; + $return->maxgrade = ""; + } + + return $return; +} + +function assignment_get_participants($assignmentid) { +//Returns the users with data in one assignment +//(users with records in assignment_submissions, students and teachers) + + global $CFG; + + //Get students + $students = get_records_sql("SELECT DISTINCT u.id, u.id + FROM {$CFG->prefix}user u, + {$CFG->prefix}assignment_submissions a + WHERE a.assignment = '$assignmentid' and + u.id = a.userid"); + //Get teachers + $teachers = get_records_sql("SELECT DISTINCT u.id, u.id + FROM {$CFG->prefix}user u, + {$CFG->prefix}assignment_submissions a + WHERE a.assignment = '$assignmentid' and + u.id = a.teacher"); + + //Add teachers to students + if ($teachers) { + foreach ($teachers as $teacher) { + $students[$teacher->id] = $teacher; + } + } + //Return students array (it contains an array of unique users) + return ($students); +} + + +function assignment_scale_used ($assignmentid,$scaleid) { +//This function returns if a scale is being used by one assignment + + $return = false; + + $rec = get_record('assignment','id',$assignmentid,'grade',-$scaleid); + + if (!empty($rec) && !empty($scaleid)) { + $return = true; + } + + return $return; +} + + +function assignment_refresh_events($courseid = 0) { +// This standard function will check all instances of this module +// and make sure there are up-to-date events created for each of them. +// If courseid = 0, then every assignment event in the site is checked, else +// only assignment events belonging to the course specified are checked. +// This function is used, in its new format, by restore_refresh_events() + + if ($courseid == 0) { + if (! $assignments = get_records("assignment")) { + return true; + } + } else { + if (! $assignments = get_records("assignment", "course", $courseid)) { + return true; + } + } + $moduleid = get_field('modules', 'id', 'name', 'assignment'); + + foreach ($assignments as $assignment) { + $event = NULL; + $event->name = addslashes($assignment->name); + $event->description = addslashes($assignment->description); + $event->timestart = $assignment->timedue; + + if ($event->id = get_field('event', 'id', 'modulename', 'assignment', 'instance', $assignment->id)) { + update_event($event); + + } else { + $event->courseid = $assignment->course; + $event->groupid = 0; + $event->userid = 0; + $event->modulename = 'assignment'; + $event->instance = $assignment->id; + $event->eventtype = 'due'; + $event->timeduration = 0; + $event->visible = get_field('course_modules', 'visible', 'module', $moduleid, 'instance', $assignment->id); + add_event($event); + } + + } + return true; +} + + +function assignment_print_recent_activity($course, $isteacher, $timestart) { + global $CFG; + + $content = false; + $assignments = NULL; + + if (!$logs = get_records_select('log', 'time > \''.$timestart.'\' AND '. + 'course = \''.$course->id.'\' AND '. + 'module = \'assignment\' AND '. + 'action = \'upload\' ', 'time ASC')) { + return false; + } + + foreach ($logs as $log) { + //Create a temp valid module structure (course,id) + $tempmod->course = $log->course; + $tempmod->id = $log->info; + //Obtain the visible property from the instance + $modvisible = instance_is_visible($log->module,$tempmod); + + //Only if the mod is visible + if ($modvisible) { + $assignments[$log->info] = assignment_log_info($log); + $assignments[$log->info]->time = $log->time; + $assignments[$log->info]->url = str_replace('&', '&', $log->url); + } + } + + if ($assignments) { + print_headline(get_string('newsubmissions', 'assignment').':'); + foreach ($assignments as $assignment) { + print_recent_activity_note($assignment->time, $assignment, $isteacher, $assignment->name, + $CFG->wwwroot.'/mod/assignment/'.$assignment->url); + } + $content = true; + } + + return $content; +} + + + +function assignment_get_recent_mod_activity(&$activities, &$index, $sincetime, $courseid, $assignment="0", $user="", $groupid="") { +// Returns all assignments since a given time. If assignment is specified then +// this restricts the results + + global $CFG; + + if ($assignment) { + $assignmentselect = " AND cm.id = '$assignment'"; + } else { + $assignmentselect = ""; + } + if ($user) { + $userselect = " AND u.id = '$user'"; + } else { + $userselect = ""; + } + + $assignments = get_records_sql("SELECT asub.*, u.firstname, u.lastname, u.picture, u.id as userid, + a.grade as maxgrade, name, cm.instance, cm.section, a.assignmenttype + FROM {$CFG->prefix}assignment_submissions asub, + {$CFG->prefix}user u, + {$CFG->prefix}assignment a, + {$CFG->prefix}course_modules cm + WHERE asub.timemodified > '$sincetime' + AND asub.userid = u.id $userselect + AND a.id = asub.assignment $assignmentselect + AND cm.course = '$courseid' + AND cm.instance = a.id + ORDER BY asub.timemodified ASC"); + + if (empty($assignments)) + return; + + foreach ($assignments as $assignment) { + if (empty($groupid) || ismember($groupid, $assignment->userid)) { + + $tmpactivity = new Object; + + $tmpactivity->type = "assignment"; + $tmpactivity->defaultindex = $index; + $tmpactivity->instance = $assignment->instance; + $tmpactivity->name = $assignment->name; + $tmpactivity->section = $assignment->section; + + $tmpactivity->content->grade = $assignment->grade; + $tmpactivity->content->maxgrade = $assignment->maxgrade; + $tmpactivity->content->type = $assignment->assignmenttype; + + $tmpactivity->user->userid = $assignment->userid; + $tmpactivity->user->fullname = fullname($assignment); + $tmpactivity->user->picture = $assignment->picture; + + $tmpactivity->timestamp = $assignment->timemodified; + + $activities[] = $tmpactivity; + + $index++; + } + } + + return; +} + + +function assignment_print_recent_mod_activity($activity, $course, $detail=false) { + global $CFG; + + echo ''; + + echo ""; + echo "
"; + print_user_picture($activity->user->userid, $course, $activity->user->picture); + echo ""; + + if ($detail) { + echo "modpixpath/$activity->type/icon.gif\" ". + "height=16 width=16 alt=\"$activity->type\"> "; + echo "wwwroot/mod/assignment/view.php?id=" . $activity->instance . "\">" + . format_string($activity->name,true) . " - "; + + } + + if (isteacher($course)) { + $grades = "(" . $activity->content->grade . " / " . $activity->content->maxgrade . ") "; + + $assignment->id = $activity->instance; + $assignment->course = $course; + $user->id = $activity->user->userid; + + echo $grades; + echo "
"; + } + echo "wwwroot/user/view.php?id=" + . $activity->user->userid . "&course=$course\">" + . $activity->user->fullname . " "; + + echo " - " . userdate($activity->timestamp); + + echo "
"; + + return; +} + +/// GENERIC SQL FUNCTIONS + +function assignment_log_info($log) { + global $CFG; + return get_record_sql("SELECT a.name, u.firstname, u.lastname + FROM {$CFG->prefix}assignment a, + {$CFG->prefix}user u + WHERE a.id = '$log->info' + AND u.id = '$log->userid'"); +} + +function assignment_get_unmailed_submissions($starttime, $endtime) { +/// Return list of marked submissions that have not been mailed out for currently enrolled students + global $CFG; + return get_records_sql("SELECT s.*, a.course, a.name + FROM {$CFG->prefix}assignment_submissions s, + {$CFG->prefix}assignment a, + {$CFG->prefix}user_students us + WHERE s.mailed = 0 + AND s.timemarked <= $endtime + AND s.timemarked >= $starttime + AND s.assignment = a.id + AND s.userid = us.userid + AND a.course = us.course"); +} + +function assignment_count_real_submissions($assignment, $groupid=0) { +/// Return all real assignment submissions by ENROLLED students (not empty ones) + global $CFG; + + if ($groupid) { /// How many in a particular group? + return count_records_sql("SELECT COUNT(DISTINCT g.userid, g.groupid) + FROM {$CFG->prefix}assignment_submissions a, + {$CFG->prefix}groups_members g + WHERE a.assignment = $assignment->id + AND a.timemodified > 0 + AND g.groupid = '$groupid' + AND a.userid = g.userid "); + } else { + $select = "s.course = '$assignment->course' AND"; + if ($assignment->course == SITEID) { + $select = ''; + } + return count_records_sql("SELECT COUNT(*) + FROM {$CFG->prefix}assignment_submissions a, + {$CFG->prefix}user_students s + WHERE a.assignment = '$assignment->id' + AND a.timemodified > 0 + AND $select a.userid = s.userid "); + } +} + +function assignment_get_all_submissions($assignment, $sort="", $dir="DESC") { +/// Return all assignment submissions by ENROLLED students (even empty) + global $CFG; + + if ($sort == "lastname" or $sort == "firstname") { + $sort = "u.$sort $dir"; + } else if (empty($sort)) { + $sort = "a.timemodified DESC"; + } else { + $sort = "a.$sort $dir"; + } + + $select = "s.course = '$assignment->course' AND"; + if ($assignment->course == SITEID) { + $select = ''; + } + return get_records_sql("SELECT a.* + FROM {$CFG->prefix}assignment_submissions a, + {$CFG->prefix}user_students s, + {$CFG->prefix}user u + WHERE a.userid = s.userid + AND u.id = a.userid + AND $select a.assignment = '$assignment->id' + ORDER BY $sort"); +} + + + + +/// OTHER GENERAL FUNCTIONS FOR ASSIGNMENTS /////////////////////////////////////// + + function assignment_types() { $types = array(); $names = get_list_of_plugins('mod/assignment/type'); diff --git a/mod/assignment/mod.html b/mod/assignment/mod.html index ebdd58fe400..2ccbbb429d1 100644 --- a/mod/assignment/mod.html +++ b/mod/assignment/mod.html @@ -34,6 +34,7 @@ if (empty($form->timedue)) { $form->timedue = ""; } + ?>
@@ -86,16 +87,6 @@ ?> - - - - @@ -115,6 +106,21 @@ ?> + + + + + + + + +
: - assignmenttype, ""); - helpbutton("assignmenttype", get_string("assignmenttype", "assignment"), "assignment"); - ?> -
:
 
: + assignmenttype, ""); + helpbutton("assignmenttype", get_string("assignmenttype", "assignment"), "assignment"); + ?> +

diff --git a/mod/assignment/restorelib.php b/mod/assignment/restorelib.php index 77f1f04b166..c569c98e72c 100644 --- a/mod/assignment/restorelib.php +++ b/mod/assignment/restorelib.php @@ -45,6 +45,11 @@ $assignment->format = backup_todb($info['MOD']['#']['FORMAT']['0']['#']); $assignment->resubmit = backup_todb($info['MOD']['#']['RESUBMIT']['0']['#']); $assignment->emailteachers = backup_todb($info['MOD']['#']['EMAILTEACHERS']['0']['#']); + $assignment->var1 = backup_todb($info['MOD']['#']['VAR1']['0']['#']); + $assignment->var2 = backup_todb($info['MOD']['#']['VAR2']['0']['#']); + $assignment->var3 = backup_todb($info['MOD']['#']['VAR3']['0']['#']); + $assignment->var4 = backup_todb($info['MOD']['#']['VAR4']['0']['#']); + $assignment->var5 = backup_todb($info['MOD']['#']['VAR5']['0']['#']); $assignment->type = backup_todb($info['MOD']['#']['TYPE']['0']['#']); $assignment->assignmenttype = backup_todb($info['MOD']['#']['ASSIGNMENTTYPE']['0']['#']); $assignment->maxbytes = backup_todb($info['MOD']['#']['MAXBYTES']['0']['#']); diff --git a/mod/assignment/styles.php b/mod/assignment/styles.php index e0a820c90c0..bb91a87f6ee 100644 --- a/mod/assignment/styles.php +++ b/mod/assignment/styles.php @@ -1,5 +1,19 @@ -#mod-assignment-submissions .submission td { +#mod-assignment-submissions .submission .content, +#mod-assignment-submissions .submission .heading, +#mod-assignment-submissions .submission .picture +{ padding: 10px; + border-width:1px; + border-style:solid; + border-color:#DDDDDD; +} + +#mod-assignment-submissions .submission .fullname { + float: left; +} + +#mod-assignment-submissions .submission .files { + float: right; } #mod-assignment-submissions .generaltable .r1 { @@ -14,8 +28,8 @@ background: #FFD991; } -#mod-assignment-submissions .submissions td, -#mod-assignment-submissions .submissions th +#mod-assignment-submissions table.submissions td, +#mod-assignment-submissions table.submissions th { border-width: 1px; border-style: solid; @@ -68,7 +82,7 @@ border-color:#DDDDDD; } -#mod-assignment-view .feedback .author { +#mod-assignment-view .feedback .fullname { font-weight: bold; } diff --git a/mod/assignment/submissions.php b/mod/assignment/submissions.php index 2a2b29444f9..5e3c40abd4d 100644 --- a/mod/assignment/submissions.php +++ b/mod/assignment/submissions.php @@ -40,7 +40,7 @@ /// Load up the required assignment code require($CFG->dirroot.'/mod/assignment/type/'.$assignment->assignmenttype.'/assignment.class.php'); $assignmentclass = 'assignment_'.$assignment->assignmenttype; - $assignmentinstance = new $assignmentclass($cm->id); + $assignmentinstance = new $assignmentclass($cm->id, $assignment, $cm, $course); $assignmentinstance->submissions($mode); // Display or process the submissions diff --git a/mod/assignment/type/uploadsingle/assignment.class.php b/mod/assignment/type/uploadsingle/assignment.class.php index 8cdf38ca906..fe4dd1715ae 100644 --- a/mod/assignment/type/uploadsingle/assignment.class.php +++ b/mod/assignment/type/uploadsingle/assignment.class.php @@ -15,6 +15,9 @@ class assignment_uploadsingle extends assignment_base { global $CFG, $usehtmleditor; parent::setup($form); + + print_simple_box(get_string('', 'assignment'), 'center'); + include("$CFG->dirroot/mod/assignment/type/uploadsingle/mod.html"); parent::setup_end(); } @@ -49,6 +52,155 @@ class assignment_uploadsingle extends assignment_base { return $submitted; } + function view() { + + $this->view_header(); + + print_simple_box_start('center'); + echo format_text($this->assignment->description, $this->assignment->format); + print_simple_box_end(); + + print_simple_box_start('center', '', '', '', 'time'); + echo ''; + echo ''; + echo ' '; + echo ''; + echo ' '; + echo '
'.get_string('availabledate','assignment').':'.userdate($this->assignment->timeavailable).'
'.get_string('duedate','assignment').':'.userdate($this->assignment->timedue).'
'; + print_simple_box_end(); + + $this->view_feedback(); + + $this->view_upload_form(); + + $this->view_footer(); + } + + function view_upload_form() { + global $CFG; + + echo '
'; + echo 'wwwroot/mod/assignment/upload.php\">"; + echo ''; + require_once($CFG->dirroot.'/lib/uploadlib.php'); + upload_print_form_fragment(1,array('newfile'),false,null,0,$this->assignment->maxbytes,false); + echo ''; + echo ''; + echo '
'; + } + + + function get_user_file($user) { + global $CFG; + + $tmpfile = ""; + + $filearea = file_area_name($user); + + if ($basedir = file_area($user)) { + if ($files = get_directory_list($basedir)) { + foreach ($files as $file) { // Just gets the first one + $icon = mimeinfo("icon", $file); + if ($CFG->slasharguments) { + $ffurl = "file.php/$filearea/$file"; + } else { + $ffurl = "file.php?file=/$filearea/$file"; + } + $tmpfile->url = $ffurl; + $tmpfile->name = $file; + $tmpfile->icon = $icon; + break; + } + } + } + return $tmpfile; + } + + function upload() { + global $CFG, $USER; + + $this->view_header(); + + if ($submission = $this->get_submission($USER->id)) { + if ($submission->grade and !$this->assignment->resubmit) { + notify(get_string('alreadygraded', 'assignment')); + } + } + + $dir = $this->file_area_name($USER); + + require_once($CFG->dirroot.'/lib/uploadlib.php'); + $um = new upload_manager('newfile',true,false,$course,false,$this->assignment->maxbytes); + if ($um->process_file_uploads($dir)) { + $newfile_name = $um->get_new_filename(); + if ($submission) { + $submission->timemodified = time(); + $submission->numfiles = 1; + $submission->comment = addslashes($submission->comment); + if (update_record("assignment_submissions", $submission)) { + $this->email_teachers($submission); + print_heading(get_string('uploadedfile')); + } else { + notify(get_string("uploadfailnoupdate", "assignment")); + } + } else { + $newsubmission->assignment = $this->assignment->id; + $newsubmission->userid = $USER->id; + $newsubmission->timecreated = time(); + $newsubmission->timemodified = time(); + $newsubmission->numfiles = 1; + if (insert_record("assignment_submissions", $newsubmission)) { + add_to_log($this->course->id, "assignment", "upload", + "view.php?a=$this->assignment->id", $this->assignment->id, $this->cm->id); + $this->email_teachers($newsubmission); + print_heading(get_string('uploadedfile')); + } else { + notify(get_string("uploadnotregistered", "assignment", $newfile_name) ); + } + } + } + + print_continue('view.php?id='.$this->cm->id); + + $this->view_footer(); + } + + + /* + * Display and process the submissions + */ + function process_feedback() { + + global $USER; + + if (!$feedback = data_submitted()) { // No incoming data? + return false; + } + + if (!empty($feedback->cancel)) { // User hit cancel button + return false; + } + + $newsubmission = $this->get_submission($feedback->userid, true); // Get or make one + + $newsubmission->grade = $feedback->grade; + $newsubmission->comment = $feedback->comment; + $newsubmission->teacher = $USER->id; + $newsubmission->mailed = 0; // Make sure mail goes out (again, even) + $newsubmission->timemarked = time(); + + if (! update_record('assignment_submissions', $newsubmission)) { + return false; + } + + add_to_log($this->course->id, 'assignment', 'update grades', + 'submissions.php?id='.$this->assignment->id.'&user='.$feedback->userid, $feedback->userid, $this->cm->id); + + return $newsubmission; + + } + } diff --git a/mod/assignment/type/uploadsingle/mod.html b/mod/assignment/type/uploadsingle/mod.html index 7f98198e7c2..2e64ad4c182 100644 --- a/mod/assignment/type/uploadsingle/mod.html +++ b/mod/assignment/type/uploadsingle/mod.html @@ -1,3 +1,52 @@ +resubmit)) { + $form->resubmit = ''; + } + if (empty($form->maxbytes)) { + $form->maxbytes = $CFG->assignment_maxbytes; + } + if (empty($form->emailteachers)) { + $form->emailteachers = ''; + } +?> + + + + + + + + + + + + + + + + + + +
: + maxbytes, $this->course->maxbytes); + choose_from_menu ($choices, "maxbytes", $form->maxbytes, ""); + ?> +
: + resubmit, ""); + helpbutton("resubmit", get_string("allowresubmit", "assignment"), "assignment"); + ?> +
: + emailteachers, ""); + helpbutton("emailteachers", get_string("emailteachers", "assignment"), "assignment"); + ?> +
+
-"> +
+" />
diff --git a/mod/assignment/type/uploadsingle/upload.php b/mod/assignment/type/uploadsingle/upload.php new file mode 100644 index 00000000000..fb73f967517 --- /dev/null +++ b/mod/assignment/type/uploadsingle/upload.php @@ -0,0 +1,73 @@ +course)) { + error("Course is misconfigured"); + } + + if (! $cm = get_coursemodule_from_instance("assignment", $assignment->id, $course->id)) { + error("Course Module ID was incorrect"); + } + + require_login($course->id, false, $cm); + + $strassignments = get_string("modulenameplural", "assignment"); + $strassignment = get_string("modulename", "assignment"); + $strupload = get_string("upload"); + + print_header_simple("$assignment->name : $strupload", "", + "id>$strassignments -> + id\">$assignment->name -> $strupload", + "", "", true); + + if ($submission = get_record("assignment_submissions", "assignment", $assignment->id, "userid", $USER->id)) { + if ($submission->grade and !$assignment->resubmit) { + error("You've already been graded - there's no point in uploading anything"); + } + } + + $dir = assignment_file_area_name($assignment,$USER); + require_once($CFG->dirroot.'/lib/uploadlib.php'); + $um = new upload_manager('newfile',true,false,$course,false,$assignment->maxbytes); + if ($um->process_file_uploads($dir)) { + $newfile_name = $um->get_new_filename(); + if ($submission) { + $submission->timemodified = time(); + $submission->numfiles = 1; + $submission->comment = addslashes($submission->comment); + if (update_record("assignment_submissions", $submission)) { + assignment_email_teachers($course, $cm, $assignment, $submission); + print_heading(get_string('uploadedfile')); + } else { + notify(get_string("uploadfailnoupdate", "assignment")); + } + } else { + $newsubmission->assignment = $assignment->id; + $newsubmission->userid = $USER->id; + $newsubmission->timecreated = time(); + $newsubmission->timemodified = time(); + $newsubmission->numfiles = 1; + if (insert_record("assignment_submissions", $newsubmission)) { + add_to_log($course->id, "assignment", "upload", "view.php?a=$assignment->id", "$assignment->id", $cm->id); + assignment_email_teachers($course, $cm, $assignment, $newsubmission); + print_heading(get_string('uploadedfile')); + } else { + notify(get_string("uploadnotregistered", "assignment", $newfile_name) ); + } + } + } + // upload class will take care of printing out errors. + + print_continue("view.php?a=$assignment->id"); + + print_footer($course); + +?> diff --git a/mod/assignment/upload.php b/mod/assignment/upload.php index fb73f967517..231048d5dc6 100644 --- a/mod/assignment/upload.php +++ b/mod/assignment/upload.php @@ -3,71 +3,40 @@ require_once("../../config.php"); require_once("lib.php"); - require_variable($id); // Assignment ID + $id = optional_param('id'); // Course module ID + $a = optional_param('a'); // Assignment ID - if (! $assignment = get_record("assignment", "id", $id)) { - error("Not a valid assignment ID"); - } + if ($id) { + if (! $cm = get_record("course_modules", "id", $id)) { + error("Course Module ID was incorrect"); + } - if (! $course = get_record("course", "id", $assignment->course)) { - error("Course is misconfigured"); - } + if (! $assignment = get_record("assignment", "id", $cm->instance)) { + error("assignment ID was incorrect"); + } - if (! $cm = get_coursemodule_from_instance("assignment", $assignment->id, $course->id)) { - error("Course Module ID was incorrect"); + if (! $course = get_record("course", "id", $assignment->course)) { + error("Course is misconfigured"); + } + } else { + if (!$assignment = get_record("assignment", "id", $a)) { + error("Course module is incorrect"); + } + if (! $course = get_record("course", "id", $assignment->course)) { + error("Course is misconfigured"); + } + if (! $cm = get_coursemodule_from_instance("assignment", $assignment->id, $course->id)) { + error("Course Module ID was incorrect"); + } } require_login($course->id, false, $cm); - $strassignments = get_string("modulenameplural", "assignment"); - $strassignment = get_string("modulename", "assignment"); - $strupload = get_string("upload"); +/// Load up the required assignment code + require($CFG->dirroot.'/mod/assignment/type/'.$assignment->assignmenttype.'/assignment.class.php'); + $assignmentclass = 'assignment_'.$assignment->assignmenttype; + $assignmentinstance = new $assignmentclass($cm->id, $assignment, $cm, $course); - print_header_simple("$assignment->name : $strupload", "", - "id>$strassignments -> - id\">$assignment->name -> $strupload", - "", "", true); - - if ($submission = get_record("assignment_submissions", "assignment", $assignment->id, "userid", $USER->id)) { - if ($submission->grade and !$assignment->resubmit) { - error("You've already been graded - there's no point in uploading anything"); - } - } - - $dir = assignment_file_area_name($assignment,$USER); - require_once($CFG->dirroot.'/lib/uploadlib.php'); - $um = new upload_manager('newfile',true,false,$course,false,$assignment->maxbytes); - if ($um->process_file_uploads($dir)) { - $newfile_name = $um->get_new_filename(); - if ($submission) { - $submission->timemodified = time(); - $submission->numfiles = 1; - $submission->comment = addslashes($submission->comment); - if (update_record("assignment_submissions", $submission)) { - assignment_email_teachers($course, $cm, $assignment, $submission); - print_heading(get_string('uploadedfile')); - } else { - notify(get_string("uploadfailnoupdate", "assignment")); - } - } else { - $newsubmission->assignment = $assignment->id; - $newsubmission->userid = $USER->id; - $newsubmission->timecreated = time(); - $newsubmission->timemodified = time(); - $newsubmission->numfiles = 1; - if (insert_record("assignment_submissions", $newsubmission)) { - add_to_log($course->id, "assignment", "upload", "view.php?a=$assignment->id", "$assignment->id", $cm->id); - assignment_email_teachers($course, $cm, $assignment, $newsubmission); - print_heading(get_string('uploadedfile')); - } else { - notify(get_string("uploadnotregistered", "assignment", $newfile_name) ); - } - } - } - // upload class will take care of printing out errors. - - print_continue("view.php?a=$assignment->id"); - - print_footer($course); + $assignmentinstance->upload(); // Upload files ?> diff --git a/mod/assignment/version.php b/mod/assignment/version.php index d11f9f668d0..2e2018c8e9a 100644 --- a/mod/assignment/version.php +++ b/mod/assignment/version.php @@ -5,7 +5,7 @@ // This fragment is called by /admin/index.php //////////////////////////////////////////////////////////////////////////////// -$module->version = 2005041501; +$module->version = 2005041600; $module->requires = 2005031000; // Requires this Moodle version $module->cron = 60; diff --git a/mod/assignment/view.php b/mod/assignment/view.php index 42cc6239db3..e9a7abbada5 100644 --- a/mod/assignment/view.php +++ b/mod/assignment/view.php @@ -36,7 +36,7 @@ require ("$CFG->dirroot/mod/assignment/type/$assignment->assignmenttype/assignment.class.php"); $assignmentclass = "assignment_$assignment->assignmenttype"; - $assignmentinstance = new $assignmentclass($cm->id); + $assignmentinstance = new $assignmentclass($cm->id, $assignment, $cm, $course); $assignmentinstance->view(); // Actually display the assignment!