Many bugfixes accummulated during CVS outage, more to come.
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
reordered according to the line numbers you specified.</p>
|
||||
|
||||
<p>Line numbers do not have to be integers, you can also use numbers with
|
||||
a decimal point if you find that convenient</p>
|
||||
a decimal point if you find that convenient.</p>
|
||||
|
||||
<p>Page breaks are given line numbers as well, to allow you to move them
|
||||
around in the same manner. If you have unticked the "Show page breaks"
|
||||
|
||||
@@ -258,6 +258,7 @@ $string['min'] = 'Min';
|
||||
$string['minutes'] = 'Minutes';
|
||||
$string['missinganswer'] = 'Too few :ANSWER, :Lx, :Rx statements for question line $a. You must define at last 2 possible answers';
|
||||
$string['missingcorrectanswer'] = 'Correct answer must be specified';
|
||||
$string['missingformula'] = 'Missing formula';
|
||||
$string['missingitemtypename'] = 'Missing name';
|
||||
$string['missingname'] = 'Missing question name';
|
||||
$string['missingquestion'] = 'Missing question label after line $a';
|
||||
|
||||
+11
-20
@@ -819,7 +819,7 @@ function question_extract_responses($questions, $formdata, $defaultevent=QUESTIO
|
||||
*
|
||||
* TODO: Make sure this is not quiz-specific
|
||||
*
|
||||
* @return boolean Indicates success/failure
|
||||
* @return boolean Indicates whether the grade has changed
|
||||
* @param object $question A question object
|
||||
* @param object $attempt The attempt, in which the question needs to be regraded.
|
||||
* @param object $cmoptions
|
||||
@@ -843,19 +843,15 @@ function regrade_question_in_attempt($question, $attempt, $cmoptions, $verbose=f
|
||||
$replaystate = clone($state);
|
||||
$replaystate->last_graded = $state;
|
||||
|
||||
$changed = 0;
|
||||
$changed = false;
|
||||
for($j = 1; $j < count($states); $j++) {
|
||||
restore_question_state($question, $states[$j]);
|
||||
$action = new stdClass;
|
||||
$action->responses = $states[$j]->responses;
|
||||
$action->timestamp = $states[$j]->timestamp;
|
||||
|
||||
// Close the last state of a finished attempt
|
||||
if (((count($states) - 1) === $j) && ($attempt->timefinish > 0)) {
|
||||
$action->event = QUESTION_EVENTCLOSE;
|
||||
|
||||
// Change event to submit so that it will be reprocessed
|
||||
} else if (QUESTION_EVENTCLOSE == $states[$j]->event
|
||||
if (QUESTION_EVENTCLOSE == $states[$j]->event
|
||||
or QUESTION_EVENTGRADE == $states[$j]->event
|
||||
or QUESTION_EVENTCLOSEANDGRADE == $states[$j]->event) {
|
||||
$action->event = QUESTION_EVENTSUBMIT;
|
||||
@@ -872,28 +868,23 @@ function regrade_question_in_attempt($question, $attempt, $cmoptions, $verbose=f
|
||||
|
||||
// We need rounding here because grades in the DB get truncated
|
||||
// e.g. 0.33333 != 0.3333333, but we want them to be equal here
|
||||
if (round((float)$replaystate->grade, 5) != round((float)$states[$j]->grade, 5)) {
|
||||
$changed++;
|
||||
if ((round((float)$replaystate->raw_grade, 5) != round((float)$states[$j]->raw_grade, 5))
|
||||
or (round((float)$replaystate->penalty, 5) != round((float)$states[$j]->penalty, 5))
|
||||
or (round((float)$replaystate->grade, 5) != round((float)$states[$j]->grade, 5))) {
|
||||
$changed = true;
|
||||
}
|
||||
|
||||
$replaystate->id = $states[$j]->id;
|
||||
$replaystate->update = true; // This will ensure that the existing database entry is updated rather than a new one created
|
||||
save_question_session($question, $replaystate);
|
||||
}
|
||||
if ($verbose) {
|
||||
if ($changed) {
|
||||
link_to_popup_window ('/question/reviewquestion.php?attempt='.$attempt->id.'&question='.$question->id,
|
||||
'reviewquestion', ' #'.$attempt->id, 450, 550, get_string('reviewresponse', 'quiz'));
|
||||
update_record('quiz_attempts', $attempt);
|
||||
} else {
|
||||
echo ' #'.$attempt->id;
|
||||
}
|
||||
echo "\n"; @flush(); @ob_flush();
|
||||
if ($changed) {
|
||||
update_record('quiz_attempts', $attempt);
|
||||
}
|
||||
|
||||
return true;
|
||||
return $changed;
|
||||
}
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -87,7 +87,7 @@ function get_last_soap_messages($connection) {
|
||||
return array('request'=>$connection->__getLastRequest(), 'response'=>$connection->__getLastResponse());
|
||||
}
|
||||
|
||||
// Fix simple type encoding - work around a bug in PHP
|
||||
// Fix simple type encoding - work around a bug in early versions of PHP5 < 5.0.3, see http://bugs.php.net/bug.php?id=31832
|
||||
function soap_encode($value, $name, $type, $namespace, $encode=XSD_STRING) {
|
||||
$value = new SoapVar($value, $encode, $type, $namespace);
|
||||
if ('' === $name)
|
||||
@@ -95,7 +95,7 @@ function soap_encode($value, $name, $type, $namespace, $encode=XSD_STRING) {
|
||||
return new SoapParam($value, $name);
|
||||
}
|
||||
|
||||
// Fix complex type encoding - work around a bug in PHP
|
||||
// Fix complex type encoding - work around a bug in early versions of PHP5 < 5.0.3, see http://bugs.php.net/bug.php?id=31832
|
||||
function soap_encode_object($value, $name, $type, $namespace) {
|
||||
if (!is_object($value))
|
||||
return $value;
|
||||
@@ -105,7 +105,7 @@ function soap_encode_object($value, $name, $type, $namespace) {
|
||||
return new SoapParam($value, $name);
|
||||
}
|
||||
|
||||
// Fix array encoding - work around a bug in PHP
|
||||
// Fix array encoding - work around a bug in early versions of PHP5 < 5.0.3, see http://bugs.php.net/bug.php?id=31832
|
||||
function soap_encode_array($value, $name, $type, $namespace) {
|
||||
if (!is_array($value))
|
||||
return $value;
|
||||
@@ -115,4 +115,4 @@ function soap_encode_array($value, $name, $type, $namespace) {
|
||||
return new SoapParam($value, $name);
|
||||
}
|
||||
|
||||
?>
|
||||
?>
|
||||
@@ -46,6 +46,8 @@ function quiz_delete_quiz_question($id, &$modform) {
|
||||
if (!set_field('quiz', 'questions', $modform->questions, 'id', $modform->instance)) {
|
||||
error('Could not save question list');
|
||||
}
|
||||
delete_records('quiz_question_instances', 'quiz', $modform->instance, 'question', $question);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ class quiz_default_report {
|
||||
return true;
|
||||
}
|
||||
|
||||
function print_header_and_tabs($cm, $course, $quiz, $reportmode="overview"){
|
||||
function print_header_and_tabs($cm, $course, $quiz, $reportmode="overview", $meta=""){
|
||||
global $CFG;
|
||||
/// Define some strings
|
||||
$strquizzes = get_string("modulenameplural", "quiz");
|
||||
@@ -30,7 +30,7 @@ class quiz_default_report {
|
||||
print_header_simple(format_string($quiz->name), "",
|
||||
"<a href=\"index.php?id=$course->id\">$strquizzes</a>
|
||||
-> ".format_string($quiz->name),
|
||||
"", "", true, update_module_button($cm->id, $course->id, $strquiz), navmenu($course, $cm));
|
||||
'', $meta, true, update_module_button($cm->id, $course->id, $strquiz), navmenu($course, $cm));
|
||||
/// Print the tabs
|
||||
$currenttab = 'reports';
|
||||
$mode = $reportmode;
|
||||
|
||||
@@ -184,7 +184,7 @@ class quiz_report extends quiz_default_report {
|
||||
restore_question_state($question, $state);
|
||||
$state->last_graded = $state;
|
||||
|
||||
$options = quiz_get_reviewoptions($quiz, $attempt, isteacher());
|
||||
$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
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ class quiz_report extends quiz_default_report {
|
||||
get_question_options($questions);
|
||||
|
||||
/// Print heading
|
||||
print_heading(get_string('regradingquiz', 'quiz', $quiz->name));
|
||||
print_heading(get_string('regradingquiz', 'quiz', format_string($quiz->name)));
|
||||
echo '<center>';
|
||||
print_string('regradedisplayexplanation', 'quiz');
|
||||
echo '<center>';
|
||||
@@ -40,7 +40,13 @@ class quiz_report extends quiz_default_report {
|
||||
echo '<b>'.get_string('regradingquestion', 'quiz', $question->name).'</b> '.get_string('attempts', 'quiz').": \n";
|
||||
foreach ($attempts as $attempt) {
|
||||
set_time_limit(30);
|
||||
regrade_question_in_attempt($question, $attempt, $quiz, true);
|
||||
$changed = regrade_question_in_attempt($question, $attempt, $quiz, true);
|
||||
if ($changed) {
|
||||
link_to_popup_window ('/mod/quiz/reviewquestion.php?attempt='.$attempt->id.'&question='.$question->id,
|
||||
'reviewquestion', ' #'.$attempt->id, 450, 550, get_string('reviewresponse', 'quiz'));
|
||||
} else {
|
||||
echo ' #'.$attempt->id;
|
||||
}
|
||||
}
|
||||
echo '<br/ >';
|
||||
// the following makes sure that the output is sent immediately.
|
||||
|
||||
+6
-1
@@ -101,7 +101,12 @@
|
||||
|
||||
/// Print heading and tabs if this is part of a preview
|
||||
if ($isteacher) {
|
||||
$currenttab = ($attempt->userid == $USER->id) ? 'preview' : '';
|
||||
if ($attempt->userid == $USER->id) { // this is the report on a preview
|
||||
$currenttab = 'preview';
|
||||
} else {
|
||||
$currenttab = 'reports';
|
||||
$mode = '';
|
||||
}
|
||||
include('tabs.php');
|
||||
} else {
|
||||
print_heading(format_string($quiz->name));
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
if (! $state = get_record('question_states', 'id', $stateid)) {
|
||||
error('Invalid state id');
|
||||
}
|
||||
if (! $attempt = get_record('quiz_attempts', 'id', $state->attempt)) {
|
||||
if (! $attempt = get_record('quiz_attempts', 'uniqueid', $state->attempt)) {
|
||||
error('No such attempt ID exists');
|
||||
}
|
||||
} elseif ($attemptid) {
|
||||
|
||||
+3
-3
@@ -30,9 +30,9 @@
|
||||
|
||||
$row[] = new tabobject('info', "$CFG->wwwroot/mod/quiz/view.php?q=$quiz->id", get_string('info', 'quiz'));
|
||||
$row[] = new tabobject('reports', "$CFG->wwwroot/mod/quiz/report.php?q=$quiz->id", get_string('results', 'quiz'));
|
||||
$row[] = new tabobject('preview', "$CFG->wwwroot/mod/quiz/attempt.php?q=$quiz->id", get_string('preview', 'quiz'), get_string('previewquiz', 'quiz', format_string($quiz->name)));
|
||||
$row[] = new tabobject('preview', "$CFG->wwwroot/mod/quiz/attempt.php?q=$quiz->id", get_string('preview', 'quiz'));
|
||||
if (isteacheredit($course->id)) {
|
||||
$row[] = new tabobject('edit', "$CFG->wwwroot/mod/quiz/edit.php?quizid=$quiz->id", get_string('edit'), get_string('editquizquestions', 'quiz'));
|
||||
$row[] = new tabobject('edit', "$CFG->wwwroot/mod/quiz/edit.php?quizid=$quiz->id", get_string('edit'));
|
||||
}
|
||||
|
||||
$tabs[] = $row;
|
||||
@@ -75,7 +75,7 @@
|
||||
$row[] = new tabobject('categories', "$CFG->wwwroot/question/category.php?id=$course->id", get_string('categories', 'quiz'), get_string('editqcats', 'quiz'));
|
||||
$row[] = new tabobject('import', "$CFG->wwwroot/question/import.php?course=$course->id", get_string('import', 'quiz'), get_string('importquestions', 'quiz'));
|
||||
$row[] = new tabobject('export', "$CFG->wwwroot/question/export.php?courseid=$course->id", get_string('export', 'quiz'), get_string('exportquestions', 'quiz'));
|
||||
$row[] = new tabobject('update', "$CFG->wwwroot/course/mod.php?update=$cm->id&sesskey=$USER->sesskey", get_string('settings'), get_string('updatesettings'));
|
||||
$row[] = new tabobject('update', "$CFG->wwwroot/course/mod.php?update=$cm->id&sesskey=$USER->sesskey", get_string('settings'), get_string('updatesettings', 'quiz'));
|
||||
|
||||
$tabs[] = $row;
|
||||
}
|
||||
|
||||
+18
-16
@@ -169,24 +169,26 @@
|
||||
|
||||
/// Now print table with existing attempts
|
||||
|
||||
if ($numattempts) {
|
||||
if ($attempts) {
|
||||
|
||||
/// prepare table header
|
||||
$table->head = array($strattempt, $strtimecompleted);
|
||||
$table->align = array("center", "left");
|
||||
$table->size = array("", "");
|
||||
if ($quiz->grade and $quiz->sumgrades) { // Grades used so have more columns in table
|
||||
if ($quiz->grade <> $quiz->sumgrades) {
|
||||
$table->head = array($strattempt, $strtimetaken, $strtimecompleted, "$strmarks / $quiz->sumgrades", "$strgrade / $quiz->grade");
|
||||
$table->align = array("center", "center", "left", "right", "right");
|
||||
$table->size = array("", "", "", "", "");
|
||||
} else {
|
||||
$table->head = array($strattempt, $strtimetaken, $strtimecompleted, "$strgrade / $quiz->grade");
|
||||
$table->align = array("center", "center", "left", "right");
|
||||
$table->size = array("", "", "", "");
|
||||
$table->head[] = "$strmarks / $quiz->sumgrades";
|
||||
$table->align[] = 'right';
|
||||
$table->size[] = '';
|
||||
}
|
||||
|
||||
} else { // No grades are being used
|
||||
$table->head = array($strattempt, $strtimetaken, $strtimecompleted);
|
||||
$table->align = array("center", "center", "left");
|
||||
$table->size = array("", "", "");
|
||||
$table->head[] = "$strgrade / $quiz->grade";
|
||||
$table->align[] = 'right';
|
||||
$table->size[] = '';
|
||||
}
|
||||
if (isset($quiz->showtimetaken)) {
|
||||
$table->head[] = $strtimetaken;
|
||||
$table->align[] = 'center';
|
||||
$table->size[] = '';
|
||||
}
|
||||
|
||||
/// One row for each attempt
|
||||
@@ -266,12 +268,10 @@
|
||||
|
||||
if ($quiz->grade <> $quiz->sumgrades) {
|
||||
$table->data[] = array( $attempt->attempt,
|
||||
$timetaken,
|
||||
$datecompleted,
|
||||
$attemptmark, $attemptgrade);
|
||||
} else {
|
||||
$table->data[] = array( $attempt->attempt,
|
||||
$timetaken,
|
||||
$datecompleted,
|
||||
$attemptgrade);
|
||||
}
|
||||
@@ -284,9 +284,11 @@
|
||||
}
|
||||
}
|
||||
$table->data[] = array( $attempt->attempt,
|
||||
$timetaken,
|
||||
$datecompleted);
|
||||
}
|
||||
if (isset($quiz->showtimetaken)) {
|
||||
$table->data[] = $timetaken;
|
||||
}
|
||||
}
|
||||
print_table($table);
|
||||
}
|
||||
|
||||
@@ -260,7 +260,7 @@ class question_calculated_qtype extends question_dataset_dependent_questiontype
|
||||
return parent::grade_responses($numericalquestion, $state, $cmoptions);
|
||||
}
|
||||
|
||||
function response_summary($state, $length=80) {
|
||||
function response_summary($question, $state, $length=80) {
|
||||
// The actual response is the bit after the hyphen
|
||||
return substr($state->answer, strpos($state->answer, '-')+1, $length);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
</div>
|
||||
|
||||
<?php if ($image) { ?>
|
||||
<img class="qimage" src="<?php echo $q->imageurl; ?>" alt="" />
|
||||
<img class="qimage" src="<?php echo $image; ?>" alt="" />
|
||||
<?php } ?>
|
||||
</div>
|
||||
</td></tr></table>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
</div>
|
||||
|
||||
<?php if ($image) { ?>
|
||||
<img class="qimage" src="<?php echo $q->imageurl; ?>" alt="" />
|
||||
<img class="qimage" src="<?php echo $image; ?>" alt="" />
|
||||
<?php } ?>
|
||||
|
||||
<div class="ablock clearfix">
|
||||
|
||||
@@ -252,7 +252,7 @@ class question_match_qtype extends default_questiontype {
|
||||
and $options->correct_responses
|
||||
and isset($correctanswers[$subquestion->id])
|
||||
and ($correctanswers[$subquestion->id] == $response)) {
|
||||
$a->class = ' class="highlight" ';
|
||||
$a->class = ' highlight ';
|
||||
} else {
|
||||
$a->class = '';
|
||||
}
|
||||
@@ -334,6 +334,11 @@ class question_match_qtype extends default_questiontype {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function response_summary($question, $state, $length=80) {
|
||||
// This should almost certainly be overridden
|
||||
return substr(implode(',', $this->get_actual_response($question, $state)), 0, $length);
|
||||
}
|
||||
|
||||
/// BACKUP FUNCTIONS ////////////////////////////
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
</div>
|
||||
|
||||
<?php if ($image) { ?>
|
||||
<img class="qimage" src="<?php echo $q->imageurl; ?>" alt="" />
|
||||
<img class="qimage" src="<?php echo $image; ?>" alt="" />
|
||||
<?php } ?>
|
||||
|
||||
<div class="ablock clearfix">
|
||||
@@ -21,4 +21,4 @@
|
||||
</tr>
|
||||
<?php } ?>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -59,12 +59,11 @@ class embedded_cloze_qtype extends default_questiontype {
|
||||
// will also create difficulties if questiontype specific tables reference the id.
|
||||
|
||||
// First we get all the existing wrapped questions
|
||||
if (!$oldwrappedids = get_records('question', 'parent', $question->id, '', 'id, id')) {
|
||||
// We need to select 'id, id' because the first one is consumed by
|
||||
// get_records.
|
||||
if (!$oldwrappedids = get_field('question_multianswers', 'sequence', 'question', $question->id)) {
|
||||
$oldwrappedids = array();
|
||||
} else {
|
||||
$oldwrappedids = explode(',', $oldwrappedids);
|
||||
}
|
||||
$oldwrappedids = array_keys($oldwrappedids);
|
||||
$sequence = array();
|
||||
foreach($question->options->questions as $wrapped) {
|
||||
// if we still have some old wrapped question ids, reuse the next of them
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
</div>
|
||||
|
||||
<?php if ($image) { ?>
|
||||
<img class="qimage" src="<?php echo $q->imageurl; ?>" alt="" />
|
||||
<img class="qimage" src="<?php echo $image; ?>" alt="" />
|
||||
<?php } ?>
|
||||
|
||||
<div class="ablock clearfix">
|
||||
|
||||
@@ -510,6 +510,8 @@ class default_questiontype {
|
||||
$table->size = array ('', '', '', '', '', '', '');
|
||||
$table->width = '100%';
|
||||
foreach ($states as $st) {
|
||||
$st->responses[''] = $st->answer;
|
||||
$this->restore_session_and_responses($question, $st);
|
||||
$b = ($state->id == $st->id) ? '<b>' : '';
|
||||
$be = ($state->id == $st->id) ? '</b>' : '';
|
||||
if ($state->id == $st->id) {
|
||||
@@ -525,7 +527,7 @@ class default_questiontype {
|
||||
$table->data[] = array (
|
||||
$link,
|
||||
$b.get_string('event'.$st->event, 'quiz').$be,
|
||||
$b.$this->response_summary($st).$be,
|
||||
$b.$this->response_summary($question, $st).$be,
|
||||
$b.userdate($st->timestamp, get_string('timestr', 'quiz')).$be,
|
||||
$b.round($st->raw_grade, $cmoptions->decimalpoints).$be,
|
||||
$b.round($st->penalty, $cmoptions->decimalpoints).$be,
|
||||
@@ -694,10 +696,11 @@ class default_questiontype {
|
||||
* summarizes the student's response in the given $state. This is used for
|
||||
* example in the response history table
|
||||
* @return string The summary of the student response
|
||||
* @param object $question
|
||||
* @param object $state The state whose responses are to be summarized
|
||||
* @param int $length The maximum length of the returned string
|
||||
*/
|
||||
function response_summary($state, $length=80) {
|
||||
function response_summary($question, $state, $length=80) {
|
||||
// This should almost certainly be overridden
|
||||
return substr($state->answer, 0, $length);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
/// QUESTION TYPE CLASS //////////////////
|
||||
class random_qtype extends default_questiontype {
|
||||
|
||||
var $excludedtypes = array('random', 'randomsamatch', 'essay', 'description');
|
||||
var $excludedtypes = array("'random'", "'randomsamatch'", "'essay'", "'description'");
|
||||
|
||||
// Carries questions available as randoms sorted by category
|
||||
// This array is used when needed only
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
</div>
|
||||
|
||||
<?php if ($image) { ?>
|
||||
<img class="qimage" src="<?php echo $q->imageurl; ?>" alt="" />
|
||||
<img class="qimage" src="<?php echo $imagel; ?>" alt="" />
|
||||
<?php } ?>
|
||||
|
||||
<div class="ablock clearfix">
|
||||
|
||||
@@ -15,11 +15,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
$emptyanswer->answer = '';
|
||||
$i = count($answers);
|
||||
$limit = QUESTION_NUMANS;
|
||||
$limit = $limit <= $i ? $i+1 : $limit;
|
||||
for (; $i < $limit; $i++) {
|
||||
$answers[] = ""; // Make answer slots, default as blank
|
||||
$answers[] = $emptyanswer; // Make answer slots, default as blank
|
||||
}
|
||||
|
||||
print_heading_with_help(get_string("editingshortanswer", "quiz"), "shortanswer", "quiz");
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
</div>
|
||||
|
||||
<?php if ($image) { ?>
|
||||
<img class="qimage" src="<?php echo $q->imageurl; ?>" alt="" />
|
||||
<img class="qimage" src="<?php echo $image; ?>" alt="" />
|
||||
<?php } ?>
|
||||
|
||||
<div class="ablock clearfix">
|
||||
|
||||
@@ -202,6 +202,15 @@ class question_truefalse_qtype extends default_questiontype {
|
||||
return true;
|
||||
}
|
||||
|
||||
function response_summary($question, $state, $length=80) {
|
||||
if (isset($question->options->answers[$state->answer])) {
|
||||
$responses = $question->options->answers[$state->answer]->answer;
|
||||
} else {
|
||||
$responses = '';
|
||||
}
|
||||
return $responses;
|
||||
}
|
||||
|
||||
function get_actual_response($question, $state) {
|
||||
if (isset($question->options->answers[$state->responses['']])) {
|
||||
$responses[] = $question->options->answers[$state->responses['']]->answer;
|
||||
|
||||
Reference in New Issue
Block a user