]> git.mjollnir.org Git - moodle.git/commitdiff
Some code cleanup, relying more on the functions from questionlib.php. Not currently...
authorgustav_delius <gustav_delius>
Thu, 6 Apr 2006 16:45:14 +0000 (16:45 +0000)
committergustav_delius <gustav_delius>
Thu, 6 Apr 2006 16:45:14 +0000 (16:45 +0000)
mod/quiz/report/grading/report.php

index fa8750e2c061c61c7daa8125874cc3e2fe893c0e..0042d74fcdc249e3a182f1900ece7a989f0d9f12 100644 (file)
@@ -1,6 +1,6 @@
-<?php  
+<?php
 
-// This file allows a teacher to grade essay questions.  
+// This file allows a teacher to grade essay questions.
 // Could be later expanded to change grades for all question types
 
 # Flow of the file:
@@ -19,7 +19,7 @@ class quiz_report extends quiz_default_report {
 
     function display($quiz, $cm, $course) {     /// This function just displays the report
         global $CFG, $SESSION, $USER, $db, $QTYPES;
-    
+
         $action = optional_param('action', 'viewquestions', PARAM_ALPHA);
         $questionid = optional_param('questionid', 0, PARAM_INT);
         $attemptid = optional_param('attemptid', 0, PARAM_INT);
@@ -27,16 +27,32 @@ class quiz_report extends quiz_default_report {
         $userid = optional_param('userid', 0, PARAM_INT);
 
         $this->print_header_and_tabs($cm, $course, $quiz, $reportmode="grading");
+        
+        notice('The manual grading is temporarily disabled during development work', $CFG->wwwroot.'/mod/quiz/report.php?q='.$quiz->id);
 
         if (!empty($questionid)) {
             if (! $question = get_record('question', 'id', $questionid)) {
                 error("Question with id $questionid not found");
             }
-            ///$number = optional_param('number', 0, PARAM_INT);
+            $question->maxgrade = get_field('quiz_question_instances', 'grade', 'quiz', $quiz->id, 'question', $question->id);
+
+            // Some of the questions code is optimised to work with several questions
+            // at once so it wants the question to be in an array. The array key
+            // must be the question id.
+            $key = $question->id;
+            $questions[$key] = &$question;
+
+            // We need to add additional questiontype specific information to
+            // the question objects.
+            if (!get_question_options($questions)) {
+                error("Unable to load questiontype specific question information");
+            }
+            // This will have extended the question object so that it now holds
+            // all the information about the questions that may be needed later.
         }
-    
+
         add_to_log($course->id, "quiz", "manualgrading", "report.php?mode=grading&amp;q=$quiz->id", "$quiz->id", "$cm->id");
-    
+
     /// GROUP CODE FROM ATTEMPTS.PHP no sure how to use just yet... need to update later perhaps
     /// Check to see if groups are being used in this quiz
         # if ($groupmode = groupmode($course, $cm)) {   // Groups are being used
@@ -44,7 +60,7 @@ class quiz_report extends quiz_default_report {
         # } else {
         #     $currentgroup = false;
         # }
-    
+
     /// Get all students
         # if ($currentgroup) {
         #     $users = get_group_students($currentgroup);
@@ -52,23 +68,20 @@ class quiz_report extends quiz_default_report {
         # else {
             $users = get_course_students($course->id);
         # }
-    
+
         if(empty($users)) {
             print_heading(get_string("noattempts", "quiz"));
             return true;
         } else {
             // for sql queries
-            $userids = implode(', ', array_keys($users)); 
+            $userids = implode(', ', array_keys($users));
         }
-    
+
         echo '<div id="overDiv" style="position:absolute; visibility:hidden; z-index:1000;"></div>'; // for overlib
-    
+
         if ($data = data_submitted()) {  // post data submitted, process it
             confirm_sesskey();
-    
-            $question->maxgrade = get_field('quiz_question_instances', 'grade', 'quiz', $quiz->id, 'question', $question->id);
-            $QTYPES[$question->qtype]->get_question_options($question);
-    
+
             // first, process all the data to extract the teacher's new responses for the question(s)
             foreach ($data as $key => $response) {
                 $keyparts = explode('_', $key); // valid keys are in this format: attemptid_stateid_fieldname
@@ -77,7 +90,7 @@ class quiz_report extends quiz_default_report {
                     $attemptid = $keyparts[0];
                     $stateid = $keyparts[1];
                     $fieldname = $keyparts[2];
-                    
+
                     $responses[$attemptid.'_'.$stateid][$fieldname] = $response;
                 }
             }
@@ -88,63 +101,48 @@ class quiz_report extends quiz_default_report {
                 $ids = explode('_', $ids);
                 $attemptid = $ids[0];
                 $stateid = $ids[1];
-                
+
                 // get our attempt
                 if (! $attempt = get_record('quiz_attempts', 'id', $attemptid)) {
                     error('No such attempt ID exists');
-                }            
-    
-                // get the state
-                $statefields = 'n.questionid as question, s.*, n.sumpenalty';
-                $sql = "SELECT $statefields".
-                   "  FROM {$CFG->prefix}question_states s,".
-                   "       {$CFG->prefix}question_sessions n".
-                   " WHERE s.id = n.newest".
-                   "   AND n.attemptid = '$attempt->uniqueid'".
-                   "   AND n.questionid = $question->id";
-                $state = get_record_sql($sql);
-    
-                // restore the state of the question
-                restore_question_state($question, $state);
-    
+                }
+
+                // Load the state for this attempt (The questions array was created earlier)
+                $states = get_question_states($questions, $quiz, $attempt);
+                // The $states array is indexed by question id but because we are dealing
+                // with only one question there is only one entry in this array
+                $state = &$states[$question->id];
+
                 // this is the new response from the teacher
                 $state->responses = $response;
-                
-                // grade the question with the new state made by the teacher
-                $QTYPES[$question->qtype]->grade_responses($question, $state, $quiz);
-    
-                // finalize the grade
-                $state->last_graded->grade = 0; // we dont want the next function to care about the last grade
-                question_apply_penalty_and_timelimit($question, $state, $attempt, $quiz);
-    
-                // want to update session.  Also set changed to 1 to trick save_question_session to save our session
-                $state->update = 1;
+
+                // Process the teacher responses
+                $QTYPES[$question->qtype]->process_teacher_responses($question, $state, $quiz);
+
+                // We need to indicate that the state has changed in order for it to be saved
                 $state->changed = 1;
+                // We want to update existing state (rather than creating new one) if it
+                // was itself created by a manual grading event
+                $state->update = ($state->event == QUESTION_EVENTMANUALGRADE) ? 1 : 0;
+                // Go ahead and save
                 save_question_session($question, $state);
-                
-                // method for changing sumgrades from report type regrade.  Thanks!
-                $sumgrades = 0;
-                $questionids = explode(',', quiz_questions_in_quiz($attempt->layout));
-                foreach($questionids as $questionid) {
-                    $lastgradedid = get_field('question_sessions', 'newgraded', 'attemptid', $attempt->uniqueid, 'questionid', $questionid);
-                    $sumgrades += get_field('question_states', 'grade', 'id', $lastgradedid);
-                }            
-    
+
                 if ($attempt->sumgrades != $sumgrades) {
                     set_field('quiz_attempts', 'sumgrades', $sumgrades, 'id', $attempt->id);
                 }
-    
+
                 // update user's grade
                 quiz_save_best_grade($quiz, $attempt->userid);
             }
             notify(get_string('changessaved', 'quiz'));
+
         } else if ( ( !empty($attemptid) or !empty($gradeall) or !empty($userid)) and !empty($questionid) ) {  // need attemptid and questionid or gradeall and a questionid
             // this sql joins the attempts table and the user table
-            $select = 'SELECT '.$db->Concat('u.id', '\'#\'', $db->IfNull('qa.attempt', '0')).' AS userattemptid, 
-                        qa.id AS attemptid, qa.uniqueid, qa.attempt, qa.timefinish, qa.preview, 
+            $select = 'SELECT '.$db->Concat('u.id', '\'#\'', $db->IfNull('qa.attempt', '0')).' AS userattemptid,
+                        qa.id AS attemptid, qa.uniqueid, qa.attempt, qa.timefinish, qa.preview,
                         u.id AS userid, u.firstname, u.lastname, u.picture ';
             $from   = 'FROM '.$CFG->prefix.'user u LEFT JOIN '.$CFG->prefix.'quiz_attempts qa ON (u.id = qa.userid AND qa.quiz = '.$quiz->id.') ';
-            
+
             if ($gradeall) { // get all user attempts
                 $where  = 'WHERE u.id IN ('.implode(',', array_keys($users)).') ';
             } else if ($userid) { // get all the attempts for a specific user
@@ -152,70 +150,58 @@ class quiz_report extends quiz_default_report {
             } else { // get a specific attempt
                 $where = 'WHERE qa.id='.$attemptid.' ';
             }
-            
+
             $where .= 'AND '.$db->IfNull('qa.attempt', '0').' != 0 ';
-            $where .= 'AND '.$db->IfNull('qa.timefinish', '0').' != 0 '; 
+            $where .= 'AND '.$db->IfNull('qa.timefinish', '0').' != 0 ';
             $sort = 'ORDER BY u.firstname, u.lastname, qa.attempt ASC';
             $attempts = get_records_sql($select.$from.$where.$sort);
-            
+
             echo '<form method="post" action="report.php">'.
                 '<input type="hidden" name="mode" value="grading">'.
                 '<input type="hidden" name="q" value="'.$quiz->id.'">'.
                 '<input type="hidden" name="sesskey" value="'.$USER->sesskey.'">'.
                 '<input type="hidden" name="action" value="viewquestion">'.
-                '<input type="hidden" name="questionid" value="'.$questionid.'">';        
-            
+                '<input type="hidden" name="questionid" value="'.$questionid.'">';
+
             foreach ($attempts as $attempt) {
-                // retrieve the state
-                if (!$neweststate = get_record('question_sessions', 'attemptid', $attempt->uniqueid, 'questionid', $questionid)) {
-                    error("Can not find newest states for attempt $attempt->uniqueid for question $questionid");
-                }
-                if (! $state = get_record('question_states', 'id', $neweststate->newest)) {
-                    error('Invalid state id');
-                }
-    
-                // get everything ready for the question to be printed
-                $instance = get_record('quiz_question_instances', 'quiz', $quiz->id, 'question', $question->id);
-                $question->instance = $instance->id;
-                $question->maxgrade = $instance->grade;
-                $question->name_prefix = $attempt->attemptid.'_'.$state->id.'_';
-                $QTYPES[$question->qtype]->get_question_options($question);
-    
-                restore_question_state($question, $state);
-                $state->last_graded = $state;
-    
+
+                // Load the state for this attempt (The questions array was created earlier)
+                $states = get_question_states($questions, $quiz, $attempt);
+                // The $states array is indexed by question id but because we are dealing
+                // with only one question there is only one entry in this array
+                $state = &$states[$question->id];
+
                 $options = quiz_get_reviewoptions($quiz, $attempt, true);
-                $options->validation = ($state->event == QUESTION_EVENTVALIDATE);  // not sure what this is
                 //$options->history = 'all';  // had this on, but seemed confusing for this
-                
-                // IF this code is expanded to manually regrade any question type, then 
-                //   readonly would be set to 0 and the essay question would have to be
-                //   updated.  Also, regrade would most likly be tossed.
+
                 $options->readonly = 1;
                 $options->regrade = 1;
-    
+
                 // print the user name, attempt count, the question, and some more hidden fields
                 echo '<div align="center" width="80%" style="padding:15px;">'.
                     '<p>'."$attempt->firstname $attempt->lastname: ".
                     get_string('attempt', 'quiz')." $attempt->attempt".
                     '</p>';
-                
+
                 print_question($question, $state, '', $quiz, $options);
                 echo '<input type="hidden" name="attemptids[]" value="'.$attempt->attemptid.'">'.
                     '<input type="hidden" name="stateids[]" value="'.$state->id.'">';
                 echo '</div>';
+                
+                // TODO: This is where the code for printing the comment box and grade selector
+                // should go.
             }
             echo '<div align="center"><input type="submit" value="'.get_string('savechanges').'"></div>'.
                 '</form>';
             print_footer($course);
             exit();
         }
-        
+
         // our 2 different views
-        // the first one displays all of the essay questions in the quiz 
+        // the first one displays all of the essay questions in the quiz
         // with the number of ungraded attempts for each essay question
-        
-        // the second view displays the users who have answered the essay question 
+
+        // the second view displays the users who have answered the essay question
         // and all of their attempts at answering the question
         switch($action) {
             case 'viewquestions':
@@ -226,9 +212,9 @@ class quiz_report extends quiz_default_report {
                 $table->align = array("left", "left");
                 $table->wrap = array("wrap", "wrap");
                 $table->width = "20%";
-                $table->size = array("*", "*");  
+                $table->size = array("*", "*");
                 $table->data = array();
-                
+
                 // get the essay questions
                 $questionlist = quiz_questions_in_quiz($quiz->questions);
                 $sql = "SELECT q.*, i.grade AS maxgrade, i.id AS instance".
@@ -246,10 +232,12 @@ class quiz_report extends quiz_default_report {
                 // get all the finished attempts by the users
                 if ($attempts = get_records_select('quiz_attempts', "quiz = $quiz->id and timefinish > 0 and userid IN ($userids)", 'userid, attempt')) {
                     foreach($questions as $question) {
-                        
+
                         $link = "<a href=\"report.php?mode=grading&amp;q=$quiz->id&amp;action=viewquestion&amp;questionid=$question->id\">".
                                 $question->name."</a>";
                         // determine the number of ungraded attempts (essay question thing only)
+                        // TODO: This should be done with more efficient SQL
+                        // It should use the event field of the newest graded state
                         $ungraded = 0;
                         foreach ($attempts as $attempt) {
                             // grab the state then check if it is graded
@@ -263,7 +251,7 @@ class quiz_report extends quiz_default_report {
                                 $ungraded++;
                             }
                         }
-    
+
                         $table->data[] = array($link, $ungraded);
                     }
                     print_table($table);
@@ -275,43 +263,43 @@ class quiz_report extends quiz_default_report {
                 // gonna use flexible_table (first time!)
                 $tablecolumns = array('picture', 'fullname', 'attempt');
                 $tableheaders = array('', get_string('fullname'), get_string("attempts", "quiz"));
-    
+
                 $table = new flexible_table('mod-quiz-report-grading');
-    
+
                 $table->define_columns($tablecolumns);
                 $table->define_headers($tableheaders);
                 $table->define_baseurl($CFG->wwwroot.'/mod/quiz/report.php?mode=grading&amp;q='.$quiz->id.'&amp;action=viewquestion&amp;questionid='.$question->id);
-    
+
                 $table->sortable(true);
                 $table->initialbars(count($users)>20);  // will show initialbars if there are more than 20 users
                 $table->pageable(true);
-    
+
                 $table->column_suppress('fullname');
                 $table->column_suppress('picture');
-    
+
                 $table->column_class('picture', 'picture');
-                
+
                 // attributes in the table tag
                 $table->set_attribute('cellspacing', '0');
                 $table->set_attribute('id', 'grading');
                 $table->set_attribute('class', 'generaltable generalbox');
                 $table->set_attribute('align', 'center');
                 $table->set_attribute('width', '50%');
-        
+
                 // get it ready!
-                $table->setup();                    
-                
+                $table->setup();
+
                 // this sql is a join of the attempts table and the user table.  I do this so I can sort by user name and attempt number (not id)
                 $select = 'SELECT '.$db->Concat('u.id', '\'#\'', $db->IfNull('qa.attempt', '0')).' AS userattemptid, qa.id AS attemptid, qa.uniqueid, qa.attempt, u.id AS userid, u.firstname, u.lastname, u.picture ';
                 $from   = 'FROM '.$CFG->prefix.'user u LEFT JOIN '.$CFG->prefix.'quiz_attempts qa ON (u.id = qa.userid AND qa.quiz = '.$quiz->id.') ';
                 $where  = 'WHERE u.id IN ('.implode(',', array_keys($users)).') ';
                 $where .= 'AND '.$db->IfNull('qa.attempt', '0').' != 0 ';
-                $where .= 'AND '.$db->IfNull('qa.timefinish', '0').' != 0 '; 
-         
+                $where .= 'AND '.$db->IfNull('qa.timefinish', '0').' != 0 ';
+
                 if($table->get_sql_where()) { // forgot what this does
                     $where .= 'AND '.$table->get_sql_where();
                 }
-                
+
                 // sorting of the table
                 if($sort = $table->get_sql_sort()) {
                     $sort = 'ORDER BY '.$sort;  // seems like I would need to have u. or qa. infront of the ORDER BY attribues... but seems to work..
@@ -319,11 +307,11 @@ class quiz_report extends quiz_default_report {
                     // my default sort rule
                     $sort = 'ORDER BY u.firstname, u.lastname, qa.attempt ASC';
                 }
-                
+
                 // set up the pagesize
                 $total  = count_records_sql('SELECT COUNT(DISTINCT('.$db->Concat('u.id', '\'#\'', $db->IfNull('qa.attempt', '0')).')) '.$from.$where);
                 $table->pagesize(10, $total);
-    
+
                 // this is for getting the correct records for a given page
                 if($table->get_page_start() !== '' && $table->get_page_size() !== '') {
                     $limit = ' '.sql_paging_limit($table->get_page_start(), $table->get_page_size());
@@ -334,18 +322,19 @@ class quiz_report extends quiz_default_report {
                 // get the attempts and process them
                 if ($attempts = get_records_sql($select.$from.$where.$sort.$limit)) {
                     foreach($attempts as $attempt) {
-    
+
                         $picture = print_user_picture($attempt->userid, $course->id, $attempt->picture, false, true);
-    
-                        // link here... grades all for this student                        
+
+                        // link here... grades all for this student
                         $userlink = "<a href=\"report.php?mode=grading&amp;q=$quiz->id&amp;questionid=$question->id&amp;userid=$attempt->userid\">".
                                     $attempt->firstname.' '.$attempt->lastname.'</a>';
-                        
+
                         // nab the state of the attempt to see if it is graded or not
+                        // TODO: should be changed to use the event field
                         if (!$neweststate = get_record('question_sessions', 'attemptid', $attempt->uniqueid, 'questionid', $question->id)) {
                             error("Can not find newest states for attempt $attempt->uniqueid for question $questionid");
                         }
-    
+
                         if (!$questionstate = get_record('question_essay_states', 'stateid', $neweststate->newest)) {
                             error('Could not find question state');
                         }
@@ -355,27 +344,27 @@ class quiz_report extends quiz_default_report {
                         } else {
                             $style = 'style="color:#008000"';  // green
                         }
-                        
+
                         // link for the attempt
                         $attemptlink = "<a $style href=\"report.php?mode=grading&amp;q=$quiz->id&amp;questionid=$question->id&amp;attemptid=$attempt->attemptid\">".  // &amp;number=$number
                                 $question->name." attempt $attempt->attempt</a>";
-                        
+
                         $table->add_data( array($picture, $userlink, $attemptlink) );
                     }
                     //$number += $question->length;
                 }
-                
+
                 // grade all and "back" links
                 $links = "<center><a href=\"report.php?mode=grading&amp;q=$quiz->id&amp;questionid=$questionid&amp;gradeall=1\">".get_string('gradeall', 'quiz').'</a> | '.
                         "<a href=\"report.php?mode=grading&amp;q=$quiz->id&amp;action=viewquestions\">".get_string('backtoquestionlist', 'quiz').'</a></center>'.
-            
+
                 // print everything here
                 print_heading($question->name);
                 echo $links;
                 echo '<div id="tablecontainer">';
                 $table->print_html();
                 echo '</div>';
-                echo $links;            
+                echo $links;
                 break;
             default:
                 error("Invalid Action");