Beispiel #1
0
 /**
  *  Display all the submissions ready for grading
  *
  * @global object
  * @global object
  * @global object
  * @global object
  * @param string $message
  * @return bool|void
  */
 function display_submissions($message = '')
 {
     global $CFG, $DB, $USER, $DB, $OUTPUT, $PAGE;
     require_once $CFG->libdir . '/gradelib.php';
     /* first we check to see if the form has just been submitted
      * to request user_preference updates
      */
     $filters = array(self::FILTER_ALL => get_string('all'), self::FILTER_REQUIRE_GRADING => get_string('requiregrading', 'assignment'));
     $updatepref = optional_param('updatepref', 0, PARAM_BOOL);
     if ($updatepref) {
         $perpage = optional_param('perpage', 10, PARAM_INT);
         $perpage = $perpage <= 0 ? 10 : $perpage;
         $filter = optional_param('filter', 0, PARAM_INT);
         set_user_preference('assignment_perpage', $perpage);
         set_user_preference('assignment_quickgrade', optional_param('quickgrade', 0, PARAM_BOOL));
         set_user_preference('assignment_filter', $filter);
     }
     /* next we get perpage and quickgrade (allow quick grade) params
      * from database
      */
     $perpage = get_user_preferences('assignment_perpage', 10);
     $quickgrade = get_user_preferences('assignment_quickgrade', 0) && $this->quickgrade_mode_allowed();
     $filter = get_user_preferences('assignment_filter', 0);
     $grading_info = grade_get_grades($this->course->id, 'mod', 'assignment', $this->assignment->id);
     if (!empty($CFG->enableoutcomes) and !empty($grading_info->outcomes)) {
         $uses_outcomes = true;
     } else {
         $uses_outcomes = false;
     }
     $page = optional_param('page', 0, PARAM_INT);
     $strsaveallfeedback = get_string('saveallfeedback', 'assignment');
     /// Some shortcuts to make the code read better
     $course = $this->course;
     $assignment = $this->assignment;
     $cm = $this->cm;
     $hassubmission = false;
     // reset filter to all for offline assignment only.
     if ($assignment->assignmenttype == 'offline') {
         if ($filter == self::FILTER_SUBMITTED) {
             $filter = self::FILTER_ALL;
         }
     } else {
         $filters[self::FILTER_SUBMITTED] = get_string('submitted', 'assignment');
     }
     $tabindex = 1;
     //tabindex for quick grading tabbing; Not working for dropdowns yet
     add_to_log($course->id, 'assignment', 'view submission', 'submissions.php?id=' . $this->cm->id, $this->assignment->id, $this->cm->id);
     $PAGE->set_title(format_string($this->assignment->name, true));
     $PAGE->set_heading($this->course->fullname);
     echo $OUTPUT->header();
     echo '<div class="usersubmissions">';
     //hook to allow plagiarism plugins to update status/print links.
     echo plagiarism_update_status($this->course, $this->cm);
     $course_context = get_context_instance(CONTEXT_COURSE, $course->id);
     if (has_capability('gradereport/grader:view', $course_context) && has_capability('moodle/grade:viewall', $course_context)) {
         echo '<div class="allcoursegrades"><a href="' . $CFG->wwwroot . '/grade/report/grader/index.php?id=' . $course->id . '">' . get_string('seeallcoursegrades', 'grades') . '</a></div>';
     }
     if (!empty($message)) {
         echo $message;
         // display messages here if any
     }
     $context = get_context_instance(CONTEXT_MODULE, $cm->id);
     /// Check to see if groups are being used in this assignment
     /// find out current groups mode
     $groupmode = groups_get_activity_groupmode($cm);
     $currentgroup = groups_get_activity_group($cm, true);
     groups_print_activity_menu($cm, $CFG->wwwroot . '/mod/assignment/submissions.php?id=' . $this->cm->id);
     /// Print quickgrade form around the table
     if ($quickgrade) {
         $formattrs = array();
         $formattrs['action'] = new moodle_url('/mod/assignment/submissions.php');
         $formattrs['id'] = 'fastg';
         $formattrs['method'] = 'post';
         echo html_writer::start_tag('form', $formattrs);
         echo html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'id', 'value' => $this->cm->id));
         echo html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'mode', 'value' => 'fastgrade'));
         echo html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'page', 'value' => $page));
         echo html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'sesskey', 'value' => sesskey()));
     }
     /// Get all ppl that are allowed to submit assignments
     list($esql, $params) = get_enrolled_sql($context, 'mod/assignment:submit', $currentgroup);
     if ($filter == self::FILTER_ALL) {
         $sql = "SELECT u.id FROM {user} u " . "LEFT JOIN ({$esql}) eu ON eu.id=u.id " . "WHERE u.deleted = 0 AND eu.id=u.id ";
     } else {
         $wherefilter = ' AND s.assignment = ' . $this->assignment->id;
         $assignmentsubmission = "LEFT JOIN {assignment_submissions} s ON (u.id = s.userid) ";
         if ($filter == self::FILTER_SUBMITTED) {
             $wherefilter .= ' AND s.timemodified > 0 ';
         } else {
             if ($filter == self::FILTER_REQUIRE_GRADING && $assignment->assignmenttype != 'offline') {
                 $wherefilter .= ' AND s.timemarked < s.timemodified ';
             } else {
                 // require grading for offline assignment
                 $assignmentsubmission = "";
                 $wherefilter = "";
             }
         }
         $sql = "SELECT u.id FROM {user} u " . "LEFT JOIN ({$esql}) eu ON eu.id=u.id " . $assignmentsubmission . "WHERE u.deleted = 0 AND eu.id=u.id " . $wherefilter;
     }
     $users = $DB->get_records_sql($sql, $params);
     if (!empty($users)) {
         if ($assignment->assignmenttype == 'offline' && $filter == self::FILTER_REQUIRE_GRADING) {
             //remove users who has submitted their assignment
             foreach ($this->get_submissions() as $submission) {
                 if (array_key_exists($submission->userid, $users)) {
                     unset($users[$submission->userid]);
                 }
             }
         }
         $users = array_keys($users);
     }
     // if groupmembersonly used, remove users who are not in any group
     if ($users and !empty($CFG->enablegroupmembersonly) and $cm->groupmembersonly) {
         if ($groupingusers = groups_get_grouping_members($cm->groupingid, 'u.id', 'u.id')) {
             $users = array_intersect($users, array_keys($groupingusers));
         }
     }
     $extrafields = get_extra_user_fields($context);
     $tablecolumns = array_merge(array('picture', 'fullname'), $extrafields, array('grade', 'submissioncomment', 'timemodified', 'timemarked', 'status', 'finalgrade'));
     if ($uses_outcomes) {
         $tablecolumns[] = 'outcome';
         // no sorting based on outcomes column
     }
     $extrafieldnames = array();
     foreach ($extrafields as $field) {
         $extrafieldnames[] = get_user_field_name($field);
     }
     $tableheaders = array_merge(array('', get_string('fullnameuser')), $extrafieldnames, array(get_string('grade'), get_string('comment', 'assignment'), get_string('lastmodified') . ' (' . get_string('submission', 'assignment') . ')', get_string('lastmodified') . ' (' . get_string('grade') . ')', get_string('status'), get_string('finalgrade', 'grades')));
     if ($uses_outcomes) {
         $tableheaders[] = get_string('outcome', 'grades');
     }
     require_once $CFG->libdir . '/tablelib.php';
     $table = new flexible_table('mod-assignment-submissions');
     $table->define_columns($tablecolumns);
     $table->define_headers($tableheaders);
     $table->define_baseurl($CFG->wwwroot . '/mod/assignment/submissions.php?id=' . $this->cm->id . '&amp;currentgroup=' . $currentgroup);
     $table->sortable(true, 'lastname');
     //sorted by lastname by default
     $table->collapsible(true);
     $table->initialbars(true);
     $table->column_suppress('picture');
     $table->column_suppress('fullname');
     $table->column_class('picture', 'picture');
     $table->column_class('fullname', 'fullname');
     foreach ($extrafields as $field) {
         $table->column_class($field, $field);
     }
     $table->column_class('grade', 'grade');
     $table->column_class('submissioncomment', 'comment');
     $table->column_class('timemodified', 'timemodified');
     $table->column_class('timemarked', 'timemarked');
     $table->column_class('status', 'status');
     $table->column_class('finalgrade', 'finalgrade');
     if ($uses_outcomes) {
         $table->column_class('outcome', 'outcome');
     }
     $table->set_attribute('cellspacing', '0');
     $table->set_attribute('id', 'attempts');
     $table->set_attribute('class', 'submissions');
     $table->set_attribute('width', '100%');
     $table->no_sorting('finalgrade');
     $table->no_sorting('outcome');
     $table->text_sorting('submissioncomment');
     // Start working -- this is necessary as soon as the niceties are over
     $table->setup();
     /// Construct the SQL
     list($where, $params) = $table->get_sql_where();
     if ($where) {
         $where .= ' AND ';
     }
     if ($filter == self::FILTER_SUBMITTED) {
         $where .= 's.timemodified > 0 AND ';
     } else {
         if ($filter == self::FILTER_REQUIRE_GRADING) {
             $where = '';
             if ($assignment->assignmenttype != 'offline') {
                 $where .= 's.timemarked < s.timemodified AND ';
             }
         }
     }
     if ($sort = $table->get_sql_sort()) {
         $sort = ' ORDER BY ' . $sort;
     }
     $ufields = user_picture::fields('u', $extrafields);
     if (!empty($users)) {
         $select = "SELECT {$ufields},\n                              s.id AS submissionid, s.grade, s.submissioncomment,\n                              s.timemodified, s.timemarked,\n                              CASE WHEN s.timemarked > 0 AND s.timemarked >= s.timemodified THEN 1\n                                   ELSE 0 END AS status ";
         $sql = 'FROM {user} u ' . 'LEFT JOIN {assignment_submissions} s ON u.id = s.userid
                 AND s.assignment = ' . $this->assignment->id . ' ' . 'WHERE ' . $where . 'u.id IN (' . implode(',', $users) . ') ';
         $ausers = $DB->get_records_sql($select . $sql . $sort, $params, $table->get_page_start(), $table->get_page_size());
         $table->pagesize($perpage, count($users));
         ///offset used to calculate index of student in that particular query, needed for the pop up to know who's next
         $offset = $page * $perpage;
         $strupdate = get_string('update');
         $strgrade = get_string('grade');
         $strview = get_string('view');
         $grademenu = make_grades_menu($this->assignment->grade);
         if ($ausers !== false) {
             $grading_info = grade_get_grades($this->course->id, 'mod', 'assignment', $this->assignment->id, array_keys($ausers));
             $endposition = $offset + $perpage;
             $currentposition = 0;
             foreach ($ausers as $auser) {
                 if ($currentposition == $offset && $offset < $endposition) {
                     $rowclass = null;
                     $final_grade = $grading_info->items[0]->grades[$auser->id];
                     $grademax = $grading_info->items[0]->grademax;
                     $final_grade->formatted_grade = round($final_grade->grade, 2) . ' / ' . round($grademax, 2);
                     $locked_overridden = 'locked';
                     if ($final_grade->overridden) {
                         $locked_overridden = 'overridden';
                     }
                     // TODO add here code if advanced grading grade must be reviewed => $auser->status=0
                     $picture = $OUTPUT->user_picture($auser);
                     if (empty($auser->submissionid)) {
                         $auser->grade = -1;
                         //no submission yet
                     }
                     if (!empty($auser->submissionid)) {
                         $hassubmission = true;
                         ///Prints student answer and student modified date
                         ///attach file or print link to student answer, depending on the type of the assignment.
                         ///Refer to print_student_answer in inherited classes.
                         if ($auser->timemodified > 0) {
                             $studentmodifiedcontent = $this->print_student_answer($auser->id) . userdate($auser->timemodified);
                             if ($assignment->timedue && $auser->timemodified > $assignment->timedue && $this->supports_lateness()) {
                                 $studentmodifiedcontent .= $this->display_lateness($auser->timemodified);
                                 $rowclass = 'late';
                             }
                         } else {
                             $studentmodifiedcontent = '&nbsp;';
                         }
                         $studentmodified = html_writer::tag('div', $studentmodifiedcontent, array('id' => 'ts' . $auser->id));
                         ///Print grade, dropdown or text
                         if ($auser->timemarked > 0) {
                             $teachermodified = '<div id="tt' . $auser->id . '">' . userdate($auser->timemarked) . '</div>';
                             if ($final_grade->locked or $final_grade->overridden) {
                                 $grade = '<div id="g' . $auser->id . '" class="' . $locked_overridden . '">' . $final_grade->formatted_grade . '</div>';
                             } else {
                                 if ($quickgrade) {
                                     $attributes = array();
                                     $attributes['tabindex'] = $tabindex++;
                                     $menu = html_writer::label(get_string('assignment:grade', 'assignment'), 'menumenu' . $auser->id, false, array('class' => 'accesshide'));
                                     $menu .= html_writer::select(make_grades_menu($this->assignment->grade), 'menu[' . $auser->id . ']', $auser->grade, array(-1 => get_string('nograde')), $attributes);
                                     $grade = '<div id="g' . $auser->id . '">' . $menu . '</div>';
                                 } else {
                                     $grade = '<div id="g' . $auser->id . '">' . $this->display_grade($auser->grade) . '</div>';
                                 }
                             }
                         } else {
                             $teachermodified = '<div id="tt' . $auser->id . '">&nbsp;</div>';
                             if ($final_grade->locked or $final_grade->overridden) {
                                 $grade = '<div id="g' . $auser->id . '" class="' . $locked_overridden . '">' . $final_grade->formatted_grade . '</div>';
                             } else {
                                 if ($quickgrade) {
                                     $attributes = array();
                                     $attributes['tabindex'] = $tabindex++;
                                     $menu = html_writer::label(get_string('assignment:grade', 'assignment'), 'menumenu' . $auser->id, false, array('class' => 'accesshide'));
                                     $menu .= html_writer::select(make_grades_menu($this->assignment->grade), 'menu[' . $auser->id . ']', $auser->grade, array(-1 => get_string('nograde')), $attributes);
                                     $grade = '<div id="g' . $auser->id . '">' . $menu . '</div>';
                                 } else {
                                     $grade = '<div id="g' . $auser->id . '">' . $this->display_grade($auser->grade) . '</div>';
                                 }
                             }
                         }
                         ///Print Comment
                         if ($final_grade->locked or $final_grade->overridden) {
                             $comment = '<div id="com' . $auser->id . '">' . shorten_text(strip_tags($final_grade->str_feedback), 15) . '</div>';
                         } else {
                             if ($quickgrade) {
                                 $comment = '<div id="com' . $auser->id . '">' . '<textarea tabindex="' . $tabindex++ . '" name="submissioncomment[' . $auser->id . ']" id="submissioncomment' . $auser->id . '" rows="2" cols="20">' . $auser->submissioncomment . '</textarea></div>';
                             } else {
                                 $comment = '<div id="com' . $auser->id . '">' . shorten_text(strip_tags($auser->submissioncomment), 15) . '</div>';
                             }
                         }
                     } else {
                         $studentmodified = '<div id="ts' . $auser->id . '">&nbsp;</div>';
                         $teachermodified = '<div id="tt' . $auser->id . '">&nbsp;</div>';
                         $status = '<div id="st' . $auser->id . '">&nbsp;</div>';
                         if ($final_grade->locked or $final_grade->overridden) {
                             $grade = '<div id="g' . $auser->id . '">' . $final_grade->formatted_grade . '</div>';
                             $hassubmission = true;
                         } else {
                             if ($quickgrade) {
                                 // allow editing
                                 $attributes = array();
                                 $attributes['tabindex'] = $tabindex++;
                                 $menu = html_writer::label(get_string('assignment:grade', 'assignment'), 'menumenu' . $auser->id, false, array('class' => 'accesshide'));
                                 $menu .= html_writer::select(make_grades_menu($this->assignment->grade), 'menu[' . $auser->id . ']', $auser->grade, array(-1 => get_string('nograde')), $attributes);
                                 $grade = '<div id="g' . $auser->id . '">' . $menu . '</div>';
                                 $hassubmission = true;
                             } else {
                                 $grade = '<div id="g' . $auser->id . '">-</div>';
                             }
                         }
                         if ($final_grade->locked or $final_grade->overridden) {
                             $comment = '<div id="com' . $auser->id . '">' . $final_grade->str_feedback . '</div>';
                         } else {
                             if ($quickgrade) {
                                 $comment = '<div id="com' . $auser->id . '">' . '<textarea tabindex="' . $tabindex++ . '" name="submissioncomment[' . $auser->id . ']" id="submissioncomment' . $auser->id . '" rows="2" cols="20">' . $auser->submissioncomment . '</textarea></div>';
                             } else {
                                 $comment = '<div id="com' . $auser->id . '">&nbsp;</div>';
                             }
                         }
                     }
                     if (empty($auser->status)) {
                         /// Confirm we have exclusively 0 or 1
                         $auser->status = 0;
                     } else {
                         $auser->status = 1;
                     }
                     $buttontext = $auser->status == 1 ? $strupdate : $strgrade;
                     if ($final_grade->locked or $final_grade->overridden) {
                         $buttontext = $strview;
                     }
                     ///No more buttons, we use popups ;-).
                     $popup_url = '/mod/assignment/submissions.php?id=' . $this->cm->id . '&amp;userid=' . $auser->id . '&amp;mode=single' . '&amp;filter=' . $filter . '&amp;offset=' . $offset++;
                     $button = $OUTPUT->action_link($popup_url, $buttontext);
                     $status = '<div id="up' . $auser->id . '" class="s' . $auser->status . '">' . $button . '</div>';
                     $finalgrade = '<span id="finalgrade_' . $auser->id . '">' . $final_grade->str_grade . '</span>';
                     $outcomes = '';
                     if ($uses_outcomes) {
                         foreach ($grading_info->outcomes as $n => $outcome) {
                             $outcomes .= '<div class="outcome"><label for="' . 'outcome_' . $n . '_' . $auser->id . '">' . $outcome->name . '</label>';
                             $options = make_grades_menu(-$outcome->scaleid);
                             if ($outcome->grades[$auser->id]->locked or !$quickgrade) {
                                 $options[0] = get_string('nooutcome', 'grades');
                                 $outcomes .= ': <span id="outcome_' . $n . '_' . $auser->id . '">' . $options[$outcome->grades[$auser->id]->grade] . '</span>';
                             } else {
                                 $attributes = array();
                                 $attributes['tabindex'] = $tabindex++;
                                 $attributes['id'] = 'outcome_' . $n . '_' . $auser->id;
                                 $outcomes .= ' ' . html_writer::select($options, 'outcome_' . $n . '[' . $auser->id . ']', $outcome->grades[$auser->id]->grade, array(0 => get_string('nooutcome', 'grades')), $attributes);
                             }
                             $outcomes .= '</div>';
                         }
                     }
                     $userlink = '<a href="' . $CFG->wwwroot . '/user/view.php?id=' . $auser->id . '&amp;course=' . $course->id . '">' . fullname($auser, has_capability('moodle/site:viewfullnames', $this->context)) . '</a>';
                     $extradata = array();
                     foreach ($extrafields as $field) {
                         $extradata[] = $auser->{$field};
                     }
                     $row = array_merge(array($picture, $userlink), $extradata, array($grade, $comment, $studentmodified, $teachermodified, $status, $finalgrade));
                     if ($uses_outcomes) {
                         $row[] = $outcomes;
                     }
                     $table->add_data($row, $rowclass);
                 }
                 $currentposition++;
             }
             if ($hassubmission && method_exists($this, 'download_submissions')) {
                 echo html_writer::start_tag('div', array('class' => 'mod-assignment-download-link'));
                 echo html_writer::link(new moodle_url('/mod/assignment/submissions.php', array('id' => $this->cm->id, 'download' => 'zip')), get_string('downloadall', 'assignment'));
                 echo html_writer::end_tag('div');
             }
             $table->print_html();
             /// Print the whole table
         } else {
             if ($filter == self::FILTER_SUBMITTED) {
                 echo html_writer::tag('div', get_string('nosubmisson', 'assignment'), array('class' => 'nosubmisson'));
             } else {
                 if ($filter == self::FILTER_REQUIRE_GRADING) {
                     echo html_writer::tag('div', get_string('norequiregrading', 'assignment'), array('class' => 'norequiregrading'));
                 }
             }
         }
     }
     /// Print quickgrade form around the table
     if ($quickgrade && $table->started_output && !empty($users)) {
         $mailinfopref = false;
         if (get_user_preferences('assignment_mailinfo', 1)) {
             $mailinfopref = true;
         }
         $emailnotification = html_writer::checkbox('mailinfo', 1, $mailinfopref, get_string('enablenotification', 'assignment'));
         $emailnotification .= $OUTPUT->help_icon('enablenotification', 'assignment');
         echo html_writer::tag('div', $emailnotification, array('class' => 'emailnotification'));
         $savefeedback = html_writer::empty_tag('input', array('type' => 'submit', 'name' => 'fastg', 'value' => get_string('saveallfeedback', 'assignment')));
         echo html_writer::tag('div', $savefeedback, array('class' => 'fastgbutton'));
         echo html_writer::end_tag('form');
     } else {
         if ($quickgrade) {
             echo html_writer::end_tag('form');
         }
     }
     echo '</div>';
     /// End of fast grading form
     /// Mini form for setting user preference
     $formaction = new moodle_url('/mod/assignment/submissions.php', array('id' => $this->cm->id));
     $mform = new MoodleQuickForm('optionspref', 'post', $formaction, '', array('class' => 'optionspref'));
     $mform->addElement('hidden', 'updatepref');
     $mform->setDefault('updatepref', 1);
     $mform->addElement('header', 'qgprefs', get_string('optionalsettings', 'assignment'));
     $mform->addElement('select', 'filter', get_string('show'), $filters);
     $mform->setDefault('filter', $filter);
     $mform->addElement('text', 'perpage', get_string('pagesize', 'assignment'), array('size' => 1));
     $mform->setDefault('perpage', $perpage);
     if ($this->quickgrade_mode_allowed()) {
         $mform->addElement('checkbox', 'quickgrade', get_string('quickgrade', 'assignment'));
         $mform->setDefault('quickgrade', $quickgrade);
         $mform->addHelpButton('quickgrade', 'quickgrade', 'assignment');
     }
     $mform->addElement('submit', 'savepreferences', get_string('savepreferences'));
     $mform->display();
     echo $OUTPUT->footer();
 }